optionally use guarded alloc for tiles compositor, also replace allocation functions...
[blender.git] / source / gameengine / GameLogic / SCA_PropertyActuator.cpp
1 /*
2  * Assign, change, copy properties
3  *
4  *
5  * ***** BEGIN GPL LICENSE BLOCK *****
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
22  * All rights reserved.
23  *
24  * The Original Code is: all of this file.
25  *
26  * Contributor(s): none yet.
27  *
28  * ***** END GPL LICENSE BLOCK *****
29  */
30
31 /** \file gameengine/GameLogic/SCA_PropertyActuator.cpp
32  *  \ingroup gamelogic
33  */
34
35
36 #include <stddef.h>
37
38 #include "SCA_PropertyActuator.h"
39 #include "InputParser.h"
40 #include "Operator2Expr.h"
41 #include "ConstExpr.h"
42
43 /* ------------------------------------------------------------------------- */
44 /* Native functions                                                          */
45 /* ------------------------------------------------------------------------- */
46
47 SCA_PropertyActuator::SCA_PropertyActuator(SCA_IObject* gameobj,SCA_IObject* sourceObj,const STR_String& propname,const STR_String& expr,int acttype)
48    :    SCA_IActuator(gameobj, KX_ACT_PROPERTY),
49         m_type(acttype),
50         m_propname(propname),
51         m_exprtxt(expr),
52         m_sourceObj(sourceObj)
53 {
54         // protect ourselves against someone else deleting the source object
55         // don't protect against ourselves: it would create a dead lock
56         if (m_sourceObj)
57                 m_sourceObj->RegisterActuator(this);
58 }
59
60 SCA_PropertyActuator::~SCA_PropertyActuator()
61 {
62         if (m_sourceObj)
63                 m_sourceObj->UnregisterActuator(this);
64 }
65
66 bool SCA_PropertyActuator::Update()
67 {
68         bool result = false;
69
70         bool bNegativeEvent = IsNegativeEvent();
71         RemoveAllEvents();
72
73
74         if (bNegativeEvent)
75                 return false; // do nothing on negative events
76
77
78         CValue* propowner = GetParent();
79         CParser parser;
80         parser.SetContext( propowner->AddRef());
81         
82         CExpression* userexpr= NULL;
83         
84         if (m_type==KX_ACT_PROP_TOGGLE)
85         {
86                 /* don't use */
87                 CValue* newval;
88                 CValue* oldprop = propowner->GetProperty(m_propname);
89                 if (oldprop)
90                 {
91                         newval = new CBoolValue((oldprop->GetNumber()==0.0) ? true:false);
92                         oldprop->SetValue(newval);
93                 } else
94                 {       /* as not been assigned, evaluate as false, so assign true */
95                         newval = new CBoolValue(true);
96                         propowner->SetProperty(m_propname,newval);
97                 }
98                 newval->Release();
99         }
100         else if ((userexpr = parser.ProcessText(m_exprtxt))) {
101                 switch (m_type)
102                 {
103
104                 case KX_ACT_PROP_ASSIGN:
105                         {
106                                 
107                                 CValue* newval = userexpr->Calculate();
108                                 CValue* oldprop = propowner->GetProperty(m_propname);
109                                 if (oldprop)
110                                 {
111                                         oldprop->SetValue(newval);
112                                 } else
113                                 {
114                                         propowner->SetProperty(m_propname,newval);
115                                 }
116                                 newval->Release();
117                                 break;
118                         }
119                 case KX_ACT_PROP_ADD:
120                         {
121                                 CValue* oldprop = propowner->GetProperty(m_propname);
122                                 if (oldprop)
123                                 {
124                                         // int waarde = (int)oldprop->GetNumber();  /*unused*/
125                                         CExpression* expr = new COperator2Expr(VALUE_ADD_OPERATOR,new CConstExpr(oldprop->AddRef()),
126                                                                                                                         userexpr->AddRef());
127
128                                         CValue* newprop = expr->Calculate();
129                                         oldprop->SetValue(newprop);
130                                         newprop->Release();
131                                         expr->Release();
132
133                                 }
134
135                                 break;
136                         }
137                 case KX_ACT_PROP_COPY:
138                         {
139                                 if (m_sourceObj)
140                                 {
141                                         CValue* copyprop = m_sourceObj->GetProperty(m_exprtxt);
142                                         if (copyprop)
143                                         {
144                                                 CValue *val = copyprop->GetReplica();
145                                                 GetParent()->SetProperty(
146                                                          m_propname,
147                                                          val);
148                                                 val->Release();
149
150                                         }
151                                 }
152                                 break;
153                         }
154                 /* case KX_ACT_PROP_TOGGLE: */ /* accounted for above, no need for userexpr */
155                 default:
156                         {
157
158                         }
159                 }
160
161                 userexpr->Release();
162         }
163         
164         return result;
165 }
166
167         bool 
168
169 SCA_PropertyActuator::
170
171 isValid(
172
173         SCA_PropertyActuator::KX_ACT_PROP_MODE mode
174
175 ) {
176         bool res = false;       
177         res = ((mode > KX_ACT_PROP_NODEF) && (mode < KX_ACT_PROP_MAX));
178         return res;
179 }
180
181
182         CValue* 
183
184 SCA_PropertyActuator::
185
186 GetReplica()
187 {
188
189         SCA_PropertyActuator* replica = new SCA_PropertyActuator(*this);
190
191         replica->ProcessReplica();
192         return replica;
193
194 };
195
196 void SCA_PropertyActuator::ProcessReplica()
197 {
198         // no need to check for self reference like in the constructor:
199         // the replica will always have a different parent
200         if (m_sourceObj)
201                 m_sourceObj->RegisterActuator(this);
202         SCA_IActuator::ProcessReplica();
203 }
204
205 bool SCA_PropertyActuator::UnlinkObject(SCA_IObject* clientobj)
206 {
207         if (clientobj == m_sourceObj)
208         {
209                 // this object is being deleted, we cannot continue to track it.
210                 m_sourceObj = NULL;
211                 return true;
212         }
213         return false;
214 }
215
216 void SCA_PropertyActuator::Relink(CTR_Map<CTR_HashedPtr, void*> *obj_map)
217 {
218         void **h_obj = (*obj_map)[m_sourceObj];
219         if (h_obj) {
220                 if (m_sourceObj)
221                         m_sourceObj->UnregisterActuator(this);
222                 m_sourceObj = (SCA_IObject*)(*h_obj);
223                 m_sourceObj->RegisterActuator(this);
224         }
225 }
226
227 #ifdef WITH_PYTHON
228
229 /* ------------------------------------------------------------------------- */
230 /* Python functions                                                          */
231 /* ------------------------------------------------------------------------- */
232
233 /* Integration hooks ------------------------------------------------------- */
234 PyTypeObject SCA_PropertyActuator::Type = {
235         PyVarObject_HEAD_INIT(NULL, 0)
236         "SCA_PropertyActuator",
237         sizeof(PyObjectPlus_Proxy),
238         0,
239         py_base_dealloc,
240         0,
241         0,
242         0,
243         0,
244         py_base_repr,
245         0,0,0,0,0,0,0,0,0,
246         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
247         0,0,0,0,0,0,0,
248         Methods,
249         0,
250         0,
251         &SCA_IActuator::Type,
252         0,0,0,0,0,0,
253         py_base_new
254 };
255
256 PyMethodDef SCA_PropertyActuator::Methods[] = {
257         {NULL,NULL} //Sentinel
258 };
259
260 PyAttributeDef SCA_PropertyActuator::Attributes[] = {
261         KX_PYATTRIBUTE_STRING_RW_CHECK("propName",0,MAX_PROP_NAME,false,SCA_PropertyActuator,m_propname,CheckProperty),
262         KX_PYATTRIBUTE_STRING_RW("value",0,100,false,SCA_PropertyActuator,m_exprtxt),
263         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 */
264         { NULL }        //Sentinel
265 };
266
267 #endif
268
269 /* eof */