diff options
| author | Felix Morgner <felix.morgner@gmail.com> | 2026-08-24 11:16:07 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@gmail.com> | 2026-08-24 11:16:07 +0200 |
| commit | c068f22329d5cc722622a2183bbb22eef2093df7 (patch) | |
| tree | 12d56c1aede67988a55e241364606bfbb4dba933 /src/libparsec/include/e_relist.h | |
| download | openparsec-c068f22329d5cc722622a2183bbb22eef2093df7.tar.xz openparsec-c068f22329d5cc722622a2183bbb22eef2093df7.zip | |
Diffstat (limited to 'src/libparsec/include/e_relist.h')
| -rw-r--r-- | src/libparsec/include/e_relist.h | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/src/libparsec/include/e_relist.h b/src/libparsec/include/e_relist.h new file mode 100644 index 0000000..6f39e54 --- /dev/null +++ b/src/libparsec/include/e_relist.h @@ -0,0 +1,328 @@ +/* +* PARSEC HEADER: e_relist.h +*/ + +#ifndef _E_RELIST_H_ +#define _E_RELIST_H_ + +// forward decls -------------------------------------------------------------- +// +class E_SimShipState; +class E_SimPlayerInfo; + + +//FIXME: this should be merged with DEBUG.C + +// easy access to the singleton ----------------------------------------------- +// +#define TheMemoryManager UTL_MemoryManager::GetMemoryManager() + +// set these wisely +#define MEMMAN_HASH_TABLE_SIZE 1001 +#define HASH_POINTER_ADDRESS(x) ( ((size_t)(x)) % MEMMAN_HASH_TABLE_SIZE ) + +// struct defining a entry in the memory manager ------------------------------ +// +class UTL_MemEntry +{ +protected: + UTL_MemEntry* m_pNext; + void* m_p; + const char* m_descr1; + const char* m_descr2; +public: + UTL_MemEntry( void* p = NULL, const char* descr1 = NULL, const char* descr2 = NULL ) : + m_pNext( NULL ), + m_p( p ), + m_descr1( descr1 ), + m_descr2( descr2 ) + { + } + + friend class UTL_MemoryManager; +}; + +// memory manager ------------------------------------------------------------- +// +class UTL_MemoryManager +{ +protected: + + UTL_MemEntry* m_HashTable[ MEMMAN_HASH_TABLE_SIZE ]; + + UTL_MemoryManager() + { + for( int nEntry = 0; nEntry < MEMMAN_HASH_TABLE_SIZE; nEntry++ ) { + m_HashTable[ nEntry ] = NULL; + } + } + ~UTL_MemoryManager() + { + CheckLeaks(); + } +public: + // SINGLETON pattern + static UTL_MemoryManager* GetMemoryManager() + { + static UTL_MemoryManager _TheMemoryManager; + return &_TheMemoryManager; + } + + // add a pointer for tracking + int AddTracking( void* p, const char* descr1, const char* descr2 ) + { + //MSGOUT( "UTL_MemoryManager::AddTracking(): %x, %s, %s", p, descr1, descr2 ); + + // get hash key + size_t htid = HASH_POINTER_ADDRESS( p ); + + // search hash table for already existing entry + for ( UTL_MemEntry* scan = m_HashTable[ htid ]; scan != NULL; scan = scan->m_pNext ) { + if ( scan->m_p == p ) { + // issue warning + MSGOUT( "UTL_MemManager::AddTracking(): duplicate call for pointer %x (%s, %s).", p, descr1, descr2 ); + return FALSE; + } + } + + // create new entry & prepend to list + UTL_MemEntry* newentry = new UTL_MemEntry( p, descr1, descr2 ); + newentry->m_pNext = m_HashTable[ htid ]; + m_HashTable[ htid ] = newentry; + + return TRUE; + } + + // remove a pointer from tracking + int RemoveTracking( void* p ) + { + // get hash key + size_t htid = HASH_POINTER_ADDRESS( p ); + + UTL_MemEntry* scan = m_HashTable[ htid ]; + if ( scan != NULL ) { + // check for head removal + if ( scan->m_p == p ) { + m_HashTable[ htid ] = scan->m_pNext; + //MSGOUT( "UTL_MemoryManager::RemoveTracking(): %x, %s, %s", scan->m_p, scan->m_descr1, scan->m_descr2 ); + delete scan; + return TRUE; + } + + // setup iteration + UTL_MemEntry* prev = scan; + scan = scan->m_pNext; + + for ( ; scan != NULL; scan = scan->m_pNext ) { + + if ( scan->m_p == p ) { + + // unlink from list + prev->m_pNext = scan->m_pNext; + //MSGOUT( "UTL_MemoryManager::RemoveTracking(): %x, %s, %s", scan->m_p, scan->m_descr1, scan->m_descr2 ); + delete scan; + return TRUE; + } + } + } + + // issue warning + MSGOUT( "UTL_MemManager::RemoveTracking(): tracking entry for pointer %x not found.", p ); + return FALSE; + } + + // dump all pointers we still track + void CheckLeaks() + { + for( int nEntry = 0; nEntry < MEMMAN_HASH_TABLE_SIZE; nEntry++ ) { + + for( UTL_MemEntry* scan = m_HashTable[ nEntry ]; scan != NULL; scan = scan->m_pNext ) { + MSGOUT( "UTL_MemManager::CheckLeaks(): leaked pointer %x (%s, %s)", scan->m_p, scan->m_descr1, scan->m_descr2 ); + } + } + } +}; + +// class holding a remote event list ------------------------------------------ +// +class E_REList +{ +protected: + char* m_data; + char* m_CurPos; + size_t m_Avail; + size_t m_nMaxSize; + + // reference counting stuff + int m_nRefCount; + ~E_REList(); + E_REList(); + E_REList( size_t size ); +public: + + // reference counting stuff + static E_REList* CreateAndAddRef( size_t size ) + { + E_REList* relist = new E_REList; + relist->AddRef(); +#ifdef PARSEC_DEBUG + TheMemoryManager->AddTracking( (void*)relist, __FILE__, "E_REList::CreateAndAddRef()" ); +#endif // PARSEC_DEBUG + relist->Init( size ); + return relist; + } + + void AddRef() { m_nRefCount++; } + void Release() + { + m_nRefCount--; + if ( m_nRefCount == 0 ) { +#ifdef PARSEC_DEBUG + TheMemoryManager->RemoveTracking( (void*)this ); +#endif // PARSEC_DEBUG + delete this; + } + } + + // init the remote event list + void Init( size_t size ); + + // return the internal data of the remote event list + RE_Header* GetData() { return (RE_Header*)m_data; } + + // return the size of the RE list + size_t GetSize() { return (size_t)( m_CurPos - m_data ); } + + // clear remote event list + int Clear(); + + // append a remote event list + int AppendList( RE_Header* relist ); + + // append a E_REList + int AppendList( E_REList* relist ); + + // append a remote event + size_t AppendEvent( RE_Header* re, size_t size ); + + // check whether we have any remote events in the list + int HasEvents() + { + return ( ( (RE_Header*) m_data)->RE_Type != RE_EMPTY ); + } + + // write to an external remote event list + size_t WriteTo( RE_Header* dst, size_t maxsize, int allow_truncate ); + + // check if enough space in RE_List for specified remote event + int RmEvAllowed( int re_type ); + + // dump contents of RE list + void Dump(); + + // allocate space for a specific RE + RE_Header* NET_Allocate( int retype ); + + // insert state sync remote event + int RmEvStateSync( byte statekey, byte stateval ); + + // append a RE_OwnerSection event + int NET_Append_RE_OwnerSection( int ownerid ); + + // insert command info into remote event list + int NET_Append_RE_CommandInfo( const char* commandstring ); + + // append a RE_PlayerAndShipStatus event + //FIXME: GAMECODE + //FIXME: consolidate naming with RmEv<remote-event-name> + int NET_Append_RE_PlayerAndShipStatus( int nClientID, E_SimPlayerInfo* pSimPlayerInfo, E_SimShipState* pSimShipState, refframe_t CurRefFrame, bool_t bUpdatePropsOnly ); + + // append a RE_GameState + //FIXME: GAMECODE + int NET_Append_RE_GameState(); + + // append a RE_KillStats event + //FIXME: GAMECODE + int NET_Append_RE_KillStats(); + + // append a RE_CreateLaser event + //FIXME: GAMECODE + int NET_Append_RE_CreateLaser( const LaserObject* laserpo ); + + // append a RE_CreateMissile event + //FIXME: GAMECODE + int NET_Append_RE_CreateMissile( const MissileObject *missilepo, dword targetobjid ); + + // Append a RE_CreateExtra event + int NET_Append_RE_CreateExtra( const ExtraObject *extrapo ); + + // append a RE_KillOjbect event + //FIXME: GAMECODE + int NET_Append_RE_KillObject( dword objectid, byte listno ); + + // append a RE_CreateExtra2 event + //FIXME: GAMECODE + int NET_Append_RE_CreateExtra2( const ExtraObject *extrapo ); + + // append a RE_IPv4ServerInfo event + int NET_Append_RE_IPv4ServerInfo( node_t* node, word nServerID, int xpos, int ypos, word flags ); + + // append a RE_ServerLinkInfo event + int NET_Append_RE_ServerLinkInfo( word nServerID_1, word nServerID_2, word flags ); + + // append a RE_MapObject + int NET_Append_RE_MapObject( int map_objectid, char* name, int xpos, int ypos, int w, int h, char* texname ); + + //Append a Particle RE (energy fields, megashield...etc) + int NET_Append_RE_ParticleObject( int type, const Vertex3& origin ); + + // determine the size of a remote-event list + static size_t DetermineListSize( RE_Header* relist ) + { + ASSERT( relist != NULL ); + + size_t lsize = 0; + + // process remote event list + while ( relist->RE_Type != RE_EMPTY ) { + + // sum up size of all remote events + size_t resize = RmEvGetSize( relist ); + lsize += resize; + + // advance to next event + ASSERT( ( relist->RE_BlockSize == RE_BLOCKSIZE_INVALID ) || + ( relist->RE_BlockSize == resize ) ); + relist = (RE_Header *) ( (char *) relist + resize ); + } + + // include size of RE list termination + lsize += sizeof( dword ); + + return lsize; + } + + // determine size of remote event + static size_t RmEvGetSize( RE_Header *relist ); + + // determine size of remote event from type + static size_t RmEvGetSizeFromType( byte retype ); + + // check whether the remote event list is well formed + static int IsWellFormed( RE_Header *relist ); + + // return the max. size of the RE list that can fit in one external packet + static size_t GetMaxSizeInPacket(); + + // validate the RE according to all bounds + static int ValidateRE( RE_Header* relist, size_t size ); + +protected: +}; + + +#define NET_RmEvList_GetSize E_REList::DetermineListSize +#define NET_RmEvList_IsWellFormed E_REList::IsWellFormed + + +#endif // _E_RELIST_H_ |
