optionally use guarded alloc for tiles compositor, also replace allocation functions...
[blender.git] / source / gameengine / GameLogic / SCA_IController.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file gameengine/GameLogic/SCA_IController.cpp
29  *  \ingroup gamelogic
30  */
31
32
33 #include <stddef.h>
34
35 #include "SCA_IController.h"
36 #include "SCA_LogicManager.h"
37 #include "SCA_IActuator.h"
38 #include "SCA_ISensor.h"
39 #include "PyObjectPlus.h"
40 #include "../Ketsji/KX_PythonSeq.h" /* not nice, only need for KX_PythonSeq_CreatePyObject */
41
42 #include <stdio.h>
43
44 SCA_IController::SCA_IController(SCA_IObject* gameobj)
45         :
46         SCA_ILogicBrick(gameobj),
47         m_statemask(0),
48         m_justActivated(false)
49 {
50 }
51         
52
53         
54 SCA_IController::~SCA_IController()
55 {
56         //UnlinkAllActuators();
57 }
58
59
60
61 std::vector<class SCA_ISensor*>& SCA_IController::GetLinkedSensors()
62 {
63         return m_linkedsensors;
64 }
65
66
67
68 std::vector<class SCA_IActuator*>& SCA_IController::GetLinkedActuators()
69 {
70         return m_linkedactuators;
71 }
72
73
74
75 void SCA_IController::UnlinkAllSensors()
76 {
77         std::vector<class SCA_ISensor*>::iterator sensit;
78         for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
79         {
80                 if (IsActive()) 
81                 {
82                         (*sensit)->DecLink();
83                 }
84                 (*sensit)->UnlinkController(this);
85         }
86         m_linkedsensors.clear();
87 }
88
89
90
91 void SCA_IController::UnlinkAllActuators()
92 {
93         std::vector<class SCA_IActuator*>::iterator actit;
94         for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
95         {
96                 if (IsActive()) 
97                 {
98                         (*actit)->DecLink();
99                 }
100                 (*actit)->UnlinkController(this);
101         }
102         m_linkedactuators.clear();
103 }
104
105 void SCA_IController::LinkToActuator(SCA_IActuator* actua)
106 {
107         m_linkedactuators.push_back(actua);
108         if (IsActive())
109         {
110                 actua->IncLink();
111         }
112 }
113
114 void    SCA_IController::UnlinkActuator(class SCA_IActuator* actua)
115 {
116         std::vector<class SCA_IActuator*>::iterator actit;
117         for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
118         {
119                 if ((*actit) == actua)
120                 {
121                         if (IsActive())
122                         {
123                                 (*actit)->DecLink();
124                         }
125                         *actit = m_linkedactuators.back();
126                         m_linkedactuators.pop_back();
127                         return;
128                 }
129         }
130         printf("Missing link from controller %s:%s to actuator %s:%s\n", 
131                 m_gameobj->GetName().ReadPtr(), GetName().ReadPtr(), 
132                 actua->GetParent()->GetName().ReadPtr(), actua->GetName().ReadPtr());
133 }
134
135 void SCA_IController::LinkToSensor(SCA_ISensor* sensor)
136 {
137         m_linkedsensors.push_back(sensor);
138         if (IsActive())
139         {
140                 sensor->IncLink();
141         }
142 }
143
144 void SCA_IController::UnlinkSensor(class SCA_ISensor* sensor)
145 {
146         std::vector<class SCA_ISensor*>::iterator sensit;
147         for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
148         {
149                 if ((*sensit) == sensor)
150                 {
151                         if (IsActive())
152                         {
153                                 sensor->DecLink();
154                         }
155                         *sensit = m_linkedsensors.back();
156                         m_linkedsensors.pop_back();
157                         return;
158                 }
159         }
160         printf("Missing link from controller %s:%s to sensor %s:%s\n", 
161                 m_gameobj->GetName().ReadPtr(), GetName().ReadPtr(), 
162                 sensor->GetParent()->GetName().ReadPtr(), sensor->GetName().ReadPtr());
163 }
164
165
166 void SCA_IController::ApplyState(unsigned int state)
167 {
168         std::vector<class SCA_IActuator*>::iterator actit;
169         std::vector<class SCA_ISensor*>::iterator sensit;
170
171         if (m_statemask & state) 
172         {
173                 if (!IsActive()) 
174                 {
175                         // reactive the controller, all the links to actuator are valid again
176                         for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
177                         {
178                                 (*actit)->IncLink();
179                         }
180
181                         for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
182                         {
183                                 (*sensit)->IncLink();
184                         }
185                         SetActive(true);
186                         m_justActivated = true;
187                 }
188         } else if (IsActive())
189         {
190                 for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
191                 {
192                         (*actit)->DecLink();
193                 }
194                 for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
195                 {
196                         (*sensit)->DecLink();
197                 }
198                 SetActive(false);
199                 m_justActivated = false;
200         }
201 }
202
203 #ifdef WITH_PYTHON
204
205 /* Python api */
206
207 PyTypeObject SCA_IController::Type = {
208         PyVarObject_HEAD_INIT(NULL, 0)
209         "SCA_IController",
210         sizeof(PyObjectPlus_Proxy),
211         0,
212         py_base_dealloc,
213         0,
214         0,
215         0,
216         0,
217         py_base_repr,
218         0,0,0,0,0,0,0,0,0,
219         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
220         0,0,0,0,0,0,0,
221         Methods,
222         0,
223         0,
224         &SCA_ILogicBrick::Type,
225         0,0,0,0,0,0,
226         py_base_new
227 };
228
229 PyMethodDef SCA_IController::Methods[] = {
230         {NULL,NULL} //Sentinel
231 };
232
233 PyAttributeDef SCA_IController::Attributes[] = {
234         KX_PYATTRIBUTE_RO_FUNCTION("state", SCA_IController, pyattr_get_state),
235         KX_PYATTRIBUTE_RO_FUNCTION("sensors", SCA_IController, pyattr_get_sensors),
236         KX_PYATTRIBUTE_RO_FUNCTION("actuators", SCA_IController, pyattr_get_actuators),
237         KX_PYATTRIBUTE_BOOL_RW("useHighPriority",SCA_IController,m_bookmark),
238         { NULL }        //Sentinel
239 };
240
241 PyObject* SCA_IController::pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
242 {
243         SCA_IController* self= static_cast<SCA_IController*>(self_v);
244         return PyLong_FromSsize_t(self->m_statemask);
245 }
246
247 PyObject* SCA_IController::pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
248 {
249         return KX_PythonSeq_CreatePyObject((static_cast<SCA_IController*>(self_v))->m_proxy, KX_PYGENSEQ_CONT_TYPE_SENSORS);    
250 }
251
252 PyObject* SCA_IController::pyattr_get_actuators(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
253 {
254         return KX_PythonSeq_CreatePyObject((static_cast<SCA_IController*>(self_v))->m_proxy, KX_PYGENSEQ_CONT_TYPE_ACTUATORS);  
255 }
256 #endif // WITH_PYTHON