00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef ArmageTron_NETOBJECT_H
00029 #define ArmageTron_NETOBJECT_H
00030
00031 #include "nNetwork.h"
00032 #include "tArray.h"
00033 #include "tConsole.h"
00034 #include <string.h>
00035
00036 class nObserver;
00037
00038
00039
00040 bool sn_Update(unsigned short &old,unsigned short n);
00041 bool sn_Update(unsigned long &old,unsigned long n);
00042
00043
00044
00045
00046
00047 typedef unsigned short nNetObjectID;
00048
00049 struct nNetObjectRegistrar;
00050
00051 class nNetObject{
00052 friend class nWaitForAckSync;
00053
00054 bool createdLocally;
00055 unsigned long int lastSyncID_;
00056
00057 private:
00058 unsigned short id;
00059
00060
00061 mutable int refCtr_;
00062
00063
00064 unsigned short owner;
00065
00066
00067
00068
00069
00070
00071 mutable tCONTROLLED_PTR( nObserver ) observer_;
00072
00073 int syncListID_;
00074 public:
00075 class nKnowsAboutInfo{
00076 public:
00077 bool knowsAboutExistence:
00078 1;
00079 bool nextSyncAck:
00080 1;
00081
00082 bool syncReq:
00083 1;
00084 unsigned int acksPending:
00085 4;
00086
00087 nKnowsAboutInfo(){
00088 memset(this, 0, sizeof(nKnowsAboutInfo) );
00089 Reset();
00090 syncReq=false;
00091 }
00092
00093 void Reset(){
00094 knowsAboutExistence=false;
00095 nextSyncAck=true;
00096 syncReq=true;
00097 acksPending=0;
00098 }
00099
00100 };
00101 protected:
00102
00103 nKnowsAboutInfo knowsAbout[MAXCLIENTS+2];
00104
00105 nNetObject *Object(int i);
00106
00107
00108
00109
00110
00111 void DoBroadcastExistence();
00112 public:
00113 static bool DoDebugPrint();
00114
00115 static nNetObject *ObjectDangerous(int i );
00116
00117
00118 virtual void AddRef();
00119
00120
00121 virtual void Release();
00122
00123 int GetRefcount() const;
00124
00125 virtual void ReleaseOwnership();
00126 virtual void TakeOwnership();
00127 bool Owned(){
00128 return createdLocally;
00129 }
00130
00131 nObserver& GetObserver() const;
00132
00133 virtual void Dump( tConsole& con );
00134
00135 unsigned short ID() const{
00136 if (this)
00137 return id;
00138 else
00139 return 0;
00140 }
00141
00142 unsigned short Owner() const{
00143 if (this)
00144 return owner;
00145 else
00146 return ::sn_myNetID;
00147 }
00148
00149 inline nMachine & GetMachine() const;
00150
00151 virtual nDescriptor& CreatorDescriptor() const=0;
00152
00153 nNetObject(int owner=-1);
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 nNetObject(nMessage &m);
00164
00165
00166 virtual void InitAfterCreation();
00167
00168
00169
00170
00171 void Register( const nNetObjectRegistrar& r );
00172 protected:
00173 virtual ~nNetObject();
00174
00175
00176
00177
00178
00179 virtual nMachine & DoGetMachine() const;
00180 public:
00181
00182
00183
00184 virtual bool ActionOnQuit(){
00185 return true;
00186 }
00187
00188
00189 virtual void ActionOnDelete(){
00190 }
00191
00192
00193
00194 virtual bool BroadcastExistence(){
00195 return true;
00196 }
00197
00198
00199 virtual void PrintName(tString &s) const;
00200
00201
00202 bool HasBeenTransmitted(int user) const;
00203 bool syncRequested(int user) const{
00204 return knowsAbout[user].syncReq;
00205 }
00206
00207
00208
00209 virtual bool ClearToTransmit(int user) const;
00210
00211
00212 virtual void WriteSync(nMessage &m);
00213 virtual void ReadSync(nMessage &m);
00214
00215
00216 virtual void WriteSync(nMessage &m, int run );
00217 virtual void ReadSync(nMessage &m, int run );
00218
00219 virtual bool SyncIsNew(nMessage &m);
00220
00221
00222 virtual void WriteCreate(nMessage &m);
00223
00224
00225
00226
00227 virtual void WriteCreate(nMessage &m, int run );
00228 virtual void ReadCreate(nMessage &m, int run );
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 void WriteAll( nMessage & m, bool create );
00249 void ReadAll ( nMessage & m, bool create );
00250
00251
00252
00253 protected:
00255 static int SyncedUser();
00256
00257 nMessage *NewControlMessage();
00258
00259
00260 public:
00261
00262 virtual void ReceiveControlNet(nMessage &m);
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 virtual bool AcceptClientSync() const;
00276
00277
00278 void GetID();
00279 void RequestSync(bool ack=true);
00280 void RequestSync(int user,bool ack);
00281
00282
00283
00284 static void SyncAll();
00285
00286
00287
00288 static void ClearAll();
00289
00290
00291
00292 static void ClearAllDeleted();
00293
00294
00295 static void ClearKnows(int user, bool clear);
00296
00297
00298 static void RelabelOnConnect();
00299 };
00300
00301 struct nNetObjectRegistrar
00302 {
00303 nNetObject * object;
00304 unsigned short sender;
00305 unsigned short id;
00306 nNetObjectRegistrar* oldRegistrar;
00307
00308 nNetObjectRegistrar();
00309 ~nNetObjectRegistrar();
00310 };
00311
00312
00313 extern tArray<tJUST_CONTROLLED_PTR<nNetObject> > sn_netObjects;
00314
00315
00316 void ClearKnows(int user, bool clear = false);
00317
00318 void Cheater(int user);
00319
00320
00321
00322
00323 extern tArray<unsigned short> sn_netObjectsOwner;
00324
00325
00326
00327
00328
00329
00330
00331 template<class T> class nNOInitialisator:public nDescriptor{
00332
00333 static void Init(nMessage &m){
00334 #ifndef NOEXCEPT
00335 try
00336 {
00337 #endif
00338 if (m.DataLen()<2)
00339 {
00340 nReadError();
00341 }
00342
00343 unsigned short id=m.Data(0);
00344
00345
00346 if (sn_netObjectsOwner[id]!=m.SenderID() || bool(sn_netObjects[id]))
00347 {
00348 #ifdef DEBUG
00349 st_Breakpoint();
00350 if (!sn_netObjects[id])
00351 {
00352 con << "Netobject " << id << " is already reserved!\n";
00353 }
00354 else
00355 {
00356 con << "Netobject " << id << " is already defined!\n";
00357 }
00358 #endif
00359 if (sn_netObjectsOwner[id]!=m.SenderID())
00360 {
00361 Cheater(m.SenderID());
00362 nReadError();
00363 }
00364 }
00365 else
00366 {
00367 nNetObjectRegistrar registrar;
00368
00369 tJUST_CONTROLLED_PTR< T > n=new T(m);
00370 n->InitAfterCreation();
00371 nNetObject * no = n;
00372 no->ReadAll(m,true);
00373 n->Register( registrar );
00374
00375 #ifdef DEBUG
00376
00377
00378
00379
00380
00381 #endif
00382
00383 if (sn_GetNetState()==nSERVER && !n->AcceptClientSync())
00384 {
00385 Cheater(m.SenderID());
00386 n->Release();
00387 }
00388 else if ( static_cast< nNetObject* >( sn_netObjects[ n->ID() ] ) != n )
00389 {
00390
00391 n->Release();
00392 }
00393 }
00394 #ifndef NOEXCEPT
00395 }
00396 catch (nKillHim)
00397 {
00398 con << "nKillHim signal caught.\n";
00399 Cheater(m.SenderID());
00400 }
00401 #endif
00402 }
00403
00404 public:
00405
00406
00407
00408 nNOInitialisator(unsigned short id,const char *name):nDescriptor(id,Init,name){};
00409 };
00410
00411
00412 template<class T> nMessage& operator >> ( nMessage& m, T*& p )
00413 {
00414 unsigned short id;
00415 m.Read(id);
00416
00417 if ( 0 != id )
00418 p = dynamic_cast<T*> ( nNetObject::ObjectDangerous(id) );
00419 else
00420 p = NULL;
00421
00422 return m;
00423 }
00424
00425 template<class T> nMessage& operator >> ( nMessage& m, tControlledPTR<T>& p )
00426 {
00427 unsigned short id;
00428 m.Read(id);
00429
00430 if ( 0 != id )
00431 p = dynamic_cast<T*> ( nNetObject::ObjectDangerous(id) );
00432 else
00433 p = NULL;
00434
00435 return m;
00436 }
00437
00438
00439
00440
00441
00442
00446
00447
00448 nMachine & nNetObject::GetMachine( void ) const
00449 {
00450 return DoGetMachine();
00451 }
00452
00453 #endif
00454