Removed my own patch #8208: export SCA_ISensor::Evaluate() to Python. It was only...
[blender.git] / source / gameengine / GameLogic / SCA_ISensor.cpp
1 /**
2  * Abstract class for sensor logic bricks
3  *
4  * $Id$
5  *
6  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version. The Blender
12  * Foundation also sells licenses for use in proprietary software under
13  * the Blender License.  See http://www.blender.org/BL/ for information
14  * about this.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  *
25  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
26  * All rights reserved.
27  *
28  * The Original Code is: all of this file.
29  *
30  * Contributor(s): none yet.
31  *
32  * ***** END GPL/BL DUAL LICENSE BLOCK *****
33  */
34
35 #include "SCA_ISensor.h"
36 #include "SCA_EventManager.h"
37 #include "SCA_LogicManager.h"
38
39 #ifdef HAVE_CONFIG_H
40 #include <config.h>
41 #endif
42
43 /* Native functions */
44 void    SCA_ISensor::ReParent(SCA_IObject* parent)
45 {
46         SCA_ILogicBrick::ReParent(parent);
47         m_eventmgr->RegisterSensor(this);
48         this->SetActive(false);
49 }
50
51
52 SCA_ISensor::SCA_ISensor(SCA_IObject* gameobj,
53                                                  class SCA_EventManager* eventmgr,
54                                                  PyTypeObject* T ) :
55         SCA_ILogicBrick(gameobj,T),
56         m_triggered(false)
57 {
58         m_suspended = false;
59         m_invert = false;
60         m_pos_ticks = 0;
61         m_neg_ticks = 0;
62         m_pos_pulsemode = false;
63         m_neg_pulsemode = false;
64         m_pulse_frequency = 0;
65         
66         m_eventmgr = eventmgr;
67 }
68
69
70 SCA_ISensor::~SCA_ISensor()  
71 {
72         // intentionally empty
73 }
74
75 bool SCA_ISensor::IsPositiveTrigger() { 
76         bool result = false;
77         
78         if (m_eventval) {
79                 result = (m_eventval->GetNumber() != 0.0);
80         }
81         if (m_invert) {
82                 result = !result;
83         }
84         
85         return result;
86 }
87
88 void SCA_ISensor::SetPulseMode(bool posmode, 
89                                                            bool negmode,
90                                                            int freq) {
91         m_pos_pulsemode = posmode;
92         m_neg_pulsemode = negmode;
93         m_pulse_frequency = freq;
94 }
95
96 void SCA_ISensor::SetInvert(bool inv) {
97         m_invert = inv;
98 }
99
100
101 float SCA_ISensor::GetNumber() {
102         return IsPositiveTrigger();
103 }
104
105 void SCA_ISensor::Suspend() {
106         m_suspended = true;
107 }
108
109 bool SCA_ISensor::IsSuspended() {
110         return m_suspended;
111 }
112
113 void SCA_ISensor::Resume() {
114         m_suspended = false;
115 }
116
117 /* python integration */
118
119 PyTypeObject SCA_ISensor::Type = {
120         PyObject_HEAD_INIT(&PyType_Type)
121         0,
122         "SCA_ISensor",
123         sizeof(SCA_ISensor),
124         0,
125         PyDestructor,
126         0,
127         __getattr,
128         __setattr,
129         0, //&MyPyCompare,
130         __repr,
131         0, //&cvalue_as_number,
132         0,
133         0,
134         0,
135         0
136 };
137
138 PyParentObject SCA_ISensor::Parents[] = {
139         &SCA_ISensor::Type,
140         &SCA_ILogicBrick::Type,
141         &CValue::Type,
142         NULL
143 };
144 PyMethodDef SCA_ISensor::Methods[] = {
145         {"isPositive", (PyCFunction) SCA_ISensor::sPyIsPositive, 
146          METH_VARARGS, IsPositive_doc},
147         {"getUsePosPulseMode", (PyCFunction) SCA_ISensor::sPyGetUsePosPulseMode, 
148          METH_VARARGS, GetUsePosPulseMode_doc},
149         {"setUsePosPulseMode", (PyCFunction) SCA_ISensor::sPySetUsePosPulseMode, 
150          METH_VARARGS, SetUsePosPulseMode_doc},
151         {"getFrequency", (PyCFunction) SCA_ISensor::sPyGetFrequency, 
152          METH_VARARGS, GetFrequency_doc},
153         {"setFrequency", (PyCFunction) SCA_ISensor::sPySetFrequency, 
154          METH_VARARGS, SetFrequency_doc},
155         {"getUseNegPulseMode", (PyCFunction) SCA_ISensor::sPyGetUseNegPulseMode, 
156          METH_VARARGS, GetUseNegPulseMode_doc},
157         {"setUseNegPulseMode", (PyCFunction) SCA_ISensor::sPySetUseNegPulseMode, 
158          METH_VARARGS, SetUseNegPulseMode_doc},
159         {"getInvert", (PyCFunction) SCA_ISensor::sPyGetInvert, 
160          METH_VARARGS, GetInvert_doc},
161         {"setInvert", (PyCFunction) SCA_ISensor::sPySetInvert, 
162          METH_VARARGS, SetInvert_doc},
163         {NULL,NULL} //Sentinel
164 };
165
166
167 PyObject*
168 SCA_ISensor::_getattr(const STR_String& attr)
169 {
170   _getattr_up(SCA_ILogicBrick);
171 }
172
173
174 void SCA_ISensor::RegisterToManager()
175 {
176         m_eventmgr->RegisterSensor(this);
177 }
178
179 void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr,      CValue* event)
180 {
181         
182         // calculate if a __triggering__ is wanted
183         if (!m_suspended) {
184                 bool result = this->Evaluate(event);
185                 if (result) {
186                         logicmgr->AddActivatedSensor(this);     
187                 } else
188                 {
189                         /* First, the pulsing behaviour, if pulse mode is
190                          * active. It seems something goes wrong if pulse mode is
191                          * not set :( */
192                         if (m_pos_pulsemode) {
193                                 m_pos_ticks++;
194                                 if (m_pos_ticks > m_pulse_frequency) {
195                                         if ( this->IsPositiveTrigger() )
196                                         {
197                                                 logicmgr->AddActivatedSensor(this);
198                                         }
199                                         m_pos_ticks = 0;
200                                 } 
201                         }
202                         
203                         if (m_neg_pulsemode)
204                         {
205                                 m_neg_ticks++;
206                                 if (m_neg_ticks > m_pulse_frequency) {
207                                         if (!this->IsPositiveTrigger() )
208                                         {
209                                                 logicmgr->AddActivatedSensor(this);
210                                         }
211                                         m_neg_ticks = 0;
212                                 }
213                         }
214                 }
215         } 
216 }
217
218 /* Python functions: */
219 char SCA_ISensor::IsPositive_doc[] = 
220 "isPositive()\n"
221 "\tReturns whether the sensor is registered a positive event.\n";
222 PyObject* SCA_ISensor::PyIsPositive(PyObject* self, PyObject* args, PyObject* kwds)
223 {
224         int retval = IsPositiveTrigger();
225         return PyInt_FromLong(retval);
226 }
227
228 /**
229  * getUsePulseMode: getter for the pulse mode (KX_TRUE = on)
230  */
231 char SCA_ISensor::GetUsePosPulseMode_doc[] = 
232 "getUsePosPulseMode()\n"
233 "\tReturns whether positive pulse mode is active.\n";
234 PyObject* SCA_ISensor::PyGetUsePosPulseMode(PyObject* self, PyObject* args, PyObject* kwds)
235 {
236         return BoolToPyArg(m_pos_pulsemode);
237 }
238
239 /**
240  * setUsePulseMode: setter for the pulse mode (KX_TRUE = on)
241  */
242 char SCA_ISensor::SetUsePosPulseMode_doc[] = 
243 "setUsePosPulseMode(pulse?)\n"
244 "\t - pulse? : Pulse when a positive event occurs?\n"
245 "\t            (KX_TRUE, KX_FALSE)\n"
246 "\tSet whether to do pulsing when positive pulses occur.\n";
247 PyObject* SCA_ISensor::PySetUsePosPulseMode(PyObject* self, PyObject* args, PyObject* kwds)
248 {
249         int pyarg = 0;
250         if(!PyArg_ParseTuple(args, "i", &pyarg)) { return NULL; }
251         m_pos_pulsemode = PyArgToBool(pyarg);
252         Py_Return;
253 }
254
255 /**
256  * getFrequency: getter for the pulse mode interval
257  */
258 char SCA_ISensor::GetFrequency_doc[] = 
259 "getFrequency()\n"
260 "\tReturns the frequency of the updates in pulse mode.\n" ;
261 PyObject* SCA_ISensor::PyGetFrequency(PyObject* self, PyObject* args, PyObject* kwds)
262 {
263         return PyInt_FromLong(m_pulse_frequency);
264 }
265
266 /**
267  * setFrequency: setter for the pulse mode (KX_TRUE = on)
268  */
269 char SCA_ISensor::SetFrequency_doc[] = 
270 "setFrequency(pulse_frequency)\n"
271 "\t- pulse_frequency: The frequency of the updates in pulse mode (integer)"
272 "\tSet the frequency of the updates in pulse mode.\n"
273 "\tIf the frequency is negative, it is set to 0.\n" ;
274 PyObject* SCA_ISensor::PySetFrequency(PyObject* self, PyObject* args, PyObject* kwds)
275 {
276         int pulse_frequencyArg = 0;
277
278         if(!PyArg_ParseTuple(args, "i", &pulse_frequencyArg)) {
279                 return NULL;
280         }
281         
282         /* We can do three things here: clip, ignore and raise an exception.  */
283         /* Exceptions don't work yet, ignoring is not desirable now...        */
284         if (pulse_frequencyArg < 0) {
285                 pulse_frequencyArg = 0;
286         };      
287         m_pulse_frequency = pulse_frequencyArg;
288
289         Py_Return;
290 }
291
292
293 char SCA_ISensor::GetInvert_doc[] = 
294 "getInvert()\n"
295 "\tReturns whether or not pulses from this sensor are inverted.\n" ;
296 PyObject* SCA_ISensor::PyGetInvert(PyObject* self, PyObject* args, PyObject* kwds)
297 {
298         return BoolToPyArg(m_invert);
299 }
300
301 char SCA_ISensor::SetInvert_doc[] = 
302 "setInvert(invert?)\n"
303 "\t- invert?: Invert the event-values? (KX_TRUE, KX_FALSE)\n"
304 "\tSet whether to invert pulses.\n";
305 PyObject* SCA_ISensor::PySetInvert(PyObject* self, PyObject* args, PyObject* kwds)
306 {
307         int pyarg = 0;
308         if(!PyArg_ParseTuple(args, "i", &pyarg)) { return NULL; }
309         m_invert = PyArgToBool(pyarg);
310         Py_Return;
311 }
312
313 char SCA_ISensor::GetUseNegPulseMode_doc[] = 
314 "getUseNegPulseMode()\n"
315 "\tReturns whether negative pulse mode is active.\n";
316 PyObject* SCA_ISensor::PyGetUseNegPulseMode(PyObject* self, PyObject* args, PyObject* kwds)
317 {
318         return BoolToPyArg(m_neg_pulsemode);
319 }
320
321 char SCA_ISensor::SetUseNegPulseMode_doc[] = 
322 "setUseNegPulseMode(pulse?)\n"
323 "\t - pulse? : Pulse when a negative event occurs?\n"
324 "\t            (KX_TRUE, KX_FALSE)\n"
325 "\tSet whether to do pulsing when negative pulses occur.\n";
326 PyObject* SCA_ISensor::PySetUseNegPulseMode(PyObject* self, PyObject* args, PyObject* kwds)
327 {
328         int pyarg = 0;
329         if(!PyArg_ParseTuple(args, "i", &pyarg)) { return NULL; }
330         m_neg_pulsemode = PyArgToBool(pyarg);
331         Py_Return;
332 }
333
334 /* eof */