Also unload collision and layers when unloading map

Ensure that the `CCollision` and `CLayers` instances do not keep any pointers to the map data after the map has been unloaded.
This commit is contained in:
Robert Müller 2024-05-05 12:33:19 +02:00
parent 7d640e1f98
commit 1551dda3e9
6 changed files with 76 additions and 80 deletions

View file

@ -612,6 +612,9 @@ void CGameClient::OnReset()
Editor()->ResetMentions(); Editor()->ResetMentions();
Editor()->ResetIngameMoved(); Editor()->ResetIngameMoved();
Collision()->Unload();
Layers()->Unload();
} }
void CGameClient::UpdatePositions() void CGameClient::UpdatePositions()

View file

@ -38,28 +38,19 @@ vec2 ClampVel(int MoveRestriction, vec2 Vel)
CCollision::CCollision() CCollision::CCollision()
{ {
m_pTiles = 0; m_pDoor = nullptr;
m_Width = 0; Unload();
m_Height = 0;
m_pLayers = 0;
m_pTele = 0;
m_pSpeedup = 0;
m_pFront = 0;
m_pSwitch = 0;
m_pDoor = 0;
m_pTune = 0;
} }
CCollision::~CCollision() CCollision::~CCollision()
{ {
Dest(); Unload();
} }
void CCollision::Init(class CLayers *pLayers) void CCollision::Init(class CLayers *pLayers)
{ {
Dest(); Unload();
m_HighestSwitchNumber = 0;
m_pLayers = pLayers; m_pLayers = pLayers;
m_Width = m_pLayers->GameLayer()->m_Width; m_Width = m_pLayers->GameLayer()->m_Width;
m_Height = m_pLayers->GameLayer()->m_Height; m_Height = m_pLayers->GameLayer()->m_Height;
@ -88,10 +79,6 @@ void CCollision::Init(class CLayers *pLayers)
m_pDoor = new CDoorTile[m_Width * m_Height]; m_pDoor = new CDoorTile[m_Width * m_Height];
mem_zero(m_pDoor, (size_t)m_Width * m_Height * sizeof(CDoorTile)); mem_zero(m_pDoor, (size_t)m_Width * m_Height * sizeof(CDoorTile));
} }
else
{
m_pDoor = 0;
}
if(m_pLayers->TuneLayer()) if(m_pLayers->TuneLayer())
{ {
@ -132,9 +119,6 @@ void CCollision::Init(class CLayers *pLayers)
} }
} }
m_TeleIns.clear();
m_TeleOuts.clear();
m_TeleCheckOuts.clear();
if(m_pTele) if(m_pTele)
{ {
for(int i = 0; i < m_Width * m_Height; i++) for(int i = 0; i < m_Width * m_Height; i++)
@ -160,6 +144,28 @@ void CCollision::Init(class CLayers *pLayers)
} }
} }
void CCollision::Unload()
{
m_pTiles = nullptr;
m_Width = 0;
m_Height = 0;
m_pLayers = nullptr;
m_HighestSwitchNumber = 0;
m_TeleIns.clear();
m_TeleOuts.clear();
m_TeleCheckOuts.clear();
m_pTele = nullptr;
m_pSpeedup = nullptr;
m_pFront = nullptr;
m_pSwitch = nullptr;
m_pTune = nullptr;
delete[] m_pDoor;
m_pDoor = nullptr;
}
void CCollision::FillAntibot(CAntibotMapData *pMapData) void CCollision::FillAntibot(CAntibotMapData *pMapData)
{ {
pMapData->m_Width = m_Width; pMapData->m_Width = m_Width;
@ -585,21 +591,6 @@ void CCollision::MoveBox(vec2 *pInoutPos, vec2 *pInoutVel, vec2 Size, vec2 Elast
// DDRace // DDRace
void CCollision::Dest()
{
delete[] m_pDoor;
m_pTiles = 0;
m_Width = 0;
m_Height = 0;
m_pLayers = 0;
m_pTele = 0;
m_pSpeedup = 0;
m_pFront = 0;
m_pSwitch = 0;
m_pTune = 0;
m_pDoor = 0;
}
int CCollision::IsSolid(int x, int y) const int CCollision::IsSolid(int x, int y) const
{ {
int index = GetTile(x, y); int index = GetTile(x, y);

View file

@ -24,16 +24,14 @@ struct CAntibotMapData;
class CCollision class CCollision
{ {
class CTile *m_pTiles;
int m_Width;
int m_Height;
class CLayers *m_pLayers;
public: public:
CCollision(); CCollision();
~CCollision(); ~CCollision();
void Init(class CLayers *pLayers); void Init(class CLayers *pLayers);
void Unload();
void FillAntibot(CAntibotMapData *pMapData); void FillAntibot(CAntibotMapData *pMapData);
bool CheckPoint(float x, float y) const { return IsSolid(round_to_int(x), round_to_int(y)); } bool CheckPoint(float x, float y) const { return IsSolid(round_to_int(x), round_to_int(y)); }
bool CheckPoint(vec2 Pos) const { return CheckPoint(Pos.x, Pos.y); } bool CheckPoint(vec2 Pos) const { return CheckPoint(Pos.x, Pos.y); }
int GetCollisionAt(float x, float y) const { return GetTile(round_to_int(x), round_to_int(y)); } int GetCollisionAt(float x, float y) const { return GetTile(round_to_int(x), round_to_int(y)); }
@ -47,8 +45,6 @@ public:
bool TestBox(vec2 Pos, vec2 Size) const; bool TestBox(vec2 Pos, vec2 Size) const;
// DDRace // DDRace
void Dest();
void SetCollisionAt(float x, float y, int id); void SetCollisionAt(float x, float y, int id);
void SetDTile(float x, float y, bool State); void SetDTile(float x, float y, bool State);
void SetDCollisionAt(float x, float y, int Type, int Flags, int Number); void SetDCollisionAt(float x, float y, int Type, int Flags, int Number);
@ -122,6 +118,11 @@ public:
const std::vector<vec2> &TeleCheckOuts(int Number) { return m_TeleCheckOuts[Number]; } const std::vector<vec2> &TeleCheckOuts(int Number) { return m_TeleCheckOuts[Number]; }
private: private:
class CTile *m_pTiles;
int m_Width;
int m_Height;
class CLayers *m_pLayers;
std::map<int, std::vector<vec2>> m_TeleIns; std::map<int, std::vector<vec2>> m_TeleIns;
std::map<int, std::vector<vec2>> m_TeleOuts; std::map<int, std::vector<vec2>> m_TeleOuts;
std::map<int, std::vector<vec2>> m_TeleCheckOuts; std::map<int, std::vector<vec2>> m_TeleCheckOuts;

View file

@ -8,33 +8,17 @@
CLayers::CLayers() CLayers::CLayers()
{ {
m_GroupsNum = 0; Unload();
m_GroupsStart = 0;
m_LayersNum = 0;
m_LayersStart = 0;
m_pGameGroup = 0;
m_pGameLayer = 0;
m_pMap = 0;
m_pTeleLayer = 0;
m_pSpeedupLayer = 0;
m_pFrontLayer = 0;
m_pSwitchLayer = 0;
m_pTuneLayer = 0;
} }
void CLayers::Init(class IKernel *pKernel) void CLayers::Init(class IKernel *pKernel)
{ {
Unload();
m_pMap = pKernel->RequestInterface<IMap>(); m_pMap = pKernel->RequestInterface<IMap>();
m_pMap->GetType(MAPITEMTYPE_GROUP, &m_GroupsStart, &m_GroupsNum); m_pMap->GetType(MAPITEMTYPE_GROUP, &m_GroupsStart, &m_GroupsNum);
m_pMap->GetType(MAPITEMTYPE_LAYER, &m_LayersStart, &m_LayersNum); m_pMap->GetType(MAPITEMTYPE_LAYER, &m_LayersStart, &m_LayersNum);
m_pTeleLayer = 0;
m_pSpeedupLayer = 0;
m_pFrontLayer = 0;
m_pSwitchLayer = 0;
m_pTuneLayer = 0;
for(int g = 0; g < NumGroups(); g++) for(int g = 0; g < NumGroups(); g++)
{ {
CMapItemGroup *pGroup = GetGroup(g); CMapItemGroup *pGroup = GetGroup(g);
@ -129,17 +113,12 @@ void CLayers::Init(class IKernel *pKernel)
void CLayers::InitBackground(class IMap *pMap) void CLayers::InitBackground(class IMap *pMap)
{ {
Unload();
m_pMap = pMap; m_pMap = pMap;
m_pMap->GetType(MAPITEMTYPE_GROUP, &m_GroupsStart, &m_GroupsNum); m_pMap->GetType(MAPITEMTYPE_GROUP, &m_GroupsStart, &m_GroupsNum);
m_pMap->GetType(MAPITEMTYPE_LAYER, &m_LayersStart, &m_LayersNum); m_pMap->GetType(MAPITEMTYPE_LAYER, &m_LayersStart, &m_LayersNum);
//following is here to prevent crash using standard map as background
m_pTeleLayer = 0;
m_pSpeedupLayer = 0;
m_pFrontLayer = 0;
m_pSwitchLayer = 0;
m_pTuneLayer = 0;
for(int g = 0; g < NumGroups(); g++) for(int g = 0; g < NumGroups(); g++)
{ {
CMapItemGroup *pGroup = GetGroup(g); CMapItemGroup *pGroup = GetGroup(g);
@ -179,6 +158,24 @@ void CLayers::InitBackground(class IMap *pMap)
InitTilemapSkip(); InitTilemapSkip();
} }
void CLayers::Unload()
{
m_GroupsNum = 0;
m_GroupsStart = 0;
m_LayersNum = 0;
m_LayersStart = 0;
m_pGameGroup = nullptr;
m_pGameLayer = nullptr;
m_pMap = nullptr;
m_pTeleLayer = nullptr;
m_pSpeedupLayer = nullptr;
m_pFrontLayer = nullptr;
m_pSwitchLayer = nullptr;
m_pTuneLayer = nullptr;
}
void CLayers::InitTilemapSkip() void CLayers::InitTilemapSkip()
{ {
for(int g = 0; g < NumGroups(); g++) for(int g = 0; g < NumGroups(); g++)

View file

@ -12,20 +12,12 @@ struct CMapItemLayerTilemap;
class CLayers class CLayers
{ {
int m_GroupsNum;
int m_GroupsStart;
int m_LayersNum;
int m_LayersStart;
CMapItemGroup *m_pGameGroup;
CMapItemLayerTilemap *m_pGameLayer;
IMap *m_pMap;
void InitTilemapSkip();
public: public:
CLayers(); CLayers();
void Init(IKernel *pKernel); void Init(IKernel *pKernel);
void InitBackground(IMap *pMap); void InitBackground(IMap *pMap);
void Unload();
int NumGroups() const { return m_GroupsNum; } int NumGroups() const { return m_GroupsNum; }
int NumLayers() const { return m_LayersNum; } int NumLayers() const { return m_LayersNum; }
IMap *Map() const { return m_pMap; } IMap *Map() const { return m_pMap; }
@ -43,11 +35,22 @@ public:
CMapItemLayerTilemap *TuneLayer() const { return m_pTuneLayer; } CMapItemLayerTilemap *TuneLayer() const { return m_pTuneLayer; }
private: private:
int m_GroupsNum;
int m_GroupsStart;
int m_LayersNum;
int m_LayersStart;
CMapItemGroup *m_pGameGroup;
CMapItemLayerTilemap *m_pGameLayer;
IMap *m_pMap;
CMapItemLayerTilemap *m_pTeleLayer; CMapItemLayerTilemap *m_pTeleLayer;
CMapItemLayerTilemap *m_pSpeedupLayer; CMapItemLayerTilemap *m_pSpeedupLayer;
CMapItemLayerTilemap *m_pFrontLayer; CMapItemLayerTilemap *m_pFrontLayer;
CMapItemLayerTilemap *m_pSwitchLayer; CMapItemLayerTilemap *m_pSwitchLayer;
CMapItemLayerTilemap *m_pTuneLayer; CMapItemLayerTilemap *m_pTuneLayer;
void InitTilemapSkip();
}; };
#endif #endif

View file

@ -4187,7 +4187,8 @@ void CGameContext::OnShutdown(void *pPersistentData)
DeleteTempfile(); DeleteTempfile();
ConfigManager()->ResetGameSettings(); ConfigManager()->ResetGameSettings();
Collision()->Dest(); Collision()->Unload();
Layers()->Unload();
delete m_pController; delete m_pController;
m_pController = 0; m_pController = 0;
Clear(); Clear();