1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-01-19 12:07:13 +01:00

Don't clear entity containers untill after the virtual machine was closed. Should close #22

This commit is contained in:
Sandu Liviu Catalin 2016-07-16 15:45:36 +03:00
parent 7fe7116df4
commit e32464b6ea
4 changed files with 260 additions and 35 deletions

View File

@ -87,6 +87,37 @@ public:
} }
}; };
/* ------------------------------------------------------------------------------------------------
* Implements RAII to make sure that entity containers area cleaned up at all costs.
*/
template < typename T > class ContainerCleaner
{
// --------------------------------------------------------------------------------------------
const EntityType m_Type; // The type of entity container to clear.
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
ContainerCleaner(T & container, EntityType type)
: m_Type(type)
{
for (auto & ent : container)
{
ent.Destroy();
}
}
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~ContainerCleaner()
{
Core::Get().ClearContainer(m_Type);
}
};
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Core Core::s_Inst; Core Core::s_Inst;
@ -413,14 +444,16 @@ void Core::Terminate()
// Tell modules to do their monkey business // Tell modules to do their monkey business
_Func->SendPluginCommand(0xDEADC0DE, ""); _Func->SendPluginCommand(0xDEADC0DE, "");
} }
LogDbg("Clearing the entity containers");
// Release all entity resources by clearing the containers // Release all entity resources by clearing the containers
m_Players.clear(); ContainerCleaner< Players > cc_players(m_Players, ENT_PLAYER);
m_Vehicles.clear(); ContainerCleaner< Vehicles > cc_vehicles(m_Vehicles, ENT_VEHICLE);
m_Objects.clear(); ContainerCleaner< Objects > cc_objects(m_Objects, ENT_OBJECT);
m_Pickups.clear(); ContainerCleaner< Pickups > cc_pickups(m_Pickups, ENT_PICKUP);
m_Checkpoints.clear(); ContainerCleaner< Checkpoints > cc_checkpoints(m_Checkpoints, ENT_CHECKPOINT);
m_Blips.clear(); ContainerCleaner< Blips > cc_blips(m_Blips, ENT_BLIP);
m_Keybinds.clear(); ContainerCleaner< Keybinds > cc_keybinds(m_Keybinds, ENT_KEYBIND);
LogDbg("Terminating routines an commands");
// Release all resources from routines // Release all resources from routines
TerminateRoutines(); TerminateRoutines();
// Release all resources from command managers // Release all resources from command managers
@ -435,6 +468,7 @@ void Core::Terminate()
// Is there a VM to close? // Is there a VM to close?
if (m_VM) if (m_VM)
{ {
LogDbg("Closing the virtual machine");
// Release all script callbacks // Release all script callbacks
ResetFunc(); ResetFunc();
// Release the script instances // Release the script instances
@ -451,6 +485,8 @@ void Core::Terminate()
// Tell modules to do their monkey business // Tell modules to do their monkey business
_Func->SendPluginCommand(0xDEADBEAF, ""); _Func->SendPluginCommand(0xDEADBEAF, "");
} }
LogDbg("Squirrel plugin was successfully terminated");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -688,7 +724,7 @@ void Core::BindEvent(Int32 id, Object & env, Function & func)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Core::BlipInst::~BlipInst() void Core::BlipInst::Destroy()
{ {
// Should we notify that this entity is being cleaned up? // Should we notify that this entity is being cleaned up?
if (VALID_ENTITY(mID)) if (VALID_ENTITY(mID))
@ -711,12 +747,14 @@ Core::BlipInst::~BlipInst()
// Now attempt to destroy this entity from the server // Now attempt to destroy this entity from the server
_Func->DestroyCoordBlip(mID); _Func->DestroyCoordBlip(mID);
} }
// Don't release the callbacks abruptly in destructor // Reset the instance to it's initial state
ResetInst(*this);
// Don't release the callbacks abruptly
Core::ResetFunc(*this); Core::ResetFunc(*this);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Core::CheckpointInst::~CheckpointInst() void Core::CheckpointInst::Destroy()
{ {
// Should we notify that this entity is being cleaned up? // Should we notify that this entity is being cleaned up?
if (VALID_ENTITY(mID)) if (VALID_ENTITY(mID))
@ -739,12 +777,14 @@ Core::CheckpointInst::~CheckpointInst()
// Now attempt to destroy this entity from the server // Now attempt to destroy this entity from the server
_Func->DeleteCheckPoint(mID); _Func->DeleteCheckPoint(mID);
} }
// Don't release the callbacks abruptly in destructor // Reset the instance to it's initial state
ResetInst(*this);
// Don't release the callbacks abruptly
Core::ResetFunc(*this); Core::ResetFunc(*this);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Core::KeybindInst::~KeybindInst() void Core::KeybindInst::Destroy()
{ {
// Should we notify that this entity is being cleaned up? // Should we notify that this entity is being cleaned up?
if (VALID_ENTITY(mID)) if (VALID_ENTITY(mID))
@ -767,12 +807,14 @@ Core::KeybindInst::~KeybindInst()
// Now attempt to destroy this entity from the server // Now attempt to destroy this entity from the server
_Func->RemoveKeyBind(mID); _Func->RemoveKeyBind(mID);
} }
// Don't release the callbacks abruptly in destructor // Reset the instance to it's initial state
ResetInst(*this);
// Don't release the callbacks abruptly
Core::ResetFunc(*this); Core::ResetFunc(*this);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Core::ObjectInst::~ObjectInst() void Core::ObjectInst::Destroy()
{ {
// Should we notify that this entity is being cleaned up? // Should we notify that this entity is being cleaned up?
if (VALID_ENTITY(mID)) if (VALID_ENTITY(mID))
@ -795,12 +837,14 @@ Core::ObjectInst::~ObjectInst()
// Now attempt to destroy this entity from the server // Now attempt to destroy this entity from the server
_Func->DeleteObject(mID); _Func->DeleteObject(mID);
} }
// Don't release the callbacks abruptly in destructor // Reset the instance to it's initial state
ResetInst(*this);
// Don't release the callbacks abruptly
Core::ResetFunc(*this); Core::ResetFunc(*this);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Core::PickupInst::~PickupInst() void Core::PickupInst::Destroy()
{ {
// Should we notify that this entity is being cleaned up? // Should we notify that this entity is being cleaned up?
if (VALID_ENTITY(mID)) if (VALID_ENTITY(mID))
@ -823,12 +867,14 @@ Core::PickupInst::~PickupInst()
// Now attempt to destroy this entity from the server // Now attempt to destroy this entity from the server
_Func->DeletePickup(mID); _Func->DeletePickup(mID);
} }
// Don't release the callbacks abruptly in destructor // Reset the instance to it's initial state
ResetInst(*this);
// Don't release the callbacks abruptly
Core::ResetFunc(*this); Core::ResetFunc(*this);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Core::PlayerInst::~PlayerInst() void Core::PlayerInst::Destroy()
{ {
// Should we notify that this entity is being cleaned up? // Should we notify that this entity is being cleaned up?
if (VALID_ENTITY(mID)) if (VALID_ENTITY(mID))
@ -845,12 +891,14 @@ Core::PlayerInst::~PlayerInst()
// Release the used memory buffer // Release the used memory buffer
mInst->m_Buffer.ResetAll(); mInst->m_Buffer.ResetAll();
} }
// Don't release the callbacks abruptly in destructor // Reset the instance to it's initial state
ResetInst(*this);
// Don't release the callbacks abruptly
Core::ResetFunc(*this); Core::ResetFunc(*this);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Core::VehicleInst::~VehicleInst() void Core::VehicleInst::Destroy()
{ {
// Should we notify that this entity is being cleaned up? // Should we notify that this entity is being cleaned up?
if (VALID_ENTITY(mID)) if (VALID_ENTITY(mID))
@ -873,7 +921,9 @@ Core::VehicleInst::~VehicleInst()
// Now attempt to destroy this entity from the server // Now attempt to destroy this entity from the server
_Func->DeleteVehicle(mID); _Func->DeleteVehicle(mID);
} }
// Don't release the callbacks abruptly in destructor // Reset the instance to it's initial state
ResetInst(*this);
// Don't release the callbacks abruptly
Core::ResetFunc(*this); Core::ResetFunc(*this);
} }

