Blender  V2.59
KX_NetworkMessageSensor.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: KX_NetworkMessageSensor.cpp 35171 2011-02-25 13:35:59Z jesterking $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00021  * All rights reserved.
00022  *
00023  * The Original Code is: all of this file.
00024  *
00025  * Contributor(s): none yet.
00026  *
00027  * ***** END GPL LICENSE BLOCK *****
00028  * Ketsji Logic Extenstion: Network Message Sensor generic implementation
00029  */
00030 
00036 #include <stddef.h>
00037 
00038 #include "KX_NetworkMessageSensor.h"
00039 #include "KX_NetworkEventManager.h"
00040 #include "NG_NetworkMessage.h"
00041 #include "NG_NetworkScene.h"
00042 #include "NG_NetworkObject.h"
00043 #include "SCA_IObject.h"        
00044 #include "InputParser.h"
00045 #include "ListValue.h"
00046 #include "StringValue.h"
00047 
00048 #ifdef NAN_NET_DEBUG
00049   #include <iostream>
00050 #endif
00051 
00052 KX_NetworkMessageSensor::KX_NetworkMessageSensor(
00053         class KX_NetworkEventManager* eventmgr, // our eventmanager
00054         class NG_NetworkScene *NetworkScene,    // our scene
00055         SCA_IObject* gameobj,                                   // the sensor controlling object
00056         const STR_String &subject
00057 ) :
00058     SCA_ISensor(gameobj,eventmgr),
00059     m_NetworkScene(NetworkScene),
00060     m_subject(subject),
00061     m_frame_message_count (0),
00062     m_BodyList(NULL),
00063     m_SubjectList(NULL)
00064 {
00065         Init();
00066 }
00067 
00068 void KX_NetworkMessageSensor::Init()
00069 {
00070     m_IsUp = false;
00071 }
00072 
00073 KX_NetworkMessageSensor::~KX_NetworkMessageSensor()
00074 {
00075 }
00076 
00077 CValue* KX_NetworkMessageSensor::GetReplica() {
00078         // This is the standard sensor implementation of GetReplica
00079         // There may be more network message sensor specific stuff to do here.
00080         CValue* replica = new KX_NetworkMessageSensor(*this);
00081 
00082         if (replica == NULL) return NULL;
00083         replica->ProcessReplica();
00084 
00085         return replica;
00086 }
00087 
00088 // Return true only for flank (UP and DOWN)
00089 bool KX_NetworkMessageSensor::Evaluate()
00090 {
00091         bool result = false;
00092         bool WasUp = m_IsUp;
00093 
00094         m_IsUp = false;
00095 
00096         if (m_BodyList) {
00097                 m_BodyList->Release();
00098                 m_BodyList = NULL;
00099         }
00100 
00101         if (m_SubjectList) {
00102                 m_SubjectList->Release();
00103                 m_SubjectList = NULL;
00104         }
00105 
00106         STR_String& toname=GetParent()->GetName();
00107         STR_String& subject = this->m_subject;
00108 
00109         vector<NG_NetworkMessage*> messages =
00110                 m_NetworkScene->FindMessages(toname,"",subject,true);
00111 
00112         m_frame_message_count = messages.size();
00113 
00114         if (!messages.empty()) {
00115 #ifdef NAN_NET_DEBUG
00116                 printf("KX_NetworkMessageSensor found one or more messages\n");
00117 #endif
00118                 m_IsUp = true;
00119                 m_BodyList = new CListValue();
00120                 m_SubjectList = new CListValue();
00121         }
00122 
00123         vector<NG_NetworkMessage*>::iterator mesit;
00124         for (mesit=messages.begin();mesit!=messages.end();mesit++)
00125         {
00126                 // save the body
00127                 const STR_String& body = (*mesit)->GetMessageText();
00128                 // save the subject
00129                 const STR_String& messub = (*mesit)->GetSubject();
00130 #ifdef NAN_NET_DEBUG
00131                 if (body) {
00132                         cout << "body [" << body << "]\n";
00133                 }
00134 #endif
00135                 m_BodyList->Add(new CStringValue(body,"body"));
00136                 // Store Subject
00137                 m_SubjectList->Add(new CStringValue(messub,"subject"));
00138 
00139                 // free the message
00140                 (*mesit)->Release();
00141         }
00142         messages.clear();
00143 
00144         result = (WasUp != m_IsUp);
00145 
00146         // Return always true if a message was received otherwise we can loose messages
00147         if (m_IsUp)
00148                 return true;
00149         // Is it usefull to return also true when the first frame without a message?? 
00150         // This will cause a fast on/off cycle that seems useless!
00151         return result;
00152 }
00153 
00154 // return true for being up (no flank needed)
00155 bool KX_NetworkMessageSensor::IsPositiveTrigger()
00156 {
00157 //      printf("KX_NetworkMessageSensor IsPositiveTrigger\n");
00158         //attempt to fix [ #3809 ] IPO Actuator does not work with some Sensors
00159         //a better solution is to properly introduce separate Edge and Level triggering concept
00160 
00161         return m_IsUp;
00162 }
00163 
00164 #ifdef WITH_PYTHON
00165 
00166 /* --------------------------------------------------------------------- */
00167 /* Python interface ---------------------------------------------------- */
00168 /* --------------------------------------------------------------------- */
00169 
00170 /* Integration hooks --------------------------------------------------- */
00171 PyTypeObject KX_NetworkMessageSensor::Type = {
00172         PyVarObject_HEAD_INIT(NULL, 0)
00173         "KX_NetworkMessageSensor",
00174         sizeof(PyObjectPlus_Proxy),
00175         0,
00176         py_base_dealloc,
00177         0,
00178         0,
00179         0,
00180         0,
00181         py_base_repr,
00182         0,0,0,0,0,0,0,0,0,
00183         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
00184         0,0,0,0,0,0,0,
00185         Methods,
00186         0,
00187         0,
00188         &SCA_ISensor::Type,
00189         0,0,0,0,0,0,
00190         py_base_new
00191 };
00192 
00193 PyMethodDef KX_NetworkMessageSensor::Methods[] = {
00194         {NULL,NULL} //Sentinel
00195 };
00196 
00197 PyAttributeDef KX_NetworkMessageSensor::Attributes[] = {
00198         KX_PYATTRIBUTE_STRING_RW("subject", 0, 100, false, KX_NetworkMessageSensor, m_subject),
00199         KX_PYATTRIBUTE_INT_RO("frameMessageCount", KX_NetworkMessageSensor, m_frame_message_count),
00200         KX_PYATTRIBUTE_RO_FUNCTION("bodies", KX_NetworkMessageSensor, pyattr_get_bodies),
00201         KX_PYATTRIBUTE_RO_FUNCTION("subjects", KX_NetworkMessageSensor, pyattr_get_subjects),
00202         { NULL }        //Sentinel
00203 };
00204 
00205 PyObject* KX_NetworkMessageSensor::pyattr_get_bodies(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
00206 {
00207         KX_NetworkMessageSensor *self = static_cast<KX_NetworkMessageSensor*>(self_v);
00208         if (self->m_BodyList) {
00209                 return self->m_BodyList->GetProxy();
00210         } else {
00211                 return (new CListValue())->NewProxy(true);
00212         }
00213 }
00214 
00215 PyObject* KX_NetworkMessageSensor::pyattr_get_subjects(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
00216 {
00217         KX_NetworkMessageSensor *self = static_cast<KX_NetworkMessageSensor*>(self_v);
00218         if (self->m_SubjectList) {
00219                 return self->m_SubjectList->GetProxy();
00220         } else {
00221                 return (new CListValue())->NewProxy(true);
00222         }
00223 }
00224 
00225 #endif // WITH_PYTHON