• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

NetworkIDObject.cpp

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 #include "NetworkIDObject.h"
00009 #include "NetworkIDManager.h"
00010 #include "RakAssert.h"
00011 
00012 #include "RakAlloca.h"
00013 
00014 uint32_t NetworkIDObject::nextAllocationNumber=0;
00015 
00017 // Construction/Destruction
00019 
00020 NetworkIDObject::NetworkIDObject()
00021 {
00022         callGenerationCode=true;
00023         networkID=UNASSIGNED_NETWORK_ID;
00024         parent=0;
00025         networkIDManager=0;
00026         allocationNumber=nextAllocationNumber++;
00027 }
00028 
00029 //-------------------------------------------------------------------------------------
00030 
00031 
00032 NetworkIDObject::~NetworkIDObject()
00033 {
00034         if (networkID!=UNASSIGNED_NETWORK_ID)
00035         {
00036 #if defined(NETWORK_ID_USE_PTR_TABLE) || defined (NETWORK_ID_USE_HASH)
00037                 void *obj = networkIDManager->IDArray[networkID.localSystemAddress];
00038                 if (obj==this)
00039                         networkIDManager->IDArray[networkID.localSystemAddress]=0;
00040 #else
00041                 NetworkIDNode * object = networkIDManager->IDTree.GetPointerToNode( NetworkIDNode( ( networkID ), 0 ) );
00042                 if ( object && object->object == this )
00043                         networkIDManager->IDTree.Del( NetworkIDNode( object->networkID, 0 ) );
00044 #endif
00045         }
00046 }
00047 
00049 // Public Methods
00051 
00052 void NetworkIDObject::SetNetworkIDManager( NetworkIDManager *manager)
00053 {
00054         networkIDManager = manager;
00055 }
00056 
00057 //-------------------------------------------------------------------------------------
00058 
00059 NetworkIDManager * NetworkIDObject::GetNetworkIDManager( void )
00060 {
00061         return networkIDManager;
00062 }
00063 
00064 //-------------------------------------------------------------------------------------
00065 
00066 NetworkID NetworkIDObject::GetNetworkID( void )
00067 {
00068         RakAssert(networkIDManager);
00069         if (callGenerationCode && networkIDManager->IsNetworkIDAuthority())
00070         {
00071                 GenerateID();
00072                 RakAssert(networkID!=UNASSIGNED_NETWORK_ID);
00073                 callGenerationCode=false;
00074         }
00075 
00076         return networkID;
00077 };
00078 //-------------------------------------------------------------------------------------
00079 
00080 bool NetworkIDObject::RequiresSetParent(void) const
00081 {
00082         return false;
00083 }
00084 
00085 //-------------------------------------------------------------------------------------
00086 
00087 void NetworkIDObject::SetNetworkID( NetworkID id )
00088 {
00089         callGenerationCode=false;
00090 
00091         if ( id == UNASSIGNED_NETWORK_ID )
00092         {
00093                 // puts("Warning: NetworkIDObject passed UNASSIGNED_NETWORK_ID.  SetID ignored");
00094                 return ;
00095         }
00096 
00097         if ( networkID == id )
00098         {
00099                 // RAKNET_DEBUG_PRINTF("NetworkIDObject passed %i which already exists in the tree.  SetID ignored", id);
00100                 return ;
00101         }
00102 
00103         RakAssert(networkIDManager);
00104 
00105 #if defined(NETWORK_ID_USE_PTR_TABLE) || defined (NETWORK_ID_USE_HASH)
00106         networkID = id;
00107         networkIDManager->IDArray[id.localSystemAddress]=this;
00108 #else
00109 
00110         NetworkIDNode* collision = networkIDManager->IDTree.GetPointerToNode( NetworkIDNode( ( id ), 0 ) );
00111 
00112         if ( collision )   // Tree should have only unique values.  The new value is already in use.
00113         {
00114                 //RAKNET_DEBUG_PRINTF("Warning: NetworkIDObject::SetID passed %i, which has an existing node in the tree.  Old node removed, which will cause the item pointed to to be inaccessible to the network", id);
00115                 networkIDManager->IDTree.Del( NetworkIDNode( collision->networkID, collision->object ) );
00116         }
00117 
00118         if ( networkID == UNASSIGNED_NETWORK_ID )   // Object has not had an ID assigned so does not already exist in the tree
00119         {
00120                 networkID = id;
00121                 networkIDManager->IDTree.Add( NetworkIDNode( networkID, this ) );
00122         }
00123         else // Object already exists in the tree and has an assigned ID
00124         {
00125                 networkIDManager->IDTree.Del( NetworkIDNode( networkID, this ) ); // Delete the node with whatever ID the existing object is using
00126                 networkID = id;
00127                 networkIDManager->IDTree.Add( NetworkIDNode( networkID, this ) );
00128         }
00129 #endif
00130 }
00131 
00132 //-------------------------------------------------------------------------------------
00133 void NetworkIDObject::SetParent( void *_parent )
00134 {
00135         parent=_parent;
00136 
00137 #ifdef _DEBUG
00138         if (networkIDManager)
00139         {
00140                 // Avoid duplicate parents in the tree
00141                 unsigned i;
00142 #if defined(NETWORK_ID_USE_PTR_TABLE) || defined (NETWORK_ID_USE_HASH)
00143                 for (i=0; i < 65534; i++)
00144                 {
00145                         NetworkIDObject *nio =  networkIDManager->IDArray[i];
00146                         RakAssert(nio==0 || nio->GetParent()!=_parent);
00147                 }
00148 #else
00149                 unsigned size = networkIDManager->IDTree.Size();
00150                 NetworkIDNode *nodeArray;
00151 
00152                 bool usedAlloca=false;
00153         #if !defined(_XBOX) && !defined(X360)
00154                 if (sizeof(NetworkIDNode) * size < MAX_ALLOCA_STACK_ALLOCATION)
00155                 {
00156                         nodeArray = (NetworkIDNode*) alloca(sizeof(NetworkIDNode) * size);
00157                         usedAlloca=true;
00158                 }
00159                 else
00160         #endif
00161                         nodeArray = RakNet::OP_NEW_ARRAY<NetworkIDNode>(size, __FILE__, __LINE__ );
00162 
00163                 networkIDManager->IDTree.DisplayBreadthFirstSearch( nodeArray );
00164                 for (i=0; i < size; i++)
00165                 {
00166                         // If this assert hits then this _parent is already in the tree.  Classes instance should never contain more than one NetworkIDObject
00167                         RakAssert(nodeArray->object->GetParent()!=parent);
00168                 }
00169 
00170                 if (usedAlloca==false)
00171                         RakNet::OP_DELETE_ARRAY(nodeArray, __FILE__, __LINE__);
00172 #endif
00173         }
00174 #endif
00175 }
00176 //-------------------------------------------------------------------------------------
00177 void* NetworkIDObject::GetParent( void ) const
00178 {
00179         return parent;
00180 }
00181 //-------------------------------------------------------------------------------------
00182 uint32_t NetworkIDObject::GetAllocationNumber(void) const
00183 {
00184         return allocationNumber;
00185 }
00186 //-------------------------------------------------------------------------------------
00187 void NetworkIDObject::GenerateID(void)
00188 {
00189         RakAssert(networkIDManager->IsNetworkIDAuthority());
00190 
00191 #if defined(NETWORK_ID_USE_PTR_TABLE) || defined (NETWORK_ID_USE_HASH)
00192         int count = 65535;
00193         (void) count;
00194         do 
00195         {
00196                 RakAssert(count-->0);
00197                 networkID.localSystemAddress=networkIDManager->sharedNetworkID++;
00198         } while(networkIDManager->IDArray[networkID.localSystemAddress]!=0);
00199         networkIDManager->IDArray[networkID.localSystemAddress]=this;
00200 #else
00201         // If you want more than 65535 network objects, change the type of networkID
00202         RakAssert(networkIDManager->IDTree.Size() < 65535);
00203 
00204         NetworkIDNode* collision;
00205         do
00206         {
00207                 networkID.localSystemAddress=networkIDManager->sharedNetworkID++;
00208 #ifdef NETWORK_ID_SUPPORTS_PEER_TO_PEER
00209                 if (NetworkID::IsPeerToPeerMode())
00210                 {
00211                         if (networkIDManager->GetGuid()==UNASSIGNED_RAKNET_GUID)
00212                         {
00213                                  // If this assert hits you forgot to call SetGUID and SetExternalSystemAddress
00214                                 RakAssert(networkIDManager->externalSystemAddress!=UNASSIGNED_SYSTEM_ADDRESS);
00215                                 networkID.systemAddress=networkIDManager->externalSystemAddress;
00216                         }
00217                         else
00218                         {
00219                                 networkID.guid=networkIDManager->GetGuid();
00220                                 networkID.systemAddress=networkIDManager->externalSystemAddress;
00221                         }
00222                 }
00223 #endif
00224                 collision = networkIDManager->IDTree.GetPointerToNode( NetworkIDNode( ( networkID ), 0 ) );
00225         }
00226         while ( collision );
00227 
00228         networkIDManager->IDTree.Add( NetworkIDNode( networkID, this ) );
00229 #endif
00230 }
00231 
00233 // EOF

Generated on Thu Sep 30 2010 01:27:25 for RakNet by  doxygen 1.7.1