View File

@ -15,6 +15,11 @@
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
namespace SqMod { namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Forward declarations.
*/
template < typename T > class ContainerCleaner;
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Circular locks employed by the central core. * Circular locks employed by the central core.
*/ */
@ -29,6 +34,9 @@ enum CoreCircularLocks
*/ */
class Core class Core
{ {
// --------------------------------------------------------------------------------------------
template < typename T > friend class ContainerCleaner;
private: private:
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
@ -71,10 +79,29 @@ protected:
*/ */
struct BlipInst struct BlipInst
{ {
/* ----------------------------------------------------------------------------------------
* Default constructor.
*/
BlipInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr) BlipInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr)
{ /* ... */ } {
Core::Get().ResetInst(*this);
}
~BlipInst(); /* ----------------------------------------------------------------------------------------
* Destructor.
*/
~BlipInst()
{
if (VALID_ENTITY(mID))
{
Destroy();
}
}
/* ----------------------------------------------------------------------------------------
* Destroy the entity instance from the server, if necessary.
*/
void Destroy();
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
Int32 mID; Int32 mID;
@ -103,10 +130,29 @@ protected:
*/ */
struct CheckpointInst struct CheckpointInst
{ {
/* ----------------------------------------------------------------------------------------
* Default constructor.
*/
CheckpointInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr) CheckpointInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr)
{ /* ... */ } {
Core::Get().ResetInst(*this);
}
~CheckpointInst(); /* ----------------------------------------------------------------------------------------
* Destructor.
*/
~CheckpointInst()
{
if (VALID_ENTITY(mID))
{
Destroy();
}
}
/* ----------------------------------------------------------------------------------------
* Destroy the entity instance from the server, if necessary.
*/
void Destroy();
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
Int32 mID; Int32 mID;
@ -127,10 +173,29 @@ protected:
*/ */
struct KeybindInst struct KeybindInst
{ {
/* ----------------------------------------------------------------------------------------
* Default constructor.
*/
KeybindInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr) KeybindInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr)
{ /* ... */ } {
Core::Get().ResetInst(*this);
}
~KeybindInst(); /* ----------------------------------------------------------------------------------------
* Destructor.
*/
~KeybindInst()
{
if (VALID_ENTITY(mID))
{
Destroy();
}
}
/* ----------------------------------------------------------------------------------------
* Destroy the entity instance from the server, if necessary.
*/
void Destroy();
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
Int32 mID; Int32 mID;
@ -158,10 +223,29 @@ protected:
*/ */
struct ObjectInst struct ObjectInst
{ {
/* ----------------------------------------------------------------------------------------
* Default constructor.
*/
ObjectInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr) ObjectInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr)
{ /* ... */ } {
Core::Get().ResetInst(*this);
}
~ObjectInst(); /* ----------------------------------------------------------------------------------------
* Destructor.
*/
~ObjectInst()
{
if (VALID_ENTITY(mID))
{
Destroy();
}
}
/* ----------------------------------------------------------------------------------------
* Destroy the entity instance from the server, if necessary.
*/
void Destroy();
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
Int32 mID; Int32 mID;
@ -183,10 +267,29 @@ protected:
*/ */
struct PickupInst struct PickupInst
{ {
/* ----------------------------------------------------------------------------------------
* Default constructor.
*/
PickupInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr) PickupInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr)
{ /* ... */ } {
Core::Get().ResetInst(*this);
}
~PickupInst(); /* ----------------------------------------------------------------------------------------
* Destructor.
*/
~PickupInst()
{
if (VALID_ENTITY(mID))
{
Destroy();
}
}
/* ----------------------------------------------------------------------------------------
* Destroy the entity instance from the server, if necessary.
*/
void Destroy();
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
Int32 mID; Int32 mID;
@ -209,10 +312,29 @@ protected:
*/ */
struct PlayerInst struct PlayerInst
{ {
/* ----------------------------------------------------------------------------------------
* Default constructor.
*/
PlayerInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr) PlayerInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr)
{ /* ... */ } {
Core::Get().ResetInst(*this);
}
~PlayerInst(); /* ----------------------------------------------------------------------------------------
* Destructor.
*/
~PlayerInst()
{
if (VALID_ENTITY(mID))
{
Destroy();
}
}
/* ----------------------------------------------------------------------------------------
* Destroy the entity instance from the server, if necessary.
*/
void Destroy();
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
Int32 mID; Int32 mID;
@ -310,10 +432,29 @@ protected:
*/ */
struct VehicleInst struct VehicleInst
{ {
/* ----------------------------------------------------------------------------------------
* Default constructor.
*/
VehicleInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr) VehicleInst() : mID(-1), mFlags(ENF_DEFAULT), mInst(nullptr)
{ /* ... */ } {
Core::Get().ResetInst(*this);
}
~VehicleInst(); /* ----------------------------------------------------------------------------------------
* Destructor.
*/
~VehicleInst()
{
if (VALID_ENTITY(mID))
{
Destroy();
}
}
/* ----------------------------------------------------------------------------------------
* Destroy the entity instance from the server, if necessary.
*/
void Destroy();
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
Int32 mID; Int32 mID;
@ -667,6 +808,24 @@ public:
protected: protected:
/* --------------------------------------------------------------------------------------------
* Container cleaner.
*/
void ClearContainer(EntityType type)
{
switch (type)
{
case ENT_BLIP: m_Blips.clear(); break;
case ENT_CHECKPOINT: m_Blips.clear(); break;
case ENT_KEYBIND: m_Blips.clear(); break;
case ENT_OBJECT: m_Blips.clear(); break;
case ENT_PICKUP: m_Blips.clear(); break;
case ENT_PLAYER: m_Blips.clear(); break;
case ENT_VEHICLE: m_Blips.clear(); break;
default: STHROWF("Cannot clear unknown entity type container");
}
}
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Instance cleaners. * Instance cleaners.
*/ */

View File

@ -224,6 +224,7 @@ static void OnPlayerDisconnect(int32_t player_id, vcmpDisconnectReason reason)
// Attempt to forward the event // Attempt to forward the event
try try
{ {
printf("Disconnecting... %d\n", player_id);
Core::Get().DisconnectPlayer(player_id, reason, NullObject()); Core::Get().DisconnectPlayer(player_id, reason, NullObject());
} }
SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerDisconnect) SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerDisconnect)

View File

@ -394,6 +394,21 @@ enum EntityFlags
ENF_LOCKED = (2 << 1) ENF_LOCKED = (2 << 1)
}; };
/* ------------------------------------------------------------------------------------------------
* Used to identify entity types.
*/
enum EntityType
{
ENT_UNKNOWN = 0,
ENT_BLIP,
ENT_CHECKPOINT,
ENT_KEYBIND,
ENT_OBJECT,
ENT_PICKUP,
ENT_PLAYER,
ENT_VEHICLE
};
} // Namespace:: SqMod } // Namespace:: SqMod
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------