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