Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions Generals/Code/GameEngine/Source/GameClient/GameClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,6 @@ void GameClient::init()
/** Reset the game client for a new game */
void GameClient::reset()
{
Drawable *draw, *nextDraw;
m_drawableHash.clear();
#if USING_STLPORT
m_drawableHash.resize(DRAWABLE_HASH_SIZE);
Expand All @@ -445,7 +444,7 @@ void GameClient::reset()
TheInGameUI->reset();

// destroy all Drawables
for( draw = m_drawableList; draw; draw = nextDraw )
for( Drawable *draw = m_drawableList, *nextDraw = nullptr; draw; draw = nextDraw )
{
nextDraw = draw->getNextDrawable();
destroyDrawable( draw );
Expand Down Expand Up @@ -801,7 +800,6 @@ void GameClient::updateFakeDrawables()

/** -----------------------------------------------------------------------------------------------
* Given an object id, return the associated object.
* For efficiency, a small Least Recently Used cache is incorporated.
* This method is the primary interface for accessing objects, and should be used
* instead of pointers to "attach" objects to each other.
*/
Expand Down Expand Up @@ -860,7 +858,7 @@ void GameClient::addDrawableToLookupTable(Drawable *draw )
if( draw == nullptr )
return;

// add to lookup
// add to lookup table
m_drawableHash[ draw->getID() ] = draw;

}
Expand All @@ -875,7 +873,7 @@ void GameClient::removeDrawableFromLookupTable( Drawable *draw )
if( draw == nullptr )
return;

// remove from table
// remove from lookup table
m_drawableHash.erase( draw->getID() );

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3444,7 +3444,7 @@ void GameLogic::addObjectToLookupTable( Object *obj )
if( obj == nullptr )
return;

// add to lookup
// add to lookup table
m_objHash[ obj->getID() ] = obj;

}
Expand Down
33 changes: 3 additions & 30 deletions GeneralsMD/Code/GameEngine/Include/GameClient/GameClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,8 @@ class SnowManager;

/// Function pointers for use by GameClient callback functions.
typedef void (*GameClientFuncPtr)( Drawable *draw, void *userData );
//typedef std::hash_map<DrawableID, Drawable *, rts::hash<DrawableID>, rts::equal_to<DrawableID> > DrawablePtrHash;
//typedef DrawablePtrHash::iterator DrawablePtrHashIt;

typedef std::vector<Drawable*> DrawablePtrVector;
typedef std::hash_map<DrawableID, Drawable *, rts::hash<DrawableID>, rts::equal_to<DrawableID>/**/> DrawablePtrHash;
typedef DrawablePtrHash::iterator DrawablePtrHashIt;

//-----------------------------------------------------------------------------
/** The Client message dispatcher, this is the last "translator" on the message
Expand Down Expand Up @@ -170,8 +168,7 @@ class GameClient : public SubsystemInterface,
UnsignedInt m_frame; ///< Simulation frame number from server

Drawable *m_drawableList; ///< All of the drawables in the world
// DrawablePtrHash m_drawableHash; ///< Used for DrawableID lookups
DrawablePtrVector m_drawableVector;
DrawablePtrHash m_drawableHash; ///< Used for DrawableID lookups

DrawableID m_nextDrawableID; ///< For allocating drawable id's
DrawableID allocDrawableID(); ///< Returns a new unique drawable id
Expand Down Expand Up @@ -237,30 +234,6 @@ class GameClient : public SubsystemInterface,
} \
} while (0);

/** -----------------------------------------------------------------------------------------------
* Given an object id, return the associated object.
* This method is the primary interface for accessing objects, and should be used
* instead of pointers to "attach" objects to each other.
*/
inline Drawable* GameClient::findDrawableByID( const DrawableID id )
{
if( id == INVALID_DRAWABLE_ID )
return nullptr;

// DrawablePtrHashIt it = m_drawableHash.find(id);
// if (it == m_drawableHash.end()) {
// // no such drawable
// return nullptr;
// }
//
// return (*it).second;

if( (size_t)id < m_drawableVector.size() )
return m_drawableVector[(size_t)id];

return nullptr;
}


// the singleton
extern GameClient *TheGameClient;
Expand Down
19 changes: 7 additions & 12 deletions GeneralsMD/Code/GameEngine/Include/GameLogic/GameLogic.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ enum

/// Function pointers for use by GameLogic callback functions.
typedef void (*GameLogicFuncPtr)( Object *obj, void *userData );
//typedef std::hash_map<ObjectID, Object *, rts::hash<ObjectID>, rts::equal_to<ObjectID> > ObjectPtrHash;
//typedef ObjectPtrHash::const_iterator ObjectPtrIter;
typedef std::hash_map<ObjectID, Object *, rts::hash<ObjectID>, rts::equal_to<ObjectID>/**/> ObjectPtrHash;
typedef ObjectPtrHash::const_iterator ObjectPtrIter;

typedef std::vector<Object*> ObjectPtrVector;

Expand Down Expand Up @@ -401,8 +401,7 @@ class GameLogic : public SubsystemInterface, public Snapshot
WindowLayout *m_background;

Object* m_objList; ///< All of the objects in the world.
// ObjectPtrHash m_objHash; ///< Used for ObjectID lookups
ObjectPtrVector m_objVector;
ObjectPtrHash m_objHash; ///< Used for ObjectID lookups

