00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef _NODE_H
00011 #define _NODE_H
00012
00013 #include <stdio.h>
00014 #include <string>
00015 #include <vector>
00016 #include <map>
00017
00018 using namespace std;
00019
00020 class NodeObject;
00021
00023
00027 class Node
00028 {
00029 public:
00030 Node();
00031 Node( NodeObject * nToInit );
00032 Node( const Node & nToCopy );
00033 ~Node();
00034
00035 Node & operator = ( const Node & rhs );
00036 Node & operator = ( NodeObject * rhs );
00037
00039 inline bool IsNull() { return This!=0; }
00040 inline operator NodeObject * () { return This; }
00041 inline NodeObject & operator * () { return *This; }
00042 inline NodeObject * Get() { return This; }
00043 inline const NodeObject * Get() const { return This; }
00044 inline NodeObject * operator -> () { return This; }
00045 inline const NodeObject * operator -> () const { return This; }
00046
00048 inline bool operator == ( const Node & rhs ) const { return This==rhs.This; }
00049
00051
00053 inline bool operator < ( const Node & rhs ) const { return ((long long)This)<((long long)rhs.This); }
00054 private:
00056 void Hook( NodeObject * n );
00057
00059 void Unhook( NodeObject * n );
00060
00062 NodeObject * This;
00063 };
00064
00065
00067
00070 class NodeObject
00071 {
00072 public:
00073 NodeObject( const string & sName );
00074 virtual ~NodeObject();
00075
00077 virtual string GetType() { return "NodeBase"; }
00078
00080 virtual bool IsTypeOf( const string & sType ) { return sType.compare( "NodeBase" )==0; }
00081
00083 void SetName( const string & sName );
00084
00086 string GetName() { return m_sName; }
00087
00089 Node AttachChild( Node n );
00090
00092 void DetachChild( Node n );
00093
00095 inline int GetCount() { return m_iCount; }
00096
00098 void DestroySelfOnUpdate() { m_bDestroyOnUpdate = true; }
00099
00101 virtual void Init();
00102
00104 virtual void Render();
00105
00107 virtual void Update( const float fDtime );
00108
00110 virtual void Message( int iMessageID, const string & sMessageName, const string & sMessagePayload );
00111
00113 virtual void Disestablish();
00114
00116 virtual void Reload() { Disestablish(); Init(); }
00117
00119 void Lock();
00120
00122 void Unlock();
00123 private:
00124 #ifndef NOSYNCHRONIZATION
00126 void * m_vMutex;
00127 #endif
00128
00130 inline void DecCount() { m_iCount--; }
00131
00133 inline void IncCount() { m_iCount++; }
00134
00135 friend class Node;
00136
00138 void AttachParent( NodeObject * n );
00139
00141 void DetachParent( NodeObject * n );
00142
00144 string m_sName;
00145
00147 vector< NodeObject * > m_vnParents;
00148
00150 vector< Node > m_vnChildren;
00151
00153 int m_iCount;
00154
00156 bool m_bDestroyOnUpdate;
00157 };
00158
00160 #define CLASS_RTTI( NAME, PARENT ) \
00161 virtual string GetType() { return #NAME; } \
00162 virtual bool IsTypeOf( const string & sType ) { return (sType.compare( #NAME ) == 0)?true:PARENT::IsTypeOf( sType ); }
00163
00165 #define REGISTER_CLASS( CLASSNAME ) \
00166 NodeObject * Produce##CLASSNAME( const string & sObjectName ) \
00167 { return new CLASSNAME( sObjectName ); } \
00168 class RegClass##CLASSNAME { public: \
00169 RegClass##CLASSNAME() { \
00170 NodeManager::Instance()->RegisterType( #CLASSNAME, Produce##CLASSNAME ); \
00171 } \
00172 }; \
00173 RegClass##CLASSNAME AUTOREG##CLASSNAME;
00174
00176 typedef NodeObject * (*ProducerFunct)( const string & sObjectName );
00177
00179 class NodeManager
00180 {
00181 public:
00182 static NodeManager * Instance();
00183
00185 void RegisterType( const string & sClass, ProducerFunct t );
00186
00188 Node Spawn( const string & sClass, const string & sName );
00189
00191 Node SpawnExplicit( const string & sClass, const string & sName );
00192
00194 void Drop( NodeObject * nObject );
00195
00197 void Add( NodeObject * nObject );
00198
00200 inline Node GetInstance( const string & sName ) { return Node( GetInstanceExp( sName ) ); }
00201
00203 inline NodeObject * GetInstanceExp( const string & sName ) {
00204 map< string, NodeObject * >::iterator i( m_mInstances.find( sName ) );
00205 if( i != m_mInstances.end() )
00206 return i->second;
00207 else
00208 return NULL;
00209 }
00210
00212 void RegisterForMessage( const string & sMessage, int iMessageID, Node nToRegister );
00213
00215 void UnregisterForMessage( const string & sMessage, int iMessageID, Node nToRegister );
00216
00218 void BroadcastMessage( const string & sMessage, const string & sPayload, Node nTarget );
00219
00221 void PostMessage( const string & sMessage, const string & sPayload, Node nTarget, const float fTimeInFuture = 0 );
00222
00224 void Update( const float fDtime );
00225
00227 inline NodeObject * DerefGet( const string & sType, const string & sName ) { return Spawn( sType, sName ).Get(); }
00228
00230 map< string, NodeObject* > * GetObjectInstanceMap() { return &m_mInstances; }
00231
00232 private:
00234 bool m_bInit;
00235
00237 map< string, ProducerFunct > m_mToMake;
00238
00240 map< string, NodeObject * > m_mInstances;
00241
00243 map< string, map< Node, int > > m_mMessageMatches;
00244
00246 struct StringPair
00247 {
00248 StringPair( const string & P1, const string & P2, NodeObject * NT )
00249 : sP1( P1 ), sP2( P2 ), nTarget(NT) { }
00250 string sP1, sP2;
00251 NodeObject * nTarget;
00252 };
00253 vector< StringPair > m_dImmediateMessages;
00254
00256 struct StringPairFloat
00257 {
00258 StringPairFloat( const string & P1, const string & P2, Node NT, float ft )
00259 : sP1( P1 ), sP2( P2 ), nTarget(NT), fFuture( ft ) { }
00260 StringPairFloat() : fFuture( 0 ) { }
00261 string sP1, sP2;
00262 Node nTarget;
00263 double fFuture;
00264 };
00265
00267 vector< StringPairFloat > m_vFutureMessages;
00268
00270 double m_fCurrentTime;
00271 };
00272
00274 extern NodeManager * NODEMAN;
00275
00277 #define NODE_CAST( Node, Type ) \
00278 (Node.Get()?((Type*) (Node->IsTypeOf(#Type)?Node.Get():NULL)):NULL)
00279
00281 #define GET_NODE_CAST( NodeName, Type ) \
00282 ((Type*)NODEMAN->DerefGet( #Type, NodeName ))
00283
00285 #define CODERENDERNODE( NODENAME, CODEIN, CODEOUT ) \
00286 class NODENAME : public NodeObject \
00287 { \
00288 public: \
00289 NODENAME( const string & sName ) : NodeObject( sName ) { } \
00290 CLASS_RTTI( NODENAME, NodeObject ); \
00291 \
00292 virtual void Render() { CODEIN; NodeObject::Render(); CODEOUT; } \
00293 };
00294
00295 #endif
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317