mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 00:37:15 +01:00
Revise the entity clean up to fix crash at server shutdown, remove duplicate code and overall make the code more reliable.
Various other minor changes surrounding the entity destruction from the server.
This commit is contained in:
parent
88765b80c0
commit
1229e7f59f
119
source/Core.cpp
119
source/Core.cpp
@ -90,22 +90,22 @@ public:
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Implements RAII to make sure that entity containers area cleaned up at all costs.
|
||||
*/
|
||||
template < typename T > class ContainerCleaner
|
||||
class ContainerCleaner
|
||||
{
|
||||
// --------------------------------------------------------------------------------------------
|
||||
const EntityType m_Type; // The type of entity container to clear.
|
||||
EntityType m_Type; // The type of entity container to clear.
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor.
|
||||
*/
|
||||
ContainerCleaner(T & container, EntityType type, bool shutdown)
|
||||
template < typename T > ContainerCleaner(T & container, EntityType type, bool destroy)
|
||||
: m_Type(type)
|
||||
{
|
||||
for (auto & ent : container)
|
||||
{
|
||||
ent.Destroy(shutdown);
|
||||
ent.Destroy(destroy, SQMOD_DESTROY_CLEANUP, NullObject());
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,6 +141,7 @@ Core::Core()
|
||||
, m_IncomingNameCapacity(0)
|
||||
, m_Debugging(false)
|
||||
, m_Executed(false)
|
||||
, m_Shutdown(false)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
@ -173,16 +174,18 @@ bool Core::Initialize()
|
||||
switch (ini_ret)
|
||||
{
|
||||
case SI_FAIL:
|
||||
{
|
||||
OutputError("Failed to load the configuration file. Probably invalid");
|
||||
break;
|
||||
} break;
|
||||
case SI_NOMEM:
|
||||
{
|
||||
OutputError("Run out of memory while loading the configuration file");
|
||||
break;
|
||||
} break;
|
||||
case SI_FILE:
|
||||
{
|
||||
OutputError("Failed to load the configuration file. %s", std::strerror(errno));
|
||||
break;
|
||||
default:
|
||||
OutputError("Failed to load the configuration file for some unforeseen reason");
|
||||
} break;
|
||||
default: OutputError("Failed to load the configuration file for some unforeseen reason");
|
||||
}
|
||||
// Failed to load the configuration file
|
||||
return false;
|
||||
@ -438,6 +441,8 @@ bool Core::Execute()
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Core::Terminate(bool shutdown)
|
||||
{
|
||||
m_Shutdown = shutdown;
|
||||
// Is there a virtual machine present?
|
||||
if (m_VM)
|
||||
{
|
||||
LogDbg("Signaling outside plug-ins to release their resources");
|
||||
@ -446,13 +451,13 @@ void Core::Terminate(bool shutdown)
|
||||
}
|
||||
LogDbg("Clearing the entity containers");
|
||||
// Release all entity resources by clearing the containers
|
||||
const ContainerCleaner< Players > cc_players(m_Players, ENT_PLAYER, shutdown);
|
||||
const ContainerCleaner< Vehicles > cc_vehicles(m_Vehicles, ENT_VEHICLE, shutdown);
|
||||
const ContainerCleaner< Objects > cc_objects(m_Objects, ENT_OBJECT, shutdown);
|
||||
const ContainerCleaner< Pickups > cc_pickups(m_Pickups, ENT_PICKUP, shutdown);
|
||||
const ContainerCleaner< Checkpoints > cc_checkpoints(m_Checkpoints, ENT_CHECKPOINT, shutdown);
|
||||
const ContainerCleaner< Blips > cc_blips(m_Blips, ENT_BLIP, shutdown);
|
||||
const ContainerCleaner< Keybinds > cc_keybinds(m_Keybinds, ENT_KEYBIND, shutdown);
|
||||
const ContainerCleaner cc_players(m_Players, ENT_PLAYER, !shutdown);
|
||||
const ContainerCleaner cc_vehicles(m_Vehicles, ENT_VEHICLE, !shutdown);
|
||||
const ContainerCleaner cc_objects(m_Objects, ENT_OBJECT, !shutdown);
|
||||
const ContainerCleaner cc_pickups(m_Pickups, ENT_PICKUP, !shutdown);
|
||||
const ContainerCleaner cc_checkpoints(m_Checkpoints, ENT_CHECKPOINT, !shutdown);
|
||||
const ContainerCleaner cc_blips(m_Blips, ENT_BLIP, !shutdown);
|
||||
const ContainerCleaner cc_keybinds(m_Keybinds, ENT_KEYBIND, !shutdown);
|
||||
LogDbg("Terminating routines an commands");
|
||||
// Release all resources from routines
|
||||
TerminateRoutines();
|
||||
@ -724,12 +729,12 @@ void Core::BindEvent(Int32 id, Object & env, Function & func)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Core::BlipInst::Destroy(bool shutdown)
|
||||
void Core::BlipInst::Destroy(bool destroy, Int32 header, Object & payload)
|
||||
{
|
||||
// Should we notify that this entity is being cleaned up?
|
||||
if (VALID_ENTITY(mID))
|
||||
{
|
||||
Core::Get().EmitBlipDestroyed(mID, SQMOD_DESTROY_CLEANUP, NullObject());
|
||||
Core::Get().EmitBlipDestroyed(mID, header, payload);
|
||||
}
|
||||
// Is there a manager instance associated with this entity?
|
||||
if (mInst)
|
||||
@ -739,8 +744,12 @@ void Core::BlipInst::Destroy(bool shutdown)
|
||||
// Release user data to avoid dangling or circular references
|
||||
mInst->m_Data.Release();
|
||||
}
|
||||
// Prevent further use of the manager instance
|
||||
mInst = nullptr;
|
||||
// Release the script object, if any
|
||||
mObj.Release();
|
||||
// Are we supposed to clean up this entity? (only at reload)
|
||||
if (!shutdown && VALID_ENTITY(mID) && (mFlags & ENF_OWNED))
|
||||
if (destroy && VALID_ENTITY(mID) && (mFlags & ENF_OWNED))
|
||||
{
|
||||
// Block the entity pool changes notification from triggering the destroy event
|
||||
const BitGuardU16 bg(mFlags, static_cast< Uint16 >(ENF_LOCKED));
|
||||
@ -748,18 +757,18 @@ void Core::BlipInst::Destroy(bool shutdown)
|
||||
_Func->DestroyCoordBlip(mID);
|
||||
}
|
||||
// Reset the instance to it's initial state
|
||||
ResetInst(*this);
|
||||
Core::ResetInst(*this);
|
||||
// Don't release the callbacks abruptly
|
||||
Core::ResetFunc(*this);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Core::CheckpointInst::Destroy(bool shutdown)
|
||||
void Core::CheckpointInst::Destroy(bool destroy, Int32 header, Object & payload)
|
||||
{
|
||||
// Should we notify that this entity is being cleaned up?
|
||||
if (VALID_ENTITY(mID))
|
||||
{
|
||||
Core::Get().EmitCheckpointDestroyed(mID, SQMOD_DESTROY_CLEANUP, NullObject());
|
||||
Core::Get().EmitCheckpointDestroyed(mID, header, payload);
|
||||
}
|
||||
// Is there a manager instance associated with this entity?
|
||||
if (mInst)
|
||||
@ -769,8 +778,12 @@ void Core::CheckpointInst::Destroy(bool shutdown)
|
||||
// Release user data to avoid dangling or circular references
|
||||
mInst->m_Data.Release();
|
||||
}
|
||||
// Prevent further use of the manager instance
|
||||
mInst = nullptr;
|
||||
// Release the script object, if any
|
||||
mObj.Release();
|
||||
// Are we supposed to clean up this entity? (only at reload)
|
||||
if (!shutdown && VALID_ENTITY(mID) && (mFlags & ENF_OWNED))
|
||||
if (destroy && VALID_ENTITY(mID) && (mFlags & ENF_OWNED))
|
||||
{
|
||||
// Block the entity pool changes notification from triggering the destroy event
|
||||
const BitGuardU16 bg(mFlags, static_cast< Uint16 >(ENF_LOCKED));
|
||||
@ -778,18 +791,18 @@ void Core::CheckpointInst::Destroy(bool shutdown)
|
||||
_Func->DeleteCheckPoint(mID);
|
||||
}
|
||||
// Reset the instance to it's initial state
|
||||
ResetInst(*this);
|
||||
Core::ResetInst(*this);
|
||||
// Don't release the callbacks abruptly
|
||||
Core::ResetFunc(*this);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Core::KeybindInst::Destroy(bool shutdown)
|
||||
void Core::KeybindInst::Destroy(bool destroy, Int32 header, Object & payload)
|
||||
{
|
||||
// Should we notify that this entity is being cleaned up?
|
||||
if (VALID_ENTITY(mID))
|
||||
{
|
||||
Core::Get().EmitKeybindDestroyed(mID, SQMOD_DESTROY_CLEANUP, NullObject());
|
||||
Core::Get().EmitKeybindDestroyed(mID, header, payload);
|
||||
}
|
||||
// Is there a manager instance associated with this entity?
|
||||
if (mInst)
|
||||
@ -799,8 +812,12 @@ void Core::KeybindInst::Destroy(bool shutdown)
|
||||
// Release user data to avoid dangling or circular references
|
||||
mInst->m_Data.Release();
|
||||
}
|
||||
// Prevent further use of the manager instance
|
||||
mInst = nullptr;
|
||||
// Release the script object, if any
|
||||
mObj.Release();
|
||||
// Are we supposed to clean up this entity? (only at reload)
|
||||
if (!shutdown && VALID_ENTITY(mID) && (mFlags & ENF_OWNED))
|
||||
if (destroy && VALID_ENTITY(mID) && (mFlags & ENF_OWNED))
|
||||
{
|
||||
// Block the entity pool changes notification from triggering the destroy event
|
||||
const BitGuardU16 bg(mFlags, static_cast< Uint16 >(ENF_LOCKED));
|
||||
@ -808,18 +825,18 @@ void Core::KeybindInst::Destroy(bool shutdown)
|
||||
_Func->RemoveKeyBind(mID);
|
||||
}
|
||||
// Reset the instance to it's initial state
|
||||
ResetInst(*this);
|
||||
Core::ResetInst(*this);
|
||||
// Don't release the callbacks abruptly
|
||||
Core::ResetFunc(*this);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Core::ObjectInst::Destroy(bool shutdown)
|
||||
void Core::ObjectInst::Destroy(bool destroy, Int32 header, Object & payload)
|
||||
{
|
||||
// Should we notify that this entity is being cleaned up?
|
||||
if (VALID_ENTITY(mID))
|
||||
{
|
||||
Core::Get().EmitObjectDestroyed(mID, SQMOD_DESTROY_CLEANUP, NullObject());
|
||||
Core::Get().EmitObjectDestroyed(mID, header, payload);
|
||||
}
|
||||
// Is there a manager instance associated with this entity?
|
||||
if (mInst)
|
||||
@ -829,8 +846,12 @@ void Core::ObjectInst::Destroy(bool shutdown)
|
||||
// Release user data to avoid dangling or circular references
|
||||
mInst->m_Data.Release();
|
||||
}
|
||||
// Prevent further use of the manager instance
|
||||
mInst = nullptr;
|
||||
// Release the script object, if any
|
||||
mObj.Release();
|
||||
// Are we supposed to clean up this entity? (only at reload)
|
||||
if (!shutdown && VALID_ENTITY(mID) && (mFlags & ENF_OWNED))
|
||||
if (destroy && VALID_ENTITY(mID) && (mFlags & ENF_OWNED))
|
||||
{
|
||||
// Block the entity pool changes notification from triggering the destroy event
|
||||
const BitGuardU16 bg(mFlags, static_cast< Uint16 >(ENF_LOCKED));
|
||||
@ -838,18 +859,18 @@ void Core::ObjectInst::Destroy(bool shutdown)
|
||||
_Func->DeleteObject(mID);
|
||||
}
|
||||
// Reset the instance to it's initial state
|
||||
ResetInst(*this);
|
||||
Core::ResetInst(*this);
|
||||
// Don't release the callbacks abruptly
|
||||
Core::ResetFunc(*this);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Core::PickupInst::Destroy(bool shutdown)
|
||||
void Core::PickupInst::Destroy(bool destroy, Int32 header, Object & payload)
|
||||
{
|
||||
// Should we notify that this entity is being cleaned up?
|
||||
if (VALID_ENTITY(mID))
|
||||
{
|
||||
Core::Get().EmitPickupDestroyed(mID, SQMOD_DESTROY_CLEANUP, NullObject());
|
||||
Core::Get().EmitPickupDestroyed(mID, header, payload);
|
||||
}
|
||||
// Is there a manager instance associated with this entity?
|
||||
if (mInst)
|
||||
@ -859,8 +880,12 @@ void Core::PickupInst::Destroy(bool shutdown)
|
||||
// Release user data to avoid dangling or circular references
|
||||
mInst->m_Data.Release();
|
||||
}
|
||||
// Prevent further use of the manager instance
|
||||
mInst = nullptr;
|
||||
// Release the script object, if any
|
||||
mObj.Release();
|
||||
// Are we supposed to clean up this entity? (only at reload)
|
||||
if (!shutdown && VALID_ENTITY(mID) && (mFlags & ENF_OWNED))
|
||||
if (destroy && VALID_ENTITY(mID) && (mFlags & ENF_OWNED))
|
||||
{
|
||||
// Block the entity pool changes notification from triggering the destroy event
|
||||
const BitGuardU16 bg(mFlags, static_cast< Uint16 >(ENF_LOCKED));
|
||||
@ -868,18 +893,18 @@ void Core::PickupInst::Destroy(bool shutdown)
|
||||
_Func->DeletePickup(mID);
|
||||
}
|
||||
// Reset the instance to it's initial state
|
||||
ResetInst(*this);
|
||||
Core::ResetInst(*this);
|
||||
// Don't release the callbacks abruptly
|
||||
Core::ResetFunc(*this);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Core::PlayerInst::Destroy(bool /*shutdown*/)
|
||||
void Core::PlayerInst::Destroy(bool /*destroy*/, Int32 header, Object & payload)
|
||||
{
|
||||
// Should we notify that this entity is being cleaned up?
|
||||
if (VALID_ENTITY(mID))
|
||||
{
|
||||
Core::Get().EmitPlayerDestroyed(mID, SQMOD_DESTROY_CLEANUP, NullObject());
|
||||
Core::Get().EmitPlayerDestroyed(mID, header, payload);
|
||||
}
|
||||
// Is there a manager instance associated with this entity?
|
||||
if (mInst)
|
||||
@ -891,19 +916,23 @@ void Core::PlayerInst::Destroy(bool /*shutdown*/)
|
||||
// Release the used memory buffer
|
||||
mInst->m_Buffer.ResetAll();
|
||||
}
|
||||
// Prevent further use of the manager instance
|
||||
mInst = nullptr;
|
||||
// Release the script object, if any
|
||||
mObj.Release();
|
||||
// Reset the instance to it's initial state
|
||||
ResetInst(*this);
|
||||
Core::ResetInst(*this);
|
||||
// Don't release the callbacks abruptly
|
||||
Core::ResetFunc(*this);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Core::VehicleInst::Destroy(bool shutdown)
|
||||
void Core::VehicleInst::Destroy(bool destroy, Int32 header, Object & payload)
|
||||
{
|
||||
// Should we notify that this entity is being cleaned up?
|
||||
if (VALID_ENTITY(mID))
|
||||
{
|
||||
Core::Get().EmitVehicleDestroyed(mID, SQMOD_DESTROY_CLEANUP, NullObject());
|
||||
Core::Get().EmitVehicleDestroyed(mID, header, payload);
|
||||
}
|
||||
// Is there a manager instance associated with this entity?
|
||||
if (mInst)
|
||||
@ -913,8 +942,12 @@ void Core::VehicleInst::Destroy(bool shutdown)
|
||||
// Release user data to avoid dangling or circular references
|
||||
mInst->m_Data.Release();
|
||||
}
|
||||
// Prevent further use of the manager instance
|
||||
mInst = nullptr;
|
||||
// Release the script object, if any
|
||||
mObj.Release();
|
||||
// Are we supposed to clean up this entity? (only at reload)
|
||||
if (!shutdown && VALID_ENTITY(mID) && (mFlags & ENF_OWNED))
|
||||
if (destroy && VALID_ENTITY(mID) && (mFlags & ENF_OWNED))
|
||||
{
|
||||
// Block the entity pool changes notification from triggering the destroy event
|
||||
const BitGuardU16 bg(mFlags, static_cast< Uint16 >(ENF_LOCKED));
|
||||
@ -922,7 +955,7 @@ void Core::VehicleInst::Destroy(bool shutdown)
|
||||
_Func->DeleteVehicle(mID);
|
||||
}
|
||||
// Reset the instance to it's initial state
|
||||
ResetInst(*this);
|
||||
Core::ResetInst(*this);
|
||||
// Don't release the callbacks abruptly
|
||||
Core::ResetFunc(*this);
|
||||
}
|
||||
|
@ -15,11 +15,6 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Forward declarations.
|
||||
*/
|
||||
template < typename T > class ContainerCleaner;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Circular locks employed by the central core.
|
||||
*/
|
||||
@ -34,9 +29,6 @@ enum CoreCircularLocks
|
||||
*/
|
||||
class Core
|
||||
{
|
||||
// --------------------------------------------------------------------------------------------
|
||||
template < typename T > friend class ContainerCleaner;
|
||||
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
@ -94,14 +86,14 @@ protected:
|
||||
{
|
||||
if (VALID_ENTITY(mID))
|
||||
{
|
||||
Destroy();
|
||||
Destroy(!Core::Get().ShuttingDown(), SQMOD_DESTROY_CLEANUP, NullObject());
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Destroy the entity instance from the server, if necessary.
|
||||
*/
|
||||
void Destroy(bool shutdown = false);
|
||||
void Destroy(bool destroy, Int32 header, Object & payload);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
Int32 mID; // The unique number that identifies this entity on the server.
|
||||
@ -145,14 +137,14 @@ protected:
|
||||
{
|
||||
if (VALID_ENTITY(mID))
|
||||
{
|
||||
Destroy();
|
||||
Destroy(!Core::Get().ShuttingDown(), SQMOD_DESTROY_CLEANUP, NullObject());
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Destroy the entity instance from the server, if necessary.
|
||||
*/
|
||||
void Destroy(bool shutdown = false);
|
||||
void Destroy(bool destroy, Int32 header, Object & payload);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
Int32 mID; // The unique number that identifies this entity on the server.
|
||||
@ -189,14 +181,14 @@ protected:
|
||||
{
|
||||
if (VALID_ENTITY(mID))
|
||||
{
|
||||
Destroy();
|
||||
Destroy(!Core::Get().ShuttingDown(), SQMOD_DESTROY_CLEANUP, NullObject());
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Destroy the entity instance from the server, if necessary.
|
||||
*/
|
||||
void Destroy(bool shutdown = false);
|
||||
void Destroy(bool destroy, Int32 header, Object & payload);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
Int32 mID; // The unique number that identifies this entity on the server.
|
||||
@ -239,14 +231,14 @@ protected:
|
||||
{
|
||||
if (VALID_ENTITY(mID))
|
||||
{
|
||||
Destroy();
|
||||
Destroy(!Core::Get().ShuttingDown(), SQMOD_DESTROY_CLEANUP, NullObject());
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Destroy the entity instance from the server, if necessary.
|
||||
*/
|
||||
void Destroy(bool shutdown = false);
|
||||
void Destroy(bool destroy, Int32 header, Object & payload);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
Int32 mID; // The unique number that identifies this entity on the server.
|
||||
@ -283,14 +275,14 @@ protected:
|
||||
{
|
||||
if (VALID_ENTITY(mID))
|
||||
{
|
||||
Destroy();
|
||||
Destroy(!Core::Get().ShuttingDown(), SQMOD_DESTROY_CLEANUP, NullObject());
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Destroy the entity instance from the server, if necessary.
|
||||
*/
|
||||
void Destroy(bool shutdown = false);
|
||||
void Destroy(bool destroy, Int32 header, Object & payload);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
Int32 mID; // The unique number that identifies this entity on the server.
|
||||
@ -328,14 +320,14 @@ protected:
|
||||
{
|
||||
if (VALID_ENTITY(mID))
|
||||
{
|
||||
Destroy();
|
||||
Destroy(false, SQMOD_DESTROY_CLEANUP, NullObject());
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Destroy the entity instance from the server, if necessary.
|
||||
*/
|
||||
void Destroy(bool shutdown = false);
|
||||
void Destroy(bool destroy, Int32 header, Object & payload);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
Int32 mID; // The unique number that identifies this entity on the server.
|
||||
@ -448,14 +440,14 @@ protected:
|
||||
{
|
||||
if (VALID_ENTITY(mID))
|
||||
{
|
||||
Destroy();
|
||||
Destroy(!Core::Get().ShuttingDown(), SQMOD_DESTROY_CLEANUP, NullObject());
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Destroy the entity instance from the server, if necessary.
|
||||
*/
|
||||
void Destroy(bool shutdown = false);
|
||||
void Destroy(bool destroy, Int32 header, Object & payload);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
Int32 mID; // The unique number that identifies this entity on the server.
|
||||
@ -540,6 +532,7 @@ private:
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool m_Debugging; // Enable debugging features, if any.
|
||||
bool m_Executed; // Whether the scripts were executed.
|
||||
bool m_Shutdown; // Whether the server currently shutting down.
|
||||
|
||||
public:
|
||||
|
||||
@ -603,6 +596,14 @@ public:
|
||||
return m_Executed;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether the server is currently in the process of shutting down.
|
||||
*/
|
||||
bool ShuttingDown() const
|
||||
{
|
||||
return m_Shutdown;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the value of the specified option.
|
||||
*/
|
||||
@ -807,46 +808,12 @@ public:
|
||||
const Players & GetPlayers() const { return m_Players; }
|
||||
const Vehicles & GetVehicles() const { return m_Vehicles; }
|
||||
|
||||
protected:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Container cleaner.
|
||||
*/
|
||||
void ClearContainer(EntityType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ENT_BLIP:
|
||||
{
|
||||
m_Blips.clear();
|
||||
} break;
|
||||
case ENT_CHECKPOINT:
|
||||
{
|
||||
m_Checkpoints.clear();
|
||||
} break;
|
||||
case ENT_KEYBIND:
|
||||
{
|
||||
m_Keybinds.clear();
|
||||
} break;
|
||||
case ENT_OBJECT:
|
||||
{
|
||||
m_Objects.clear();
|
||||
} break;
|
||||
case ENT_PICKUP:
|
||||
{
|
||||
m_Pickups.clear();
|
||||
} break;
|
||||
case ENT_PLAYER:
|
||||
{
|
||||
m_Players.clear();
|
||||
} break;
|
||||
case ENT_VEHICLE:
|
||||
{
|
||||
m_Vehicles.clear();
|
||||
} break;
|
||||
default: STHROWF("Cannot clear unknown entity type container");
|
||||
}
|
||||
}
|
||||
void ClearContainer(EntityType type);
|
||||
|
||||
protected:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Instance cleaners.
|
||||
|
@ -396,43 +396,11 @@ void Core::DeallocBlip(Int32 id, bool destroy, Int32 header, Object & payload)
|
||||
}
|
||||
// Retrieve the specified entity instance
|
||||
BlipInst & inst = m_Blips[id];
|
||||
// Make sure that the instance is even allocated
|
||||
if (INVALID_ENTITY(inst.mID) || (inst.mFlags & ENF_LOCKED))
|
||||
// Make sure that the instance is even allocated and we are allowed to destroy it
|
||||
if (VALID_ENTITY(inst.mID) && !(inst.mFlags & ENF_LOCKED))
|
||||
{
|
||||
return; // Nothing to deallocate!
|
||||
inst.Destroy(destroy, header, payload); // Now attempt to destroy the entity from the server
|
||||
}
|
||||
// Prevent further attempts to delete this entity
|
||||
const BitGuardU16 bg(inst.mFlags, static_cast< Uint16 >(ENF_LOCKED));
|
||||
// Let the script callbacks know this entity should no longer be used
|
||||
try
|
||||
{
|
||||
EmitBlipDestroyed(id, header, payload);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// The error was probably dealt with already
|
||||
}
|
||||
// Is there a manager instance associated with this entity?
|
||||
if (inst.mInst)
|
||||
{
|
||||
// Prevent further use of this entity
|
||||
inst.mInst->m_ID = -1;
|
||||
// Release user data to avoid dangling or circular references
|
||||
inst.mInst->m_Data.Release();
|
||||
}
|
||||
// Should we delete this entity from the server as well?
|
||||
if (destroy || (inst.mFlags & ENF_OWNED))
|
||||
{
|
||||
_Func->DestroyCoordBlip(inst.mID);
|
||||
}
|
||||
// Reset the entity instance
|
||||
ResetInst(inst);
|
||||
// Release associated script callbacks
|
||||
ResetFunc(inst);
|
||||
// Prevent further use of the manager instance
|
||||
inst.mInst = nullptr;
|
||||
// Release the script object, if any
|
||||
inst.mObj.Release();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
@ -445,43 +413,11 @@ void Core::DeallocCheckpoint(Int32 id, bool destroy, Int32 header, Object & payl
|
||||
}
|
||||
// Retrieve the specified entity instance
|
||||
CheckpointInst & inst = m_Checkpoints[id];
|
||||
// Make sure that the instance is even allocated
|
||||
if (INVALID_ENTITY(inst.mID) || (inst.mFlags & ENF_LOCKED))
|
||||
// Make sure that the instance is even allocated and we are allowed to destroy it
|
||||
if (VALID_ENTITY(inst.mID) && !(inst.mFlags & ENF_LOCKED))
|
||||
{
|
||||
return; // Nothing to deallocate!
|
||||
inst.Destroy(destroy, header, payload); // Now attempt to destroy the entity from the server
|
||||
}
|
||||
// Prevent further attempts to delete this entity
|
||||
const BitGuardU16 bg(inst.mFlags, static_cast< Uint16 >(ENF_LOCKED));
|
||||
// Let the script callbacks know this entity should no longer be used
|
||||
try
|
||||
{
|
||||
EmitCheckpointDestroyed(id, header, payload);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// The error was probably dealt with already
|
||||
}
|
||||
// Is there a manager instance associated with this entity?
|
||||
if (inst.mInst)
|
||||
{
|
||||
// Prevent further use of this entity
|
||||
inst.mInst->m_ID = -1;
|
||||
// Release user data to avoid dangling or circular references
|
||||
inst.mInst->m_Data.Release();
|
||||
}
|
||||
// Should we delete this entity from the server as well?
|
||||
if (destroy || (inst.mFlags & ENF_OWNED))
|
||||
{
|
||||
_Func->DeleteCheckPoint(inst.mID);
|
||||
}
|
||||
// Reset the entity instance
|
||||
ResetInst(inst);
|
||||
// Release associated script callbacks
|
||||
ResetFunc(inst);
|
||||
// Prevent further use of the manager instance
|
||||
inst.mInst = nullptr;
|
||||
// Release the script object, if any
|
||||
inst.mObj.Release();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
@ -494,43 +430,11 @@ void Core::DeallocKeybind(Int32 id, bool destroy, Int32 header, Object & payload
|
||||
}
|
||||
// Retrieve the specified entity instance
|
||||
KeybindInst & inst = m_Keybinds[id];
|
||||
// Make sure that the instance is even allocated
|
||||
if (INVALID_ENTITY(inst.mID) || (inst.mFlags & ENF_LOCKED))
|
||||
// Make sure that the instance is even allocated and we are allowed to destroy it
|
||||
if (VALID_ENTITY(inst.mID) && !(inst.mFlags & ENF_LOCKED))
|
||||
{
|
||||
return; // Nothing to deallocate!
|
||||
inst.Destroy(destroy, header, payload); // Now attempt to destroy the entity from the server
|
||||
}
|
||||
// Prevent further attempts to delete this entity
|
||||
const BitGuardU16 bg(inst.mFlags, static_cast< Uint16 >(ENF_LOCKED));
|
||||
// Let the script callbacks know this entity should no longer be used
|
||||
try
|
||||
{
|
||||
EmitBlipDestroyed(id, header, payload);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// The error was dealt with already
|
||||
}
|
||||
// Is there a manager instance associated with this entity?
|
||||
if (inst.mInst)
|
||||
{
|
||||
// Prevent further use of this entity
|
||||
inst.mInst->m_ID = -1;
|
||||
// Release user data to avoid dangling or circular references
|
||||
inst.mInst->m_Data.Release();
|
||||
}
|
||||
// Should we delete this entity from the server as well?
|
||||
if (destroy || (inst.mFlags & ENF_OWNED))
|
||||
{
|
||||
_Func->RemoveKeyBind(inst.mID);
|
||||
}
|
||||
// Reset the entity instance
|
||||
ResetInst(inst);
|
||||
// Release associated script callbacks
|
||||
ResetFunc(inst);
|
||||
// Prevent further use of the manager instance
|
||||
inst.mInst = nullptr;
|
||||
// Release the script object, if any
|
||||
inst.mObj.Release();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
@ -543,43 +447,11 @@ void Core::DeallocObject(Int32 id, bool destroy, Int32 header, Object & payload)
|
||||
}
|
||||
// Retrieve the specified entity instance
|
||||
ObjectInst & inst = m_Objects[id];
|
||||
// Make sure that the instance is even allocated
|
||||
if (INVALID_ENTITY(inst.mID) || (inst.mFlags & ENF_LOCKED))
|
||||
// Make sure that the instance is even allocated and we are allowed to destroy it
|
||||
if (VALID_ENTITY(inst.mID) && !(inst.mFlags & ENF_LOCKED))
|
||||
{
|
||||
return; // Nothing to deallocate!
|
||||
inst.Destroy(destroy, header, payload); // Now attempt to destroy the entity from the server
|
||||
}
|
||||
// Prevent further attempts to delete this entity
|
||||
const BitGuardU16 bg(inst.mFlags, static_cast< Uint16 >(ENF_LOCKED));
|
||||
// Let the script callbacks know this entity should no longer be used
|
||||
try
|
||||
{
|
||||
EmitObjectDestroyed(id, header, payload);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// The error was probably dealt with already
|
||||
}
|
||||
// Is there a manager instance associated with this entity?
|
||||
if (inst.mInst)
|
||||
{
|
||||
// Prevent further use of this entity
|
||||
inst.mInst->m_ID = -1;
|
||||
// Release user data to avoid dangling or circular references
|
||||
inst.mInst->m_Data.Release();
|
||||
}
|
||||
// Should we delete this entity from the server as well?
|
||||
if (destroy || (inst.mFlags & ENF_OWNED))
|
||||
{
|
||||
_Func->DeleteObject(inst.mID);
|
||||
}
|
||||
// Reset the entity instance
|
||||
ResetInst(inst);
|
||||
// Release associated script callbacks
|
||||
ResetFunc(inst);
|
||||
// Prevent further use of the manager instance
|
||||
inst.mInst = nullptr;
|
||||
// Release the script object, if any
|
||||
inst.mObj.Release();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
@ -592,43 +464,11 @@ void Core::DeallocPickup(Int32 id, bool destroy, Int32 header, Object & payload)
|
||||
}
|
||||
// Retrieve the specified entity instance
|
||||
PickupInst & inst = m_Pickups[id];
|
||||
// Make sure that the instance is even allocated
|
||||
if (INVALID_ENTITY(inst.mID) || (inst.mFlags & ENF_LOCKED))
|
||||
// Make sure that the instance is even allocated and we are allowed to destroy it
|
||||
if (VALID_ENTITY(inst.mID) && !(inst.mFlags & ENF_LOCKED))
|
||||
{
|
||||
return; // Nothing to deallocate!
|
||||
inst.Destroy(destroy, header, payload); // Now attempt to destroy the entity from the server
|
||||
}
|
||||
// Prevent further attempts to delete this entity
|
||||
const BitGuardU16 bg(inst.mFlags, static_cast< Uint16 >(ENF_LOCKED));
|
||||
// Let the script callbacks know this entity should no longer be used
|
||||
try
|
||||
{
|
||||
EmitPickupDestroyed(id, header, payload);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// The error was probably dealt with already
|
||||
}
|
||||
// Is there a manager instance associated with this entity?
|
||||
if (inst.mInst)
|
||||
{
|
||||
// Prevent further use of this entity
|
||||
inst.mInst->m_ID = -1;
|
||||
// Release user data to avoid dangling or circular references
|
||||
inst.mInst->m_Data.Release();
|
||||
}
|
||||
// Should we delete this entity from the server as well?
|
||||
if (destroy || (inst.mFlags & ENF_OWNED))
|
||||
{
|
||||
_Func->DeletePickup(inst.mID);
|
||||
}
|
||||
// Reset the entity instance
|
||||
ResetInst(inst);
|
||||
// Release associated script callbacks
|
||||
ResetFunc(inst);
|
||||
// Prevent further use of the manager instance
|
||||
inst.mInst = nullptr;
|
||||
// Release the script object, if any
|
||||
inst.mObj.Release();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
@ -641,43 +481,11 @@ void Core::DeallocVehicle(Int32 id, bool destroy, Int32 header, Object & payload
|
||||
}
|
||||
// Retrieve the specified entity instance
|
||||
VehicleInst & inst = m_Vehicles[id];
|
||||
// Make sure that the instance is even allocated
|
||||
if (INVALID_ENTITY(inst.mID) || (inst.mFlags & ENF_LOCKED))
|
||||
// Make sure that the instance is even allocated and we are allowed to destroy it
|
||||
if (VALID_ENTITY(inst.mID) && !(inst.mFlags & ENF_LOCKED))
|
||||
{
|
||||
return; // Nothing to deallocate!
|
||||
inst.Destroy(destroy, header, payload); // Now attempt to destroy the entity from the server
|
||||
}
|
||||
// Prevent further attempts to delete this entity
|
||||
const BitGuardU16 bg(inst.mFlags, static_cast< Uint16 >(ENF_LOCKED));
|
||||
// Let the script callbacks know this entity should no longer be used
|
||||
try
|
||||
{
|
||||
EmitVehicleDestroyed(id, header, payload);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// The error was probably dealt with already
|
||||
}
|
||||
// Is there a manager instance associated with this entity?
|
||||
if (inst.mInst)
|
||||
{
|
||||
// Prevent further use of this entity
|
||||
inst.mInst->m_ID = -1;
|
||||
// Release user data to avoid dangling or circular references
|
||||
inst.mInst->m_Data.Release();
|
||||
}
|
||||
// Should we delete this entity from the server as well?
|
||||
if (destroy || (inst.mFlags & ENF_OWNED))
|
||||
{
|
||||
_Func->DeleteVehicle(inst.mID);
|
||||
}
|
||||
// Reset the entity instance
|
||||
ResetInst(inst);
|
||||
// Release associated script callbacks
|
||||
ResetFunc(inst);
|
||||
// Prevent further use of the manager instance
|
||||
inst.mInst = nullptr;
|
||||
// Release the script object, if any
|
||||
inst.mObj.Release();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
@ -914,7 +722,7 @@ bool Core::DelVehicle(Int32 id, Int32 header, Object & payload)
|
||||
return true;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Core::ConnectPlayer(Int32 id, Int32 header, Object & payload)
|
||||
{
|
||||
// Make sure that the specified entity identifier is valid
|
||||
@ -952,6 +760,7 @@ void Core::ConnectPlayer(Int32 id, Int32 header, Object & payload)
|
||||
EmitPlayerCreated(id, header, payload);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Core::DisconnectPlayer(Int32 id, Int32 header, Object & payload)
|
||||
{
|
||||
// Make sure that the specified entity identifier is valid
|
||||
@ -961,40 +770,11 @@ void Core::DisconnectPlayer(Int32 id, Int32 header, Object & payload)
|
||||
}
|
||||
// Retrieve the specified entity instance
|
||||
PlayerInst & inst = m_Players[id];
|
||||
// Make sure that the instance is even allocated and we're allowed to deallocate it
|
||||
if (INVALID_ENTITY(inst.mID) || (inst.mFlags & ENF_LOCKED))
|
||||
// Make sure that the instance is even allocated and we are allowed to destroy it
|
||||
if (VALID_ENTITY(inst.mID) && !(inst.mFlags & ENF_LOCKED))
|
||||
{
|
||||
return; // Nothing to deallocate!
|
||||
inst.Destroy(false, header, payload); // Now attempt to destroy the entity from the server
|
||||
}
|
||||
// Prevent further attempts to delete this entity
|
||||
const BitGuardU16 bg(inst.mFlags, static_cast< Uint16 >(ENF_LOCKED));
|
||||
// Let the script callbacks know this entity should no longer be used
|
||||
try
|
||||
{
|
||||
EmitPlayerDestroyed(id, header, payload);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// The error was probably dealt with already
|
||||
}
|
||||
// Is there a manager instance associated with this entity?
|
||||
if (inst.mInst)
|
||||
{
|
||||
// Prevent further use of this entity
|
||||
inst.mInst->m_ID = -1;
|
||||
// Release user data to avoid dangling or circular references
|
||||
inst.mInst->m_Data.Release();
|
||||
// Release the used memory buffer
|
||||
inst.mInst->m_Buffer.ResetAll();
|
||||
}
|
||||
// Reset the entity instance
|
||||
ResetInst(inst);
|
||||
// Release associated script callbacks
|
||||
ResetFunc(inst);
|
||||
// Prevent further use of the manager instance
|
||||
inst.mInst = nullptr;
|
||||
// Release the script object, if any
|
||||
inst.mObj.Release();
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
@ -4,6 +4,43 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Core::ClearContainer(EntityType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ENT_BLIP:
|
||||
{
|
||||
m_Blips.clear();
|
||||
} break;
|
||||
case ENT_CHECKPOINT:
|
||||
{
|
||||
m_Checkpoints.clear();
|
||||
} break;
|
||||
case ENT_KEYBIND:
|
||||
{
|
||||
m_Keybinds.clear();
|
||||
} break;
|
||||
case ENT_OBJECT:
|
||||
{
|
||||
m_Objects.clear();
|
||||
} break;
|
||||
case ENT_PICKUP:
|
||||
{
|
||||
m_Pickups.clear();
|
||||
} break;
|
||||
case ENT_PLAYER:
|
||||
{
|
||||
m_Players.clear();
|
||||
} break;
|
||||
case ENT_VEHICLE:
|
||||
{
|
||||
m_Vehicles.clear();
|
||||
} break;
|
||||
default: STHROWF("Cannot clear unknown entity type container");
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Core::ResetInst(BlipInst & inst)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user