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