Blender  V2.59
SCA_PropertyActuator.cpp
Go to the documentation of this file.
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 */