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