Skip to content

Commit

Permalink
physenv: I forgot to actually implement the rest of the delete logic
Browse files Browse the repository at this point in the history
  • Loading branch information
RaphaelIT7 committed Nov 19, 2024
1 parent 4399b4b commit 2c5229a
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 7 deletions.
57 changes: 50 additions & 7 deletions source/modules/physenv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,11 +379,25 @@ LUA_FUNCTION_STATIC(physenv_DestroyEnvironment)
if (!physics)
LUA->ThrowError("Failed to get IPhysics!");

ILuaPhysicsEnvironment* pEnvironment = Get_ILuaPhysicsEnvironment(1, true);
if (pEnvironment->pEnvironment)
physics->DestroyEnvironment(pEnvironment->pEnvironment);
ILuaPhysicsEnvironment* pLuaEnv = Get_ILuaPhysicsEnvironment(1, true);
CPhysicsEnvironment* pEnvironment = (CPhysicsEnvironment*)pLuaEnv->pEnvironment;
if (pLuaEnv->pEnvironment)
{
int index = -1;
for (int i = pEnvironment->m_objects.Count(); --i >= 0; )
{
IPhysicsObject* pObject = pEnvironment->m_objects[i];
CBaseEntity* pEntity = (CBaseEntity*)pObject->GetGameData();
if (pEntity)
{

Delete_ILuaPhysicsEnvironment(pEnvironment);
}
}

physics->DestroyEnvironment(pEnvironment);
}

Delete_ILuaPhysicsEnvironment(pLuaEnv);

return 0;
}
Expand Down Expand Up @@ -1679,6 +1693,8 @@ void* hook_CBaseEntity_GMOD_VPhysicsTest(CBaseEntity* pEnt, IPhysicsObject* obj)
static Detouring::Hook detour_CPhysicsEnvironment_DestroyObject;
static void hook_CPhysicsEnvironment_DestroyObject(CPhysicsEnvironment* pEnvironment, IPhysicsObject* pObject)
{
int foundIndex = -1;
CPhysicsEnvironment* pFoundEnvironment = NULL;
if (pEnvironment != physics->GetActiveEnvironmentByIndex(0))
{
int index = -1;
Expand All @@ -1693,15 +1709,16 @@ static void hook_CPhysicsEnvironment_DestroyObject(CPhysicsEnvironment* pEnviron

if (index != -1)
{
foundIndex = index;
pEnvironment->m_objects.FastRemove(index);
pFoundEnvironment = pEnvironment;
return;
} else {
Warning("holylib - physenv: Failed to find a PhysicsObject in our environment?!?\n");
// We somehow failed to find it in this environment.... time to loop thru ALL.
}
}

bool bDeleted = false;
int envirnmentIndex = 0;
CPhysicsEnvironment* pEnv = pEnvironment;
while (pEnv != NULL)
Expand All @@ -1718,11 +1735,13 @@ static void hook_CPhysicsEnvironment_DestroyObject(CPhysicsEnvironment* pEnviron

if (index != -1)
{
foundIndex = index;
pEnv->m_objects.FastRemove(index);
pFoundEnvironment = pEnv;
pEnv = NULL;
bDeleted = true;
if (envirnmentIndex != 0 && g_pPhysEnvModule.InDebug())
Msg("holylib - physenv: Found right environment(%i) for physics object\n", envirnmentIndex);

break;
}

Expand All @@ -1738,8 +1757,32 @@ static void hook_CPhysicsEnvironment_DestroyObject(CPhysicsEnvironment* pEnviron
}
}

if (!bDeleted)
if (!pFoundEnvironment)
{
Warning("holylib - physenv: Failed to find environment of physics object.... How?!?\n");
return;
}

//pFoundEnvironment->DestroyObject(pObject);

CPhysicsObject* pPhysics = static_cast<CPhysicsObject*>(pObject);
// add this flag so we can optimize some cases
pPhysics->AddCallbackFlags(CALLBACK_MARKED_FOR_DELETE);

// was created/destroyed without simulating. No need to wake the neighbors!
if (foundIndex > pFoundEnvironment->m_lastObjectThisTick)
pPhysics->ForceSilentDelete();

if (pFoundEnvironment->m_inSimulation || pFoundEnvironment->m_queueDeleteObject)
{
// don't delete while simulating
pFoundEnvironment->m_deadObjects.AddToTail(pObject);
}
else
{
pFoundEnvironment->m_pSleepEvents->DeleteObject(pPhysics);
delete pObject;
}
}

void CPhysEnvModule::LuaInit(bool bServerInit)
Expand Down
59 changes: 59 additions & 0 deletions source/sourcesdk/cphysicsenvironment.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,4 +244,63 @@ class CCollisionSolver : public IVP_Collision_Filter, public IVP_Anomaly_Manager

class CCollisionEvent : public IPhysicsCollisionEvent, public IPhysicsCollisionSolver, public IPhysicsObjectEvent
{
};

class IVP_Event_Object;
class IVP_Listener_Object
{
public:
virtual void event_object_deleted(IVP_Event_Object*) = 0;
virtual void event_object_created(IVP_Event_Object*) = 0;
virtual void event_object_revived(IVP_Event_Object*) = 0;
virtual void event_object_frozen(IVP_Event_Object*) = 0;

virtual ~IVP_Listener_Object() {};
};

class CSleepObjects : public IVP_Listener_Object
{
public:
CSleepObjects(void) : IVP_Listener_Object()
{
m_pCallback = NULL;
m_lastScrapeTime = 0.0f;
}

void SetHandler(IPhysicsObjectEvent* pListener)
{
m_pCallback = pListener;
}

void Remove(intp index)
{
// fast remove preserves indices except for the last element (moved into the empty spot)
m_activeObjects.FastRemove(index);
// If this isn't the last element, shift its index over
if (index < m_activeObjects.Count())
{
m_activeObjects[index]->SetActiveIndex(index);
}
}

void DeleteObject(CPhysicsObject* pObject)
{
int index = pObject->GetActiveIndex();
if (index < m_activeObjects.Count())
{
Assert(m_activeObjects[index] == pObject);
Remove(index);
pObject->SetActiveIndex(0xFFFF);
}
else
{
Assert(index == 0xFFFF);
}

}

private:
CUtlVector<CPhysicsObject*> m_activeObjects;
float m_lastScrapeTime;
IPhysicsObjectEvent* m_pCallback;
};

0 comments on commit 2c5229a

Please sign in to comment.