81864ab6a3461fd20378642744960db75369fe47
[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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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  * Interface Class for all logic Sensors. Implements
29  * pulsemode and pulsefrequency, and event suppression.
30  */
31
32 #ifndef __SCA_ISENSOR
33 #define __SCA_ISENSOR
34
35 #include "SCA_IController.h"
36
37 #include <vector>
38
39 /**
40  * Interface Class for all logic Sensors. Implements
41  * pulsemode,pulsefrequency 
42  * Use of SG_DList element: link sensors to their respective event manager
43  *                          Head: SCA_EventManager::m_sensors
44  * Use of SG_QList element: not used
45  */
46 class SCA_ISensor : public SCA_ILogicBrick
47 {
48         Py_Header;
49 protected:
50         class SCA_EventManager* m_eventmgr;
51
52         /** Pulse positive  pulses? */
53         bool m_pos_pulsemode;
54
55         /** Pulse negative pulses? */
56         bool m_neg_pulsemode;
57
58         /** Repeat frequency in pulse mode. */
59         int m_pulse_frequency;
60
61         /** Number of ticks since the last positive pulse. */
62         int m_pos_ticks;
63
64         /** Number of ticks since the last negative pulse. */
65         int m_neg_ticks;
66
67         /** invert the output signal*/
68         bool m_invert;
69
70         /** detect level instead of edge*/
71         bool m_level;
72
73         /** tap mode */
74         bool m_tap;
75
76         /** sensor has been reset */
77         bool m_reset;
78
79         /** Sensor must ignore updates? */
80         bool m_suspended;
81
82         /** number of connections to controller */
83         int m_links;
84
85         /** current sensor state */
86         bool m_state;
87
88         /** previous state (for tap option) */
89         bool m_prev_state;
90
91         std::vector<class SCA_IController*>             m_linkedcontrollers;
92
93 public:
94
95         enum sensortype {
96                 ST_NONE = 0,
97                 ST_TOUCH,
98                 ST_NEAR,
99                 ST_RADAR,
100                 // to be updated as needed
101         };
102
103         SCA_ISensor(SCA_IObject* gameobj,
104                                 class SCA_EventManager* eventmgr);;
105         ~SCA_ISensor();
106         virtual void    ReParent(SCA_IObject* parent);
107
108         /** Because we want sensors to share some behaviour, the Activate has     */
109         /* an implementation on this level. It requires an evaluate on the lower */
110         /* level of individual sensors. Mapping the old activate()s is easy.     */
111         /* The IsPosTrig() also has to change, to keep things consistent.        */
112         void Activate(class SCA_LogicManager* logicmgr);
113         virtual bool Evaluate() = 0;
114         virtual bool IsPositiveTrigger();
115         virtual void Init();
116
117         virtual CValue* GetReplica()=0;
118
119         /** Set parameters for the pulsing behaviour.
120          * @param posmode Trigger positive pulses?
121          * @param negmode Trigger negative pulses?
122          * @param freq    Frequency to use when doing pulsing.
123          */
124         void SetPulseMode(bool posmode,
125                                           bool negmode,
126                                           int freq);
127         
128         /** Set inversion of pulses on or off. */
129         void SetInvert(bool inv);
130         /** set the level detection on or off */
131         void SetLevel(bool lvl);
132         void SetTap(bool tap);
133
134         virtual void RegisterToManager();
135         virtual void UnregisterToManager();
136         void ReserveController(int num)
137         {
138                 m_linkedcontrollers.reserve(num);
139         }
140         void LinkToController(SCA_IController* controller);
141         void UnlinkController(SCA_IController* controller);
142         void UnlinkAllControllers();
143         void ActivateControllers(class SCA_LogicManager* logicmgr);
144
145         virtual void ProcessReplica();
146
147         virtual double GetNumber();
148
149         virtual sensortype GetSensorType() { return ST_NONE; }
150
151         /** Stop sensing for a while. */
152         void Suspend();
153
154         /** Is this sensor switched off? */
155         bool IsSuspended();
156         
157         /** get the state of the sensor: positive or negative */
158         bool GetState()
159         {
160                 return m_state;
161         }
162
163         /** Resume sensing. */
164         void Resume();
165
166         void ClrLink()
167                 { m_links = 0; }
168         void IncLink()
169                 { if (!m_links++) RegisterToManager(); }
170         void DecLink();
171         bool IsNoLink() const 
172                 { return !m_links; }
173
174         /* Python functions: */
175
176         //Deprecated functions ----->
177         KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,IsPositive);
178         KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,IsTriggered);
179         KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,GetUsePosPulseMode);
180         KX_PYMETHOD_DOC_VARARGS(SCA_ISensor,SetUsePosPulseMode);
181         KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,GetFrequency);
182         KX_PYMETHOD_DOC_VARARGS(SCA_ISensor,SetFrequency);
183         KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,GetUseNegPulseMode);
184         KX_PYMETHOD_DOC_VARARGS(SCA_ISensor,SetUseNegPulseMode);
185         KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,GetInvert);
186         KX_PYMETHOD_DOC_VARARGS(SCA_ISensor,SetInvert);
187         KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,GetLevel);
188         KX_PYMETHOD_DOC_VARARGS(SCA_ISensor,SetLevel);
189         //<------
190         KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,reset);
191         
192         static PyObject*        pyattr_get_triggered(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
193         static PyObject*        pyattr_get_positive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
194         static int          pyattr_check_level(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
195         static int          pyattr_check_tap(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
196 };
197
198 #endif //__SCA_ISENSOR
199