// this is a vector, but is maintained as a priority queue.
// never modify it directly; please use the proper access methods.
Expand Down Expand Up @@ -503,15 +502,11 @@ inline Object* GameLogic::findObjectByID( ObjectID id )
if( id == INVALID_ID )
return nullptr;

// ObjectPtrHash::iterator it = m_objHash.find(id);
// if (it == m_objHash.end())
// return nullptr;
//
// return (*it).second;
if( (size_t)id < m_objVector.size() )
return m_objVector[(size_t)id];
ObjectPtrHash::iterator it = m_objHash.find(id);
if (it == m_objHash.end())
return nullptr;

return nullptr;
return (*it).second;
}


Expand Down
47 changes: 28 additions & 19 deletions GeneralsMD/Code/GameEngine/Source/GameClient/GameClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,18 +453,18 @@ void GameClient::init()
/** Reset the game client for a new game */
void GameClient::reset()
{
Drawable *draw, *nextDraw;
// m_drawableHash.clear();
// m_drawableHash.resize(DRAWABLE_HASH_SIZE);

m_drawableVector.clear();
m_drawableVector.resize(DRAWABLE_HASH_SIZE, nullptr);
m_drawableHash.clear();
#if USING_STLPORT
m_drawableHash.resize(DRAWABLE_HASH_SIZE);
#else
m_drawableHash.reserve(DRAWABLE_HASH_SIZE);
#endif

// need to reset the in game UI to clear drawables before they are destroyed
TheInGameUI->reset();

// destroy all Drawables
for( draw = m_drawableList; draw; draw = nextDraw )
for( Drawable *draw = m_drawableList, *nextDraw = nullptr; draw; draw = nextDraw )
{
nextDraw = draw->getNextDrawable();
destroyDrawable( draw );
Expand Down Expand Up @@ -849,6 +849,22 @@ void GameClient::updateFakeDrawables()
}
}

/** -----------------------------------------------------------------------------------------------
* Given an object id, return the associated object.
* This method is the primary interface for accessing objects, and should be used
* instead of pointers to "attach" objects to each other.
*/
Drawable* GameClient::findDrawableByID( const DrawableID id )
{
DrawablePtrHashIt it = m_drawableHash.find(id);
if (it == m_drawableHash.end()) {
// no such drawable
return nullptr;
}

return (*it).second;
}

/** -----------------------------------------------------------------------------------------------
* Destroy the drawable immediately.
*/
Expand Down Expand Up @@ -893,13 +909,8 @@ void GameClient::addDrawableToLookupTable(Drawable *draw )
if( draw == nullptr )
return;

// add to lookup
// m_drawableHash[ draw->getID() ] = draw;
DrawableID newID = draw->getID();
while( newID >= m_drawableVector.size() ) // Fail case is hella rare, so faster to double up on size() call
m_drawableVector.resize(m_drawableVector.size() * 2, nullptr);

m_drawableVector[ newID ] = draw;
// add to lookup table
m_drawableHash[ draw->getID() ] = draw;

}

Expand All @@ -910,13 +921,11 @@ void GameClient::removeDrawableFromLookupTable( Drawable *draw )
{

// sanity
// TheSuperHackers @fix Mauller/Xezon 24/04/2025 Prevent out of range access to vector lookup table
if( draw == nullptr || static_cast<size_t>(draw->getID()) >= m_drawableVector.size() )
if( draw == nullptr )
return;

// remove from table
// m_drawableHash.erase( draw->getID() );
m_drawableVector[ draw->getID() ] = nullptr;
// remove from lookup table
m_drawableHash.erase( draw->getID() );

}

Expand Down
25 changes: 10 additions & 15 deletions GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,7 @@ void GameLogic::destroyAllObjectsImmediate()
processDestroyList();
DEBUG_ASSERTCRASH( m_objList == nullptr, ("destroyAllObjectsImmediate: Object list not cleared") );

// m_objHash.clear();
m_objVector.clear();
m_objHash.clear();

}

Expand Down Expand Up @@ -422,8 +421,11 @@ void GameLogic::reset()
destroyAllObjectsImmediate();

// set the hash to be rather large. We need to optimize this value later.
// m_objHash.resize(OBJ_HASH_SIZE);
m_objVector.resize(OBJ_HASH_SIZE, nullptr);
#if USING_STLPORT
m_objHash.resize(OBJ_HASH_SIZE);
#else
m_objHash.reserve(OBJ_HASH_SIZE);
#endif

m_nextObjID = (ObjectID)1;

Expand Down Expand Up @@ -3977,13 +3979,8 @@ void GameLogic::addObjectToLookupTable( Object *obj )
if( obj == nullptr )
return;

// add to lookup
// m_objHash[ obj->getID() ] = obj;
ObjectID newID = obj->getID();
while( newID >= m_objVector.size() ) // Fail case is hella rare, so faster to double up on size() call
m_objVector.resize(m_objVector.size() * 2, nullptr);

m_objVector[ newID ] = obj;
// add to lookup table
m_objHash[ obj->getID() ] = obj;

}

Expand All @@ -3994,13 +3991,11 @@ void GameLogic::removeObjectFromLookupTable( Object *obj )
{

// sanity
// TheSuperHackers @fix Mauller/Xezon 24/04/2025 Prevent out of range access to vector lookup table
if( obj == nullptr || static_cast<size_t>(obj->getID()) >= m_objVector.size() )
if( obj == nullptr )
return;

// remove from lookup table
// m_objHash.erase( obj->getID() );
m_objVector[ obj->getID() ] = nullptr;
m_objHash.erase( obj->getID() );

}

Expand Down
Loading