- BGE, Some sensors, stored the event manager in 2 places (became confusing to do...
[blender-staging.git] / source / gameengine / Ketsji / KXNetwork / KX_NetworkMessageSensor.cpp
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  * Ketsji Logic Extenstion: Network Message Sensor generic implementation
29  */
30
31 #include "KX_NetworkMessageSensor.h"
32 #include "KX_NetworkEventManager.h"
33 #include "NG_NetworkMessage.h"
34 #include "NG_NetworkScene.h"
35 #include "NG_NetworkObject.h"
36 #include "SCA_IObject.h"        
37 #include "InputParser.h"
38 #include "ListValue.h"
39 #include "StringValue.h"
40
41 #ifdef HAVE_CONFIG_H
42 #include <config.h>
43 #endif
44
45 #ifdef NAN_NET_DEBUG
46   #include <iostream>
47 #endif
48
49 KX_NetworkMessageSensor::KX_NetworkMessageSensor(
50         class KX_NetworkEventManager* eventmgr, // our eventmanager
51         class NG_NetworkScene *NetworkScene,    // our scene
52         SCA_IObject* gameobj,                                   // the sensor controlling object
53         const STR_String &subject,
54         PyTypeObject* T
55 ) :
56     SCA_ISensor(gameobj,eventmgr,T),
57     m_NetworkScene(NetworkScene),
58     m_subject(subject),
59     m_frame_message_count (0),
60     m_BodyList(NULL),
61     m_SubjectList(NULL)
62 {
63         Init();
64 }
65
66 void KX_NetworkMessageSensor::Init()
67 {
68     m_IsUp = false;
69 }
70
71 KX_NetworkMessageSensor::~KX_NetworkMessageSensor()
72 {
73 }
74
75 CValue* KX_NetworkMessageSensor::GetReplica() {
76         // This is the standard sensor implementation of GetReplica
77         // There may be more network message sensor specific stuff to do here.
78         CValue* replica = new KX_NetworkMessageSensor(*this);
79
80         if (replica == NULL) return NULL;
81         replica->ProcessReplica();
82
83         return replica;
84 }
85
86 // Return true only for flank (UP and DOWN)
87 bool KX_NetworkMessageSensor::Evaluate()
88 {
89         bool result = false;
90         bool WasUp = m_IsUp;
91
92         m_IsUp = false;
93
94         if (m_BodyList) {
95                 m_BodyList->Release();
96                 m_BodyList = NULL;
97         }
98
99         if (m_SubjectList) {
100                 m_SubjectList->Release();
101                 m_SubjectList = NULL;
102         }
103
104         STR_String& toname=GetParent()->GetName();
105         STR_String& subject = this->m_subject;
106
107         vector<NG_NetworkMessage*> messages =
108                 m_NetworkScene->FindMessages(toname,"",subject,true);
109
110         m_frame_message_count = messages.size();
111
112         if (!messages.empty()) {
113 #ifdef NAN_NET_DEBUG
114                 printf("KX_NetworkMessageSensor found one or more messages\n");
115 #endif
116                 m_IsUp = true;
117                 m_BodyList = new CListValue();
118                 m_SubjectList = new CListValue();
119         }
120
121         vector<NG_NetworkMessage*>::iterator mesit;
122         for (mesit=messages.begin();mesit!=messages.end();mesit++)
123         {
124                 // save the body
125                 const STR_String& body = (*mesit)->GetMessageText();
126                 // save the subject
127                 const STR_String& messub = (*mesit)->GetSubject();
128 #ifdef NAN_NET_DEBUG
129                 if (body) {
130                         cout << "body [" << body << "]\n";
131                 }
132 #endif
133                 m_BodyList->Add(new CStringValue(body,"body"));
134                 // Store Subject
135                 m_SubjectList->Add(new CStringValue(messub,"subject"));
136
137                 // free the message
138                 (*mesit)->Release();
139         }
140         messages.clear();
141
142         result = (WasUp != m_IsUp);
143
144         // Return always true if a message was received otherwise we can loose messages
145         if (m_IsUp)
146                 return true;
147         // Is it usefull to return also true when the first frame without a message?? 
148         // This will cause a fast on/off cycle that seems useless!
149         return result;
150 }
151
152 // return true for being up (no flank needed)
153 bool KX_NetworkMessageSensor::IsPositiveTrigger()
154 {
155 //      printf("KX_NetworkMessageSensor IsPositiveTrigger\n");
156         //attempt to fix [ #3809 ] IPO Actuator does not work with some Sensors
157         //a better solution is to properly introduce separate Edge and Level triggering concept
158
159         return m_IsUp;
160 }
161
162 /* --------------------------------------------------------------------- */
163 /* Python interface ---------------------------------------------------- */
164 /* --------------------------------------------------------------------- */
165
166 /* Integration hooks --------------------------------------------------- */
167 PyTypeObject KX_NetworkMessageSensor::Type = {
168 #if (PY_VERSION_HEX >= 0x02060000)
169         PyVarObject_HEAD_INIT(NULL, 0)
170 #else
171         /* python 2.5 and below */
172         PyObject_HEAD_INIT( NULL )  /* required py macro */
173         0,                          /* ob_size */
174 #endif
175         "KX_NetworkMessageSensor",
176         sizeof(PyObjectPlus_Proxy),
177         0,
178         py_base_dealloc,
179         0,
180         0,
181         0,
182         0,
183         py_base_repr,
184         0,0,0,0,0,0,
185         py_base_getattro,
186         py_base_setattro,
187         0,0,0,0,0,0,0,0,0,
188         Methods
189 };
190
191 PyParentObject KX_NetworkMessageSensor::Parents[] = {
192         &KX_NetworkMessageSensor::Type,
193         &SCA_ISensor::Type,
194         &SCA_ILogicBrick::Type,
195         &CValue::Type,
196         NULL
197 };
198
199 PyMethodDef KX_NetworkMessageSensor::Methods[] = {
200         // Deprecated ----->
201         {"setSubjectFilterText", (PyCFunction)
202                 KX_NetworkMessageSensor::sPySetSubjectFilterText, METH_O,
203                 (PY_METHODCHAR)SetSubjectFilterText_doc},
204         {"getFrameMessageCount", (PyCFunction)
205                 KX_NetworkMessageSensor::sPyGetFrameMessageCount, METH_NOARGS,
206                 (PY_METHODCHAR)GetFrameMessageCount_doc},
207         {"getBodies", (PyCFunction)
208                 KX_NetworkMessageSensor::sPyGetBodies, METH_NOARGS,
209                 (PY_METHODCHAR)GetBodies_doc},
210         {"getSubject", (PyCFunction)
211                 KX_NetworkMessageSensor::sPyGetSubject, METH_NOARGS,
212                 (PY_METHODCHAR)GetSubject_doc},
213         {"getSubjects", (PyCFunction)
214                 KX_NetworkMessageSensor::sPyGetSubjects, METH_NOARGS,
215                 (PY_METHODCHAR)GetSubjects_doc},
216         // <-----
217         {NULL,NULL} //Sentinel
218 };
219
220 PyAttributeDef KX_NetworkMessageSensor::Attributes[] = {
221         KX_PYATTRIBUTE_STRING_RW("subject", 0, 100, false, KX_NetworkMessageSensor, m_subject),
222         KX_PYATTRIBUTE_INT_RO("frameMessageCount", KX_NetworkMessageSensor, m_frame_message_count),
223         KX_PYATTRIBUTE_RO_FUNCTION("bodies", KX_NetworkMessageSensor, pyattr_get_bodies),
224         KX_PYATTRIBUTE_RO_FUNCTION("subjects", KX_NetworkMessageSensor, pyattr_get_subjects),
225         { NULL }        //Sentinel
226 };
227
228 PyObject* KX_NetworkMessageSensor::py_getattro(PyObject *attr) {
229         py_getattro_up(SCA_ISensor);
230 }
231
232 PyObject* KX_NetworkMessageSensor::py_getattro_dict() {
233         py_getattro_dict_up(SCA_ISensor);
234 }
235
236 int KX_NetworkMessageSensor::py_setattro(PyObject *attr, PyObject *value) {
237         return SCA_ISensor::py_setattro(attr, value);
238 }
239
240 PyObject* KX_NetworkMessageSensor::pyattr_get_bodies(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
241 {
242         KX_NetworkMessageSensor *self = static_cast<KX_NetworkMessageSensor*>(self_v);
243         if (self->m_BodyList) {
244                 return self->m_BodyList->GetProxy();
245         } else {
246                 return (new CListValue())->NewProxy(true);
247         }
248 }
249
250 PyObject* KX_NetworkMessageSensor::pyattr_get_subjects(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
251 {
252         KX_NetworkMessageSensor *self = static_cast<KX_NetworkMessageSensor*>(self_v);
253         if (self->m_SubjectList) {
254                 return self->m_SubjectList->GetProxy();
255         } else {
256                 return (new CListValue())->NewProxy(true);
257         }
258 }
259
260 // Deprecated ----->
261 // 1. Set the message subject that this sensor listens for
262 const char KX_NetworkMessageSensor::SetSubjectFilterText_doc[] = 
263 "\tsetSubjectFilterText(value)\n"
264 "\tChange the message subject text that this sensor is listening to.\n";
265
266 PyObject* KX_NetworkMessageSensor::PySetSubjectFilterText(PyObject* value)
267 {
268         ShowDeprecationWarning("setSubjectFilterText()", "subject");
269         char* Subject = PyString_AsString(value);
270         if (Subject==NULL) {
271                 PyErr_SetString(PyExc_TypeError, "sensor.tsetSubjectFilterText(string): KX_NetworkMessageSensor, expected a string message");
272                 return NULL;
273         }
274         
275         m_subject = Subject;
276         Py_RETURN_NONE;
277 }
278
279 // 2. Get the number of messages received since the last frame
280 const char KX_NetworkMessageSensor::GetFrameMessageCount_doc[] =
281 "\tgetFrameMessageCount()\n"
282 "\tGet the number of messages received since the last frame.\n";
283
284 PyObject* KX_NetworkMessageSensor::PyGetFrameMessageCount()
285 {
286         ShowDeprecationWarning("getFrameMessageCount()", "frameMessageCount");
287         return PyInt_FromLong(long(m_frame_message_count));
288 }
289
290 // 3. Get the message bodies
291 const char KX_NetworkMessageSensor::GetBodies_doc[] =
292 "\tgetBodies()\n"
293 "\tGet the list of message bodies.\n";
294
295 PyObject* KX_NetworkMessageSensor::PyGetBodies()
296 {
297         ShowDeprecationWarning("getBodies()", "bodies");
298         if (m_BodyList) {
299                 return m_BodyList->GetProxy();
300         } else {
301                 return (new CListValue())->NewProxy(true);
302         }
303 }
304
305 // 4. Get the message subject: field of the message sensor
306 const char KX_NetworkMessageSensor::GetSubject_doc[] =
307 "\tgetSubject()\n"
308 "\tGet the subject: field of the message sensor.\n";
309
310 PyObject* KX_NetworkMessageSensor::PyGetSubject()
311 {
312         ShowDeprecationWarning("getSubject()", "subject");
313         return PyString_FromString(m_subject ? m_subject : "");
314 }
315
316 // 5. Get the message subjects
317 const char KX_NetworkMessageSensor::GetSubjects_doc[] =
318 "\tgetSubjects()\n"
319 "\tGet list of message subjects.\n";
320
321 PyObject* KX_NetworkMessageSensor::PyGetSubjects()
322 {
323         ShowDeprecationWarning("getSubjects()", "subjects");
324         if (m_SubjectList) {
325                 return m_SubjectList->GetProxy();
326         } else {
327                 return (new CListValue())->NewProxy(true);
328         }
329 }
330 // <----- Deprecated