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="../source/Base/AABB.cpp" />
<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.hpp" />
<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 "Base/Algo.hpp"
#include "Core.hpp"
// ------------------------------------------------------------------------------------------------
@ -358,28 +359,24 @@ static const Object & Blip_FindBySprID(Int32 sprid)
// ------------------------------------------------------------------------------------------------
static Array Blip_FindActive()
{
// Remember the initial stack size
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();
const StackGuard sg;
// Allocate an empty array on the stack
sq_newarray(DefaultVM::Get(), 0);
// Process each entity in the pool
for (; itr != end; ++itr)
{
// Is this entity instance active?
if (VALID_ENTITY(itr->mID))
{
Algo::Collect(Core::Get().GetBlips().cbegin(), Core::Get().GetBlips().cend(),
[](Core::Blips::const_reference inst) -> bool {
return VALID_ENTITY(inst.mID);
},
[](Core::Blips::const_reference inst) -> void {
// 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
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");
}
}
}
);
// Return the array at the top of the stack
return Var< Array >(DefaultVM::Get(), -1).value;
}

View File

@ -1,6 +1,7 @@
// ------------------------------------------------------------------------------------------------
#include "Entity/Checkpoint.hpp"
#include "Entity/Player.hpp"
#include "Base/Algo.hpp"
#include "Base/Color4.hpp"
#include "Base/Vector3.hpp"
#include "Core.hpp"
@ -532,28 +533,24 @@ static const Object & Checkpoint_FindByTag(CSStr tag)
// ------------------------------------------------------------------------------------------------
static Array Checkpoint_FindActive()
{
// Remember the initial stack size
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();
const StackGuard sg;
// Allocate an empty array on the stack
sq_newarray(DefaultVM::Get(), 0);
// Process each entity in the pool
for (; itr != end; ++itr)
{
// Is this entity instance active?
if (VALID_ENTITY(itr->mID))
{
Algo::Collect(Core::Get().GetCheckpoints().cbegin(), Core::Get().GetCheckpoints().cend(),
[](Core::Checkpoints::const_reference inst) -> bool {
return VALID_ENTITY(inst.mID);
},
[](Core::Checkpoints::const_reference inst) -> void {
// 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
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");
}
}
}
);
// Return the array at the top of the stack
return Var< Array >(DefaultVM::Get(), -1).value;
}

View File

@ -1,5 +1,6 @@
// ------------------------------------------------------------------------------------------------
#include "Entity/Keybind.hpp"
#include "Base/Algo.hpp"
#include "Core.hpp"
// ------------------------------------------------------------------------------------------------
@ -230,28 +231,24 @@ static const Object & Keybind_FindByTag(CSStr tag)
// ------------------------------------------------------------------------------------------------
static Array Keybind_FindActive()
{
// Remember the initial stack size
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();
const StackGuard sg;
// Allocate an empty array on the stack
sq_newarray(DefaultVM::Get(), 0);
// Process each entity in the pool
for (; itr != end; ++itr)
{
// Is this entity instance active?
if (VALID_ENTITY(itr->mID))
{
Algo::Collect(Core::Get().GetKeybinds().cbegin(), Core::Get().GetKeybinds().cend(),
[](Core::Keybinds::const_reference inst) -> bool {
return VALID_ENTITY(inst.mID);
},
[](Core::Keybinds::const_reference inst) -> void {
// 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
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");
}
}
}
);
// Return the array at the top of the stack
return Var< Array >(DefaultVM::Get(), -1).value;
}

View File

@ -1,6 +1,7 @@
// ------------------------------------------------------------------------------------------------
#include "Entity/Object.hpp"
#include "Entity/Player.hpp"
#include "Base/Algo.hpp"
#include "Base/Quaternion.hpp"
#include "Base/Vector3.hpp"
#include "Core.hpp"
@ -856,28 +857,24 @@ static const Object & Object_FindByTag(CSStr tag)
// ------------------------------------------------------------------------------------------------
static Array Object_FindActive()
{
// Remember the initial stack size
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();
const StackGuard sg;
// Allocate an empty array on the stack
sq_newarray(DefaultVM::Get(), 0);
// Process each entity in the pool
for (; itr != end; ++itr)
{
// Is this entity instance active?
if (VALID_ENTITY(itr->mID))
{
Algo::Collect(Core::Get().GetObjects().cbegin(), Core::Get().GetObjects().cend(),
[](Core::Objects::const_reference inst) -> bool {
return VALID_ENTITY(inst.mID);
},
[](Core::Objects::const_reference inst) -> void {
// 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
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");
}
}
}
);
// Return the array at the top of the stack
return Var< Array >(DefaultVM::Get(), -1).value;
}

View File

@ -1,6 +1,7 @@
// ------------------------------------------------------------------------------------------------
#include "Entity/Pickup.hpp"
#include "Entity/Player.hpp"
#include "Base/Algo.hpp"
#include "Base/Vector3.hpp"
#include "Core.hpp"
@ -418,28 +419,24 @@ static const Object & Pickup_FindByTag(CSStr tag)
// ------------------------------------------------------------------------------------------------
static Array Pickup_FindActive()
{
// Remember the initial stack size
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();
const StackGuard sg;
// Allocate an empty array on the stack
sq_newarray(DefaultVM::Get(), 0);
// Process each entity in the pool
for (; itr != end; ++itr)
{
// Is this entity instance active?
if (VALID_ENTITY(itr->mID))
{
Algo::Collect(Core::Get().GetPickups().cbegin(), Core::Get().GetPickups().cend(),
[](Core::Pickups::const_reference inst) -> bool {
return VALID_ENTITY(inst.mID);
},
[](Core::Pickups::const_reference inst) -> void {
// 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
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");
}
}
}
);
// Return the array at the top of the stack
return Var< Array >(DefaultVM::Get(), -1).value;
}

View File

@ -1,6 +1,7 @@
// ------------------------------------------------------------------------------------------------
#include "Entity/Player.hpp"
#include "Entity/Vehicle.hpp"
#include "Base/Algo.hpp"
#include "Base/Color3.hpp"
#include "Base/Color4.hpp"
#include "Base/Vector3.hpp"
@ -2112,28 +2113,24 @@ static const Object & Player_FindByTag(CSStr tag)
// ------------------------------------------------------------------------------------------------
static Array Player_FindActive()
{
// Remember the initial stack size
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();
const StackGuard sg;
// Allocate an empty array on the stack
sq_newarray(DefaultVM::Get(), 0);
// Process each entity in the pool
for (; itr != end; ++itr)
{
// Is this entity instance active?
if (VALID_ENTITY(itr->mID))
{
Algo::Collect(Core::Get().GetPlayers().cbegin(), Core::Get().GetPlayers().cend(),
[](Core::Players::const_reference inst) -> bool {
return VALID_ENTITY(inst.mID);
},
[](Core::Players::const_reference inst) -> void {
// 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
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");
}
}
}
);
// Return the array at the top of the stack
return Var< Array >(DefaultVM::Get(), -1).value;
}

View File

@ -1,6 +1,7 @@
// ------------------------------------------------------------------------------------------------
#include "Entity/Vehicle.hpp"
#include "Entity/Player.hpp"
#include "Base/Algo.hpp"
#include "Base/Quaternion.hpp"
#include "Base/Vector2.hpp"
#include "Base/Vector3.hpp"
@ -1675,28 +1676,24 @@ static const Object & Vehicle_FindByTag(CSStr tag)
// ------------------------------------------------------------------------------------------------
static Array Vehicle_FindActive()
{
// Remember the initial stack size
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();
const StackGuard sg;
// Allocate an empty array on the stack
sq_newarray(DefaultVM::Get(), 0);
// Process each entity in the pool
for (; itr != end; ++itr)
{
// Is this entity instance active?
if (VALID_ENTITY(itr->mID))
{
Algo::Collect(Core::Get().GetVehicles().cbegin(), Core::Get().GetVehicles().cend(),
[](Core::Vehicles::const_reference inst) -> bool {
return VALID_ENTITY(inst.mID);
},
[](Core::Vehicles::const_reference inst) -> void {
// 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
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");
}
}
}
);
// Return the array at the top of the stack
return Var< Array >(DefaultVM::Get(), -1).value;
}