1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-02-21 20:27:13 +01:00

Improve searching for active entities. Also fix a possible crash because the entity instance pushed on the stack was appending to itself instead of the array.

This commit is contained in:
Sandu Liviu Catalin 2016-06-21 09:02:44 +03:00
parent 22fc6c54c2
commit 1d12ddd60d
10 changed files with 109 additions and 91 deletions

View File

@ -437,6 +437,8 @@
<Unit filename="../shared/Base/Utility.hpp" /> <Unit filename="../shared/Base/Utility.hpp" />
<Unit filename="../source/Base/AABB.cpp" /> <Unit filename="../source/Base/AABB.cpp" />
<Unit filename="../source/Base/AABB.hpp" /> <Unit filename="../source/Base/AABB.hpp" />
<Unit filename="../source/Base/Algo.cpp" />
<Unit filename="../source/Base/Algo.hpp" />
<Unit filename="../source/Base/Circle.cpp" /> <Unit filename="../source/Base/Circle.cpp" />
<Unit filename="../source/Base/Circle.hpp" /> <Unit filename="../source/Base/Circle.hpp" />
<Unit filename="../source/Base/Color3.cpp" /> <Unit filename="../source/Base/Color3.cpp" />

8
source/Base/Algo.cpp Normal file
View File

@ -0,0 +1,8 @@
// ------------------------------------------------------------------------------------------------
#include "Base/Algo.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
} // Namespace:: SqMod

29
source/Base/Algo.hpp Normal file
View File

@ -0,0 +1,29 @@
#ifndef _BASE_ALGO_HPP_
#define _BASE_ALGO_HPP_
// ------------------------------------------------------------------------------------------------
#include <SqBase.hpp>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
namespace Algo {
/* ------------------------------------------------------------------------------------------------
* Collect all elements within the specified range that the inspector deems worthy.
*/
template < typename Iterator, typename Inspector, typename Collector >
void Collect(Iterator first, Iterator last, Inspector inspect, Collector collect)
{
for (; first != last; ++first)
{
if (inspect(*first))
{
collect(*first);
}
}
}
} // Namespace:: Algo
} // Namespace:: SqMod
#endif // _BASE_ALGO_HPP_

View File

@ -1,5 +1,6 @@
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#include "Entity/Blip.hpp" #include "Entity/Blip.hpp"
#include "Base/Algo.hpp"
#include "Core.hpp" #include "Core.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -358,28 +359,24 @@ static const Object & Blip_FindBySprID(Int32 sprid)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static Array Blip_FindActive() static Array Blip_FindActive()
{ {
// Remember the initial stack size const StackGuard sg;
StackGuard sg;
// Obtain the ends of the entity pool
Core::Blips::const_iterator itr = Core::Get().GetBlips().cbegin();
Core::Blips::const_iterator end = Core::Get().GetBlips().cend();
// Allocate an empty array on the stack // Allocate an empty array on the stack
sq_newarray(DefaultVM::Get(), 0); sq_newarray(DefaultVM::Get(), 0);
// Process each entity in the pool // Process each entity in the pool
for (; itr != end; ++itr) Algo::Collect(Core::Get().GetBlips().cbegin(), Core::Get().GetBlips().cend(),
{ [](Core::Blips::const_reference inst) -> bool {
// Is this entity instance active? return VALID_ENTITY(inst.mID);
if (VALID_ENTITY(itr->mID)) },
{ [](Core::Blips::const_reference inst) -> void {
// Push the script object on the stack // Push the script object on the stack
sq_pushobject(DefaultVM::Get(), (HSQOBJECT &)((*itr).mObj)); sq_pushobject(DefaultVM::Get(), inst.mObj.GetObject());
// Append the object at the back of the array // Append the object at the back of the array
if (SQ_FAILED(sq_arrayappend(DefaultVM::Get(), -1))) if (SQ_FAILED(sq_arrayappend(DefaultVM::Get(), -2)))
{ {
STHROWF("Unable to append entity instance to the list"); STHROWF("Unable to append entity instance to the list");
} }
} }
} );
// Return the array at the top of the stack // Return the array at the top of the stack
return Var< Array >(DefaultVM::Get(), -1).value; return Var< Array >(DefaultVM::Get(), -1).value;
} }

View File

@ -1,6 +1,7 @@
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#include "Entity/Checkpoint.hpp" #include "Entity/Checkpoint.hpp"
#include "Entity/Player.hpp" #include "Entity/Player.hpp"
#include "Base/Algo.hpp"
#include "Base/Color4.hpp" #include "Base/Color4.hpp"
#include "Base/Vector3.hpp" #include "Base/Vector3.hpp"
#include "Core.hpp" #include "Core.hpp"
@ -532,28 +533,24 @@ static const Object & Checkpoint_FindByTag(CSStr tag)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static Array Checkpoint_FindActive() static Array Checkpoint_FindActive()
{ {
// Remember the initial stack size const StackGuard sg;
StackGuard sg;
// Obtain the ends of the entity pool
Core::Checkpoints::const_iterator itr = Core::Get().GetCheckpoints().cbegin();
Core::Checkpoints::const_iterator end = Core::Get().GetCheckpoints().cend();
// Allocate an empty array on the stack // Allocate an empty array on the stack
sq_newarray(DefaultVM::Get(), 0); sq_newarray(DefaultVM::Get(), 0);
// Process each entity in the pool // Process each entity in the pool
for (; itr != end; ++itr) Algo::Collect(Core::Get().GetCheckpoints().cbegin(), Core::Get().GetCheckpoints().cend(),
{ [](Core::Checkpoints::const_reference inst) -> bool {
// Is this entity instance active? return VALID_ENTITY(inst.mID);
if (VALID_ENTITY(itr->mID)) },
{ [](Core::Checkpoints::const_reference inst) -> void {
// Push the script object on the stack // Push the script object on the stack
sq_pushobject(DefaultVM::Get(), (HSQOBJECT &)((*itr).mObj)); sq_pushobject(DefaultVM::Get(), inst.mObj.GetObject());
// Append the object at the back of the array // Append the object at the back of the array
if (SQ_FAILED(sq_arrayappend(DefaultVM::Get(), -1))) if (SQ_FAILED(sq_arrayappend(DefaultVM::Get(), -2)))
{ {
STHROWF("Unable to append entity instance to the list"); STHROWF("Unable to append entity instance to the list");
} }
} }
} );
// Return the array at the top of the stack // Return the array at the top of the stack
return Var< Array >(DefaultVM::Get(), -1).value; return Var< Array >(DefaultVM::Get(), -1).value;
} }

View File

@ -1,5 +1,6 @@
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#include "Entity/Keybind.hpp" #include "Entity/Keybind.hpp"
#include "Base/Algo.hpp"
#include "Core.hpp" #include "Core.hpp"
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -230,28 +231,24 @@ static const Object & Keybind_FindByTag(CSStr tag)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static Array Keybind_FindActive() static Array Keybind_FindActive()
{ {
// Remember the initial stack size const StackGuard sg;
StackGuard sg;
// Obtain the ends of the entity pool
Core::Keybinds::const_iterator itr = Core::Get().GetKeybinds().cbegin();
Core::Keybinds::const_iterator end = Core::Get().GetKeybinds().cend();
// Allocate an empty array on the stack // Allocate an empty array on the stack
sq_newarray(DefaultVM::Get(), 0); sq_newarray(DefaultVM::Get(), 0);
// Process each entity in the pool // Process each entity in the pool
for (; itr != end; ++itr) Algo::Collect(Core::Get().GetKeybinds().cbegin(), Core::Get().GetKeybinds().cend(),
{ [](Core::Keybinds::const_reference inst) -> bool {
// Is this entity instance active? return VALID_ENTITY(inst.mID);
if (VALID_ENTITY(itr->mID)) },
{ [](Core::Keybinds::const_reference inst) -> void {
// Push the script object on the stack // Push the script object on the stack
sq_pushobject(DefaultVM::Get(), (HSQOBJECT &)((*itr).mObj)); sq_pushobject(DefaultVM::Get(), inst.mObj.GetObject());
// Append the object at the back of the array // Append the object at the back of the array
if (SQ_FAILED(sq_arrayappend(DefaultVM::Get(), -1))) if (SQ_FAILED(sq_arrayappend(DefaultVM::Get(), -2)))
{ {
STHROWF("Unable to append entity instance to the list"); STHROWF("Unable to append entity instance to the list");
} }
} }
} );
// Return the array at the top of the stack // Return the array at the top of the stack
return Var< Array >(DefaultVM::Get(), -1).value; return Var< Array >(DefaultVM::Get(), -1).value;
} }

View File

@ -1,6 +1,7 @@
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#include "Entity/Object.hpp" #include "Entity/Object.hpp"
#include "Entity/Player.hpp" #include "Entity/Player.hpp"
#include "Base/Algo.hpp"
#include "Base/Quaternion.hpp" #include "Base/Quaternion.hpp"
#include "Base/Vector3.hpp" #include "Base/Vector3.hpp"
#include "Core.hpp" #include "Core.hpp"
@ -856,28 +857,24 @@ static const Object & Object_FindByTag(CSStr tag)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static Array Object_FindActive() static Array Object_FindActive()
{ {
// Remember the initial stack size const StackGuard sg;
StackGuard sg;
// Obtain the ends of the entity pool
Core::Objects::const_iterator itr = Core::Get().GetObjects().cbegin();
Core::Objects::const_iterator end = Core::Get().GetObjects().cend();
// Allocate an empty array on the stack // Allocate an empty array on the stack
sq_newarray(DefaultVM::Get(), 0); sq_newarray(DefaultVM::Get(), 0);
// Process each entity in the pool // Process each entity in the pool
for (; itr != end; ++itr) Algo::Collect(Core::Get().GetObjects().cbegin(), Core::Get().GetObjects().cend(),
{ [](Core::Objects::const_reference inst) -> bool {
// Is this entity instance active? return VALID_ENTITY(inst.mID);
if (VALID_ENTITY(itr->mID)) },
{ [](Core::Objects::const_reference inst) -> void {
// Push the script object on the stack // Push the script object on the stack
sq_pushobject(DefaultVM::Get(), (HSQOBJECT &)((*itr).mObj)); sq_pushobject(DefaultVM::Get(), inst.mObj.GetObject());
// Append the object at the back of the array // Append the object at the back of the array
if (SQ_FAILED(sq_arrayappend(DefaultVM::Get(), -1))) if (SQ_FAILED(sq_arrayappend(DefaultVM::Get(), -2)))
{ {
STHROWF("Unable to append entity instance to the list"); STHROWF("Unable to append entity instance to the list");
} }
} }
} );
// Return the array at the top of the stack // Return the array at the top of the stack
return Var< Array >(DefaultVM::Get(), -1).value; return Var< Array >(DefaultVM::Get(), -1).value;
} }

View File

@ -1,6 +1,7 @@
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#include "Entity/Pickup.hpp" #include "Entity/Pickup.hpp"
#include "Entity/Player.hpp" #include "Entity/Player.hpp"
#include "Base/Algo.hpp"
#include "Base/Vector3.hpp" #include "Base/Vector3.hpp"
#include "Core.hpp" #include "Core.hpp"
@ -418,28 +419,24 @@ static const Object & Pickup_FindByTag(CSStr tag)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static Array Pickup_FindActive() static Array Pickup_FindActive()
{ {
// Remember the initial stack size const StackGuard sg;
StackGuard sg;
// Obtain the ends of the entity pool
Core::Pickups::const_iterator itr = Core::Get().GetPickups().cbegin();
Core::Pickups::const_iterator end = Core::Get().GetPickups().cend();
// Allocate an empty array on the stack // Allocate an empty array on the stack
sq_newarray(DefaultVM::Get(), 0); sq_newarray(DefaultVM::Get(), 0);
// Process each entity in the pool // Process each entity in the pool
for (; itr != end; ++itr) Algo::Collect(Core::Get().GetPickups().cbegin(), Core::Get().GetPickups().cend(),
{ [](Core::Pickups::const_reference inst) -> bool {
// Is this entity instance active? return VALID_ENTITY(inst.mID);
if (VALID_ENTITY(itr->mID)) },
{ [](Core::Pickups::const_reference inst) -> void {
// Push the script object on the stack // Push the script object on the stack
sq_pushobject(DefaultVM::Get(), (HSQOBJECT &)((*itr).mObj)); sq_pushobject(DefaultVM::Get(), inst.mObj.GetObject());
// Append the object at the back of the array // Append the object at the back of the array
if (SQ_FAILED(sq_arrayappend(DefaultVM::Get(), -1))) if (SQ_FAILED(sq_arrayappend(DefaultVM::Get(), -2)))
{ {
STHROWF("Unable to append entity instance to the list"); STHROWF("Unable to append entity instance to the list");
} }
} }
} );
// Return the array at the top of the stack // Return the array at the top of the stack
return Var< Array >(DefaultVM::Get(), -1).value; return Var< Array >(DefaultVM::Get(), -1).value;
} }

View File

@ -1,6 +1,7 @@
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#include "Entity/Player.hpp" #include "Entity/Player.hpp"
#include "Entity/Vehicle.hpp" #include "Entity/Vehicle.hpp"
#include "Base/Algo.hpp"
#include "Base/Color3.hpp" #include "Base/Color3.hpp"
#include "Base/Color4.hpp" #include "Base/Color4.hpp"
#include "Base/Vector3.hpp" #include "Base/Vector3.hpp"
@ -2112,28 +2113,24 @@ static const Object & Player_FindByTag(CSStr tag)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static Array Player_FindActive() static Array Player_FindActive()
{ {
// Remember the initial stack size const StackGuard sg;
StackGuard sg;
// Obtain the ends of the entity pool
Core::Players::const_iterator itr = Core::Get().GetPlayers().cbegin();
Core::Players::const_iterator end = Core::Get().GetPlayers().cend();
// Allocate an empty array on the stack // Allocate an empty array on the stack
sq_newarray(DefaultVM::Get(), 0); sq_newarray(DefaultVM::Get(), 0);
// Process each entity in the pool // Process each entity in the pool
for (; itr != end; ++itr) Algo::Collect(Core::Get().GetPlayers().cbegin(), Core::Get().GetPlayers().cend(),
{ [](Core::Players::const_reference inst) -> bool {
// Is this entity instance active? return VALID_ENTITY(inst.mID);
if (VALID_ENTITY(itr->mID)) },
{ [](Core::Players::const_reference inst) -> void {
// Push the script object on the stack // Push the script object on the stack
sq_pushobject(DefaultVM::Get(), (HSQOBJECT &)((*itr).mObj)); sq_pushobject(DefaultVM::Get(), inst.mObj.GetObject());
// Append the object at the back of the array // Append the object at the back of the array
if (SQ_FAILED(sq_arrayappend(DefaultVM::Get(), -1))) if (SQ_FAILED(sq_arrayappend(DefaultVM::Get(), -2)))
{ {
STHROWF("Unable to append entity instance to the list"); STHROWF("Unable to append entity instance to the list");
} }
} }
} );
// Return the array at the top of the stack // Return the array at the top of the stack
return Var< Array >(DefaultVM::Get(), -1).value; return Var< Array >(DefaultVM::Get(), -1).value;
} }

View File

@ -1,6 +1,7 @@
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#include "Entity/Vehicle.hpp" #include "Entity/Vehicle.hpp"
#include "Entity/Player.hpp" #include "Entity/Player.hpp"
#include "Base/Algo.hpp"
#include "Base/Quaternion.hpp" #include "Base/Quaternion.hpp"
#include "Base/Vector2.hpp" #include "Base/Vector2.hpp"
#include "Base/Vector3.hpp" #include "Base/Vector3.hpp"
@ -1675,28 +1676,24 @@ static const Object & Vehicle_FindByTag(CSStr tag)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static Array Vehicle_FindActive() static Array Vehicle_FindActive()
{ {
// Remember the initial stack size const StackGuard sg;
StackGuard sg;
// Obtain the ends of the entity pool
Core::Vehicles::const_iterator itr = Core::Get().GetVehicles().cbegin();
Core::Vehicles::const_iterator end = Core::Get().GetVehicles().cend();
// Allocate an empty array on the stack // Allocate an empty array on the stack
sq_newarray(DefaultVM::Get(), 0); sq_newarray(DefaultVM::Get(), 0);
// Process each entity in the pool // Process each entity in the pool
for (; itr != end; ++itr) Algo::Collect(Core::Get().GetVehicles().cbegin(), Core::Get().GetVehicles().cend(),
{ [](Core::Vehicles::const_reference inst) -> bool {
// Is this entity instance active? return VALID_ENTITY(inst.mID);
if (VALID_ENTITY(itr->mID)) },
{ [](Core::Vehicles::const_reference inst) -> void {
// Push the script object on the stack // Push the script object on the stack
sq_pushobject(DefaultVM::Get(), (HSQOBJECT &)((*itr).mObj)); sq_pushobject(DefaultVM::Get(), inst.mObj.GetObject());
// Append the object at the back of the array // Append the object at the back of the array
if (SQ_FAILED(sq_arrayappend(DefaultVM::Get(), -1))) if (SQ_FAILED(sq_arrayappend(DefaultVM::Get(), -2)))
{ {
STHROWF("Unable to append entity instance to the list"); STHROWF("Unable to append entity instance to the list");
} }
} }
} );
// Return the array at the top of the stack // Return the array at the top of the stack
return Var< Array >(DefaultVM::Get(), -1).value; return Var< Array >(DefaultVM::Get(), -1).value;
} }