Blender V2.61 - r43446

SCA_PropertyActuator.cpp

Go to the documentation of this file.
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 */