741448b10961727b3ba2805d9877ae48bbbacac8
[blender.git] / source / gameengine / GameLogic / SCA_ISensor.h
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 /** \file SCA_IController.h
31  *  \ingroup gamelogic
32  *  \brief Interface Class for all logic Sensors. Implements
33  *   pulsemode and pulsefrequency, and event suppression.
34  */
35
36 #ifndef __SCA_ISENSOR
37 #define __SCA_ISENSOR
38
39 #include "SCA_IController.h"
40
41 #include <vector>
42
43 /**
44  * Interface Class for all logic Sensors. Implements
45  * pulsemode,pulsefrequency 
46  * Use of SG_DList element: link sensors to their respective event manager
47  *                          Head: SCA_EventManager::m_sensors
48  * Use of SG_QList element: not used
49  */
50 class SCA_ISensor : public SCA_ILogicBrick
51 {
52         Py_Header;
53 protected:
54         class SCA_EventManager* m_eventmgr;
55
56         /** Pulse positive  pulses? */
57         bool m_pos_pulsemode;
58
59         /** Pulse negative pulses? */
60         bool m_neg_pulsemode;
61
62         /** Repeat frequency in pulse mode. */
63         int m_pulse_frequency;
64
65         /** Number of ticks since the last positive pulse. */
66         int m_pos_ticks;
67
68         /** Number of ticks since the last negative pulse. */
69         int m_neg_ticks;
70
71         /** invert the output signal*/
72         bool m_invert;
73
74         /** detect level instead of edge*/
75         bool m_level;
76
77         /** tap mode */
78         bool m_tap;
79
80         /** sensor has been reset */
81         bool m_reset;
82
83         /** Sensor must ignore updates? */
84         bool m_suspended;
85
86         /** number of connections to controller */
87         int m_links;
88
89         /** current sensor state */
90         bool m_state;
91
92         /** previous state (for tap option) */
93         bool m_prev_state;
94
95         std::vector<class SCA_IController*>             m_linkedcontrollers;
96
97 public:
98
99         enum sensortype {
100                 ST_NONE = 0,
101                 ST_TOUCH,
102                 ST_NEAR,
103                 ST_RADAR,
104                 // to be updated as needed
105         };
106
107         SCA_ISensor(SCA_IObject* gameobj,
108                                 class SCA_EventManager* eventmgr);;
109         ~SCA_ISensor();
110         virtual void    ReParent(SCA_IObject* parent);
111
112         /** Because we want sensors to share some behaviour, the Activate has     */
113         /* an implementation on this level. It requires an evaluate on the lower */
114         /* level of individual sensors. Mapping the old activate()s is easy.     */
115         /* The IsPosTrig() also has to change, to keep things consistent.        */
116         void Activate(class SCA_LogicManager* logicmgr);
117         virtual bool Evaluate() = 0;
118         virtual bool IsPositiveTrigger();
119         virtual void Init();
120
121         virtual CValue* GetReplica()=0;
122
123         /** Set parameters for the pulsing behaviour.
124          * @param posmode Trigger positive pulses?
125          * @param negmode Trigger negative pulses?
126          * @param freq    Frequency to use when doing pulsing.
127          */
128         void SetPulseMode(bool posmode,
129                                           bool negmode,
130                                           int freq);
131         
132         /** Set inversion of pulses on or off. */
133         void SetInvert(bool inv);
134         /** set the level detection on or off */
135         void SetLevel(bool lvl);
136         void SetTap(bool tap);
137
138         virtual void RegisterToManager();
139         virtual void UnregisterToManager();
140         void Replace_EventManager(class SCA_LogicManager* logicmgr);
141         void ReserveController(int num)
142         {
143                 m_linkedcontrollers.reserve(num);
144         }
145         void LinkToController(SCA_IController* controller);
146         void UnlinkController(SCA_IController* controller);
147         void UnlinkAllControllers();
148         void ActivateControllers(class SCA_LogicManager* logicmgr);
149
150         virtual void ProcessReplica();
151
152         virtual double GetNumber();
153
154         virtual sensortype GetSensorType() { return ST_NONE; }
155
156         /** Stop sensing for a while. */
157         void Suspend();
158
159         /** Is this sensor switched off? */
160         bool IsSuspended();
161         
162         /** get the state of the sensor: positive or negative */
163         bool GetState()
164         {
165                 return m_state;
166         }
167         
168         /** get the previous state of the sensor: positive or negative */
169         bool GetPrevState()
170         {
171                 return m_prev_state;
172         }
173
174         /** get the number of ticks since the last positive pulse */
175         int GetPosTicks()
176         {
177                 return m_pos_ticks;
178         }
179
180         /** get the number of ticks since the last negative pulse */
181         int GetNegTicks()
182         {
183                 return m_neg_ticks;
184         }
185
186         /** Resume sensing. */
187         void Resume();
188
189         void ClrLink()
190                 { m_links = 0; }
191         void IncLink()
192                 { if (!m_links++) RegisterToManager(); }
193         void DecLink();
194         bool IsNoLink() const 
195                 { return !m_links; }
196
197 #ifdef WITH_PYTHON
198         /* Python functions: */
199         KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,reset);
200         
201         static PyObject*        pyattr_get_triggered(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
202         static PyObject*        pyattr_get_positive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
203         static PyObject*        pyattr_get_status(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
204         static PyObject*        pyattr_get_posTicks(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
205         static PyObject*        pyattr_get_negTicks(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
206
207         static int          pyattr_check_level(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
208         static int          pyattr_check_tap(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
209         
210         enum SensorStatus {
211                 KX_SENSOR_INACTIVE = 0,
212                 KX_SENSOR_JUST_ACTIVATED,
213                 KX_SENSOR_ACTIVE,
214                 KX_SENSOR_JUST_DEACTIVATED
215         
216         };
217 #endif // WITH_PYTHON
218 };
219
220 #endif //__SCA_ISENSOR
221