00001 #include "Node.h"
00002
00003 #ifdef _WIN32
00004 #include <windows.h>
00005 #else
00006 #include <pthread.h>
00007 #endif
00008
00009 #undef PostMessage
00010
00013 Node::Node()
00014 {
00015 This = NULL;
00016 }
00017
00018 Node::Node( NodeObject * nToInit )
00019 {
00020 This = NULL;
00021 Hook( nToInit );
00022 }
00023
00024 Node::Node( const Node & nToCopy )
00025 {
00026 This = NULL;
00027 Hook( nToCopy.This );
00028 }
00029
00030 Node::~Node()
00031 {
00032 Unhook( This );
00033 }
00034
00035 Node & Node::operator = ( const Node & rhs )
00036 {
00037 NodeObject * Tmp = This;
00038 Hook( rhs.This );
00039 Unhook( Tmp );
00040 return *this;
00041 }
00042
00043 Node & Node::operator = ( NodeObject * rhs )
00044 {
00045 NodeObject * Tmp = This;
00046 Hook( rhs );
00047 Unhook( Tmp );
00048 return *this;
00049 }
00050
00051 void Node::Hook( NodeObject * n )
00052 {
00053 if( n )
00054 n->Lock();
00055 This = n;
00056 if( This ) This->IncCount();
00057 if( This ) This->Unlock();
00058 }
00059
00060 void Node::Unhook( NodeObject * n )
00061 {
00062 if( !n )
00063 return;
00064 n->Lock();
00065 n->DecCount();
00066 if( n->GetCount() <= 0 )
00067 {
00068 n->Unlock();
00069 delete n;
00070 }
00071 else
00072 n->Unlock();
00073 return;
00074 }
00075
00078 NodeObject::NodeObject( const string & sName )
00079 {
00080 #ifndef NOSYNCHRONIZATION
00081 #if defined( _WIN32 )
00082 SECURITY_ATTRIBUTES p;
00083 p.nLength = sizeof( SECURITY_ATTRIBUTES );
00084 p.bInheritHandle = true;
00085 p.lpSecurityDescriptor = NULL;
00086 m_vMutex = CreateMutex( &p, true, sName.c_str() );
00087 #else
00088 m_vMutex = malloc( sizeof( pthread_mutex_t ) );
00089 pthread_mutexattr_t attr;
00090 pthread_mutexattr_init( &attr );
00091 pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE );
00092 pthread_mutex_init( (pthread_mutex_t*)m_vMutex, &attr );
00093 #endif
00094 #endif
00095 m_sName = sName;
00096 m_iCount = 0;
00097 m_bDestroyOnUpdate = false;
00098 NODEMAN->Add( this );
00099 }
00100
00101 NodeObject::~NodeObject()
00102 {
00103 NODEMAN->Drop( this );
00104 #ifndef NOSYNCHRONIZATION
00105 #if defined( _WIN32 )
00106 CloseHandle( m_vMutex );
00107 #else
00108 pthread_mutex_destroy( (pthread_mutex_t*)m_vMutex );
00109 free( m_vMutex );
00110 #endif
00111 #endif
00112 }
00113
00114 void NodeObject::SetName( const string & sName )
00115 {
00116 NODEMAN->Drop( this );
00117 m_sName = sName;
00118 NODEMAN->Add( this );
00119 }
00120
00121 Node NodeObject::AttachChild( Node n )
00122 {
00123 m_vnChildren.push_back( n );
00124 n->AttachParent( Node( this ) );
00125 return Node( this );
00126 }
00127
00128 void NodeObject::DetachChild( Node n )
00129 {
00130 for( unsigned i = 0; i < m_vnChildren.size(); ++i )
00131 if( m_vnChildren[i] == n )
00132 {
00133 m_vnChildren[i]->DetachParent( this );
00134 m_vnChildren.erase( m_vnChildren.begin() + i );
00135 --i;
00136 }
00137 }
00138
00139 void NodeObject::AttachParent( NodeObject * n )
00140 {
00141 m_vnParents.push_back( n );
00142 }
00143
00144 void NodeObject::Init()
00145 {
00146 }
00147
00148 void NodeObject::Disestablish()
00149 {
00150
00151 }
00152
00153 void NodeObject::Render()
00154 {
00155 for( unsigned i = 0; i < m_vnChildren.size(); ++i )
00156 m_vnChildren[i]->Render();
00157 }
00158
00159 void NodeObject::Update( const float fDtime )
00160 {
00161 for( unsigned i = 0; i < m_vnChildren.size(); ++i )
00162 m_vnChildren[i]->Update( fDtime );
00163 }
00164
00165 void NodeObject::Message( int iMessageID, const string & sMessageName, const string & sMessagePayload )
00166 {
00167 printf( "Message Received: %d %s %s ME:\"%s\"\n", iMessageID, sMessageName.c_str(), sMessagePayload.c_str(), GetName().c_str() );
00168 }
00169
00170 void NodeObject::DetachParent( NodeObject * n )
00171 {
00172 for( unsigned i = 0; i < m_vnParents.size(); ++i )
00173 if( m_vnParents[i] == n )
00174 {
00175 m_vnParents.erase( m_vnParents.begin() + i );
00176 --i;
00177 }
00178 }
00179
00180
00181 #ifndef NOSYNCHRONIZATION
00182 void NodeObject::Lock()
00183 {
00184 #if defined( _WIN32 )
00185 int r = WaitForSingleObject( m_vMutex, 100000 );
00186 #else
00187 pthread_mutex_lock( (pthread_mutex_t*)m_vMutex );
00188 #endif
00189 }
00190
00191 void NodeObject::Unlock()
00192 {
00193 #if defined( _WIN32 )
00194 ReleaseMutex( m_vMutex );
00195 #else
00196 pthread_mutex_unlock( (pthread_mutex_t*)m_vMutex );
00197 #endif
00198 }
00199
00200 #else
00201 void NodeObject::Lock() { }
00202 void NodeObject::Unlock() { }
00203 #endif
00204
00205 REGISTER_CLASS( NodeObject );
00206
00209 NodeManager * NODEMAN = NULL;
00210
00211 NodeManager * NodeManager::Instance()
00212 {
00213 if( !NODEMAN )
00214 {
00215 NODEMAN = new NodeManager;
00216 NODEMAN->m_fCurrentTime = 0.0f;
00217 }
00218 return NODEMAN;
00219 }
00220
00221 void NodeManager::RegisterType( const string & sClass, ProducerFunct t )
00222 {
00223 m_mToMake[sClass] = t;
00224 }
00225
00226 Node NodeManager::Spawn( const string & sClass, const string & sName )
00227 {
00228 NodeObject * n = GetInstanceExp( sName );
00229 if( n )
00230 return Node( n );
00231 else
00232 return SpawnExplicit( sClass, sName );
00233 }
00234
00235 Node NodeManager::SpawnExplicit( const string & sClass, const string & sName )
00236 {
00237 map< string, ProducerFunct >::iterator i( m_mToMake.find( sClass ) );
00238 if( i != m_mToMake.end() )
00239 return (i->second)( sName );
00240 else
00241 return Node( NULL );
00242 }
00243
00244 void NodeManager::Add( NodeObject * nObject )
00245 {
00246 if( nObject )
00247 m_mInstances[nObject->GetName()] = nObject;
00248 }
00249
00250 void NodeManager::Drop( NodeObject * nObject )
00251 {
00252 if( nObject )
00253 {
00254 map< string, NodeObject * >::iterator i = m_mInstances.find( nObject->GetName() );
00255 if( i != m_mInstances.end() )
00256 m_mInstances.erase( i );
00257 }
00258 }
00259
00260 void NodeManager::RegisterForMessage( const string & sMessage, int iMessageID, Node nToRegister )
00261 {
00262 m_mMessageMatches[sMessage][nToRegister] = iMessageID;
00263 }
00264
00265 void NodeManager::UnregisterForMessage( const string & sMessage, int iMessageID, Node nToRegister )
00266 {
00267 map< Node, int > & j = m_mMessageMatches[sMessage];
00268 map< Node, int >::iterator i = j.find( nToRegister );
00269 if( i == j.end() )
00270 return;
00271 else
00272 j.erase( i );
00273 }
00274
00275 void NodeManager::BroadcastMessage( const string & sMessage, const string & sPayload, Node nTarget )
00276 {
00277 if( nTarget )
00278 nTarget->Message( -1, sMessage, sPayload );
00279 else
00280 {
00281 map< string, map< Node, int > >::iterator i = m_mMessageMatches.find( sMessage );
00282 if( i == m_mMessageMatches.end() )
00283 return;
00284
00285 map< Node, int >::iterator j = (i->second).begin();
00286 for( ; j != (i->second).end() ; ++j )
00287 ((NodeObject*)(j->first).Get())->Message( j->second, sMessage, sPayload );
00288 }
00289 }
00290
00291 void NodeManager::PostMessage( const string & sMessage, const string & sPayload, Node nTarget, const float fTimeInFuture )
00292 {
00293 if( fTimeInFuture < 0.00001 )
00294 {
00295 m_dImmediateMessages.push_back( StringPair(sMessage, sPayload, nTarget) );
00296 } else
00297 {
00298 int i;
00299 for( i = m_vFutureMessages.size() - 1; i >= 0; --i )
00300 if( m_vFutureMessages[i].fFuture - m_fCurrentTime > fTimeInFuture )
00301 {
00302 m_vFutureMessages.insert( m_vFutureMessages.begin() + i + 1, StringPairFloat( sMessage, sPayload, nTarget, fTimeInFuture + m_fCurrentTime ) );
00303 break;
00304 }
00305
00306 if( i < 0 )
00307 m_vFutureMessages.insert( m_vFutureMessages.begin(), StringPairFloat( sMessage, sPayload, nTarget, fTimeInFuture + m_fCurrentTime ) );
00308 }
00309 }
00310
00311 void NodeManager::Update( const float fDtime )
00312 {
00313 m_fCurrentTime += fDtime;
00314 for( unsigned i = 0; i < m_dImmediateMessages.size(); i++ )
00315 {
00316 StringPair * f = &m_dImmediateMessages[i];
00317 BroadcastMessage( f->sP1, f->sP2, f->nTarget );
00318 }
00319 m_dImmediateMessages.clear();
00320
00321 for( int i = m_vFutureMessages.size() - 1; i >= 0; --i )
00322 {
00323 if( m_vFutureMessages[i].fFuture > m_fCurrentTime )
00324 break;
00325 StringPairFloat * f = &m_vFutureMessages[i];
00326 BroadcastMessage( f->sP1, f->sP2, f->nTarget );
00327 m_vFutureMessages.resize( m_vFutureMessages.size() - 1 );
00328 }
00329 }
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351