|
Blender
V2.59
|
00001 /* 00002 * Assign, change, copy properties 00003 * 00004 * $Id: SCA_PropertyActuator.cpp 36523 2011-05-06 20:18:42Z blendix $ 00005 * 00006 * ***** BEGIN GPL LICENSE BLOCK ***** 00007 * 00008 * This program is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU General Public License 00010 * as published by the Free Software Foundation; either version 2 00011 * of the License, or (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software Foundation, 00020 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00021 * 00022 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00023 * All rights reserved. 00024 * 00025 * The Original Code is: all of this file. 00026 * 00027 * Contributor(s): none yet. 00028 * 00029 * ***** END GPL LICENSE BLOCK ***** 00030 */ 00031 00037 #include <stddef.h> 00038 00039 #include "SCA_PropertyActuator.h" 00040 #include "InputParser.h" 00041 #include "Operator2Expr.h" 00042 #include "ConstExpr.h" 00043 00044 /* ------------------------------------------------------------------------- */ 00045 /* Native functions */ 00046 /* ------------------------------------------------------------------------- */ 00047 00048 SCA_PropertyActuator::SCA_PropertyActuator(SCA_IObject* gameobj,SCA_IObject* sourceObj,const STR_String& propname,const STR_String& expr,int acttype) 00049 : SCA_IActuator(gameobj, KX_ACT_PROPERTY), 00050 m_type(acttype), 00051 m_propname(propname), 00052 m_exprtxt(expr), 00053 m_sourceObj(sourceObj) 00054 { 00055 // protect ourselves against someone else deleting the source object 00056 // don't protect against ourselves: it would create a dead lock 00057 if (m_sourceObj) 00058 m_sourceObj->RegisterActuator(this); 00059 } 00060 00061 SCA_PropertyActuator::~SCA_PropertyActuator() 00062 { 00063 if (m_sourceObj) 00064 m_sourceObj->UnregisterActuator(this); 00065 } 00066 00067 bool SCA_PropertyActuator::Update() 00068 { 00069 bool result = false; 00070 00071 bool bNegativeEvent = IsNegativeEvent(); 00072 RemoveAllEvents(); 00073 00074 00075 if (bNegativeEvent) 00076 return false; // do nothing on negative events 00077 00078 00079 CValue* propowner = GetParent(); 00080 CParser parser; 00081 parser.SetContext( propowner->AddRef()); 00082 00083 CExpression* userexpr= NULL; 00084 00085 if (m_type==KX_ACT_PROP_TOGGLE) 00086 { 00087 /* dont use */ 00088 CValue* newval; 00089 CValue* oldprop = propowner->GetProperty(m_propname); 00090 if (oldprop) 00091 { 00092 newval = new CBoolValue((oldprop->GetNumber()==0.0) ? true:false); 00093 oldprop->SetValue(newval); 00094 } else 00095 { /* as not been assigned, evaluate as false, so assign true */ 00096 newval = new CBoolValue(true); 00097 propowner->SetProperty(m_propname,newval); 00098 } 00099 newval->Release(); 00100 } 00101 else if ((userexpr = parser.ProcessText(m_exprtxt))) { 00102 switch (m_type) 00103 { 00104 00105 case KX_ACT_PROP_ASSIGN: 00106 { 00107 00108 CValue* newval = userexpr->Calculate(); 00109 CValue* oldprop = propowner->GetProperty(m_propname); 00110 if (oldprop) 00111 { 00112 oldprop->SetValue(newval); 00113 } else 00114 { 00115 propowner->SetProperty(m_propname,newval); 00116 } 00117 newval->Release(); 00118 break; 00119 } 00120 case KX_ACT_PROP_ADD: 00121 { 00122 CValue* oldprop = propowner->GetProperty(m_propname); 00123 if (oldprop) 00124 { 00125 // int waarde = (int)oldprop->GetNumber(); /*unused*/ 00126 CExpression* expr = new COperator2Expr(VALUE_ADD_OPERATOR,new CConstExpr(oldprop->AddRef()), 00127 userexpr->AddRef()); 00128 00129 CValue* newprop = expr->Calculate(); 00130 oldprop->SetValue(newprop); 00131 newprop->Release(); 00132 expr->Release(); 00133 00134 } 00135 00136 break; 00137 } 00138 case KX_ACT_PROP_COPY: 00139 { 00140 if (m_sourceObj) 00141 { 00142 CValue* copyprop = m_sourceObj->GetProperty(m_exprtxt); 00143 if (copyprop) 00144 { 00145 CValue *val = copyprop->GetReplica(); 00146 GetParent()->SetProperty( 00147 m_propname, 00148 val); 00149 val->Release(); 00150 00151 } 00152 } 00153 break; 00154 } 00155 /* case KX_ACT_PROP_TOGGLE: */ /* accounted for above, no need for userexpr */ 00156 default: 00157 { 00158 00159 } 00160 } 00161 00162 userexpr->Release(); 00163 } 00164 00165 return result; 00166 } 00167 00168 bool 00169 00170 SCA_PropertyActuator:: 00171 00172 isValid( 00173 00174 SCA_PropertyActuator::KX_ACT_PROP_MODE mode 00175 00176 ){ 00177 bool res = false; 00178 res = ((mode > KX_ACT_PROP_NODEF) && (mode < KX_ACT_PROP_MAX)); 00179 return res; 00180 } 00181 00182 00183 CValue* 00184 00185 SCA_PropertyActuator:: 00186 00187 GetReplica() { 00188 00189 SCA_PropertyActuator* replica = new SCA_PropertyActuator(*this); 00190 00191 replica->ProcessReplica(); 00192 return replica; 00193 00194 }; 00195 00196 void SCA_PropertyActuator::ProcessReplica() 00197 { 00198 // no need to check for self reference like in the constructor: 00199 // the replica will always have a different parent 00200 if (m_sourceObj) 00201 m_sourceObj->RegisterActuator(this); 00202 SCA_IActuator::ProcessReplica(); 00203 } 00204 00205 bool SCA_PropertyActuator::UnlinkObject(SCA_IObject* clientobj) 00206 { 00207 if (clientobj == m_sourceObj) 00208 { 00209 // this object is being deleted, we cannot continue to track it. 00210 m_sourceObj = NULL; 00211 return true; 00212 } 00213 return false; 00214 } 00215 00216 void SCA_PropertyActuator::Relink(CTR_Map<CTR_HashedPtr, void*> *obj_map) 00217 { 00218 void **h_obj = (*obj_map)[m_sourceObj]; 00219 if (h_obj) { 00220 if (m_sourceObj) 00221 m_sourceObj->UnregisterActuator(this); 00222 m_sourceObj = (SCA_IObject*)(*h_obj); 00223 m_sourceObj->RegisterActuator(this); 00224 } 00225 } 00226 00227 #ifdef WITH_PYTHON 00228 00229 /* ------------------------------------------------------------------------- */ 00230 /* Python functions */ 00231 /* ------------------------------------------------------------------------- */ 00232 00233 /* Integration hooks ------------------------------------------------------- */ 00234 PyTypeObject SCA_PropertyActuator::Type = { 00235 PyVarObject_HEAD_INIT(NULL, 0) 00236 "SCA_PropertyActuator", 00237 sizeof(PyObjectPlus_Proxy), 00238 0, 00239 py_base_dealloc, 00240 0, 00241 0, 00242 0, 00243 0, 00244 py_base_repr, 00245 0,0,0,0,0,0,0,0,0, 00246 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, 00247 0,0,0,0,0,0,0, 00248 Methods, 00249 0, 00250 0, 00251 &SCA_IActuator::Type, 00252 0,0,0,0,0,0, 00253 py_base_new 00254 }; 00255 00256 PyMethodDef SCA_PropertyActuator::Methods[] = { 00257 {NULL,NULL} //Sentinel 00258 }; 00259 00260 PyAttributeDef SCA_PropertyActuator::Attributes[] = { 00261 KX_PYATTRIBUTE_STRING_RW_CHECK("propName",0,100,false,SCA_PropertyActuator,m_propname,CheckProperty), 00262 KX_PYATTRIBUTE_STRING_RW("value",0,100,false,SCA_PropertyActuator,m_exprtxt), 00263 KX_PYATTRIBUTE_INT_RW("mode", KX_ACT_PROP_NODEF+1, KX_ACT_PROP_MAX-1, false, SCA_PropertyActuator, m_type), /* ATTR_TODO add constents to game logic dict */ 00264 { NULL } //Sentinel 00265 }; 00266 00267 #endif 00268 00269 /* eof */