1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2024-11-08 16:57:16 +01:00
SqMod/source/Tasks.hpp

301 lines
11 KiB
C++
Raw Normal View History

#ifndef _TASKS_HPP_
#define _TASKS_HPP_
// ------------------------------------------------------------------------------------------------
#include "Base/Shared.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Execute callbacks for specific entities after specific intervals of time.
*/
class Tasks
{
public:
/* --------------------------------------------------------------------------------------------
* Simplify future changes to a single point of change.
*/
typedef Int64 Time;
typedef SQInteger Interval;
typedef Uint32 Iterator;
typedef LightObject Argument;
private:
/* --------------------------------------------------------------------------------------------
* Structure that represents a task and keeps track of the task information.
*/
struct Task
{
// ----------------------------------------------------------------------------------------
SQHash mHash; // The hash of the referenced function object.
HSQOBJECT mEnv; // A reference to the managed environment object.
HSQOBJECT mFunc; // A reference to the managed function object.
Iterator mIterations; // Number of iterations before self destruct.
Interval mInterval; // Interval between task invocations.
Int16 mEntity; // The identifier of the entity to which is belongs.
Uint8 mType; // The type of the entity to which is belongs.
Uint8 mArgc; // The number of arguments that the task must forward.
Argument mArgv[14]; // The arguments that the task must forward.
/* ----------------------------------------------------------------------------------------
* Default constructor.
*/
Task()
: mHash(0)
, mEnv()
, mFunc()
, mIterations(0)
, mInterval(0)
, mEntity(-1)
, mType(-1)
, mArgc(0)
, mArgv()
{
sq_resetobject(&mEnv);
sq_resetobject(&mFunc);
}
/* ----------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
Task(const Task & o) = delete;
/* ----------------------------------------------------------------------------------------
* Move constructor. (disabled)
*/
Task(Task && o) = delete;
/* ----------------------------------------------------------------------------------------
* Release managed script resources.
*/
~Task()
{
Release();
Clear();
}
/* ----------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
Task & operator = (const Task & o) = delete;
/* ----------------------------------------------------------------------------------------
* Move assignment operator. (disabled)
*/
Task & operator = (Task && o) = delete;
/* ----------------------------------------------------------------------------------------
* Initializes the task parameters. (assumes previous values are already released)
*/
void Init(HSQOBJECT & env, HSQOBJECT & func, Interval intrv, Iterator itr, Int32 id, Int32 type);
/* ----------------------------------------------------------------------------------------
* Clear the arguments.
*/
void Clear()
{
// Now release the arguments
for (auto & a : mArgv)
{
a.Release();
}
// Reset the counter
mArgc = 0;
}
/* ----------------------------------------------------------------------------------------
* Release managed script resources.
*/
void Release();
/* ----------------------------------------------------------------------------------------
* Execute the managed task.
*/
Interval Execute();
};
// --------------------------------------------------------------------------------------------
static Uint32 s_Used; // The number of occupied slots.
static Time s_Last; // Last time point.
static Time s_Prev; // Previous time point.
static Interval s_Intervals[SQMOD_MAX_TASKS]; // List of intervals to be processed.
static Task s_Tasks[SQMOD_MAX_TASKS]; // List of tasks to be executed.
/* --------------------------------------------------------------------------------------------
* Default constructor. (disabled)
*/
Tasks() = delete;
/* --------------------------------------------------------------------------------------------
* Copy constructor. (disabled)
*/
Tasks(const Tasks & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor. (disabled)
*/
Tasks(Tasks && o) = delete;
/* --------------------------------------------------------------------------------------------
* Destructor. (disabled)
*/
~Tasks() = delete;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator. (disabled)
*/
Tasks & operator = (const Tasks & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator. (disabled)
*/
Tasks & operator = (Tasks && o) = delete;
public:
/* --------------------------------------------------------------------------------------------
* Process all active tasks and update elapsed time.
*/
static void Process();
/* --------------------------------------------------------------------------------------------
* Initialize all resources and prepare for startup.
*/
static void Initialize();
/* --------------------------------------------------------------------------------------------
* Release all resources and prepare for shutdown.
*/
static void Deinitialize();
protected:
/* --------------------------------------------------------------------------------------------
* Retrieve the instance of the specified entity.
*/
static Object & FindEntity(Int32 id, Int32 type);
/* --------------------------------------------------------------------------------------------
* Find an unoccupied task slot.
*/
static SQInteger FindUnused();
/* --------------------------------------------------------------------------------------------
* Locate the first task with the specified parameters.
*/
static SQInteger Find(Int32 id, Int32 type, SQInteger & pos, HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* Attempt to create a task with the specified parameters.
*/
static SQInteger Create(Int32 id, Int32 type, HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* Attempt to remove the task with the specified parameters.
*/
static SQInteger Remove(Int32 id, Int32 type, HSQUIRRELVM vm);
/* --------------------------------------------------------------------------------------------
* See if a task with the specified parameters exists.
*/
static SQInteger Exists(Int32 id, Int32 type, HSQUIRRELVM vm);
public:
/* --------------------------------------------------------------------------------------------
* Cleanup all tasks associated with the specified entity.
*/
static void Cleanup(Int32 id, Int32 type);
/* --------------------------------------------------------------------------------------------
* Forwards calls to create tasks.
*/
template < typename Entity, Int32 Type > static SQInteger MakeTask(HSQUIRRELVM vm)
{
// The entity instance
const Entity * inst = nullptr;
// Attempt to extract the instance
try
{
// Fetch the instance from the stack
inst = Var< const Entity * >(vm, 1).value;
// Do we have a valid instance?
if (!inst)
{
STHROWF("Invalid entity instance");
}
// Validate the actual entity instance
inst->Validate();
}
catch (const Sqrat::Exception & e)
{
return sq_throwerror(vm, e.what());
}
// Forward the call and return the result
return Create(inst->GetID(), Type, vm);
}
/* --------------------------------------------------------------------------------------------
* Forwards calls to remove tasks.
*/
template < typename Entity, Int32 Type > static SQInteger DropTask(HSQUIRRELVM vm)
{
// The entity instance
const Entity * inst = nullptr;
// Attempt to extract the instance
try
{
// Fetch the instance from the stack
inst = Var< const Entity * >(vm, 1).value;
// Do we have a valid instance?
if (!inst)
{
STHROWF("Invalid entity instance");
}
// Validate the actual entity instance
inst->Validate();
}
catch (const Sqrat::Exception & e)
{
return sq_throwerror(vm, e.what());
}
// Forward the call and return the result
return Remove(inst->GetID(), Type, vm);
}
/* --------------------------------------------------------------------------------------------
* Forwards calls to check tasks.
*/
template < typename Entity, Int32 Type > static SQInteger DoesTask(HSQUIRRELVM vm)
{
// The entity instance
const Entity * inst = nullptr;
// Attempt to extract the instance
try
{
// Fetch the instance from the stack
inst = Var< const Entity * >(vm, 1).value;
// Do we have a valid instance?
if (!inst)
{
STHROWF("Invalid entity instance");
}
// Validate the actual entity instance
inst->Validate();
}
catch (const Sqrat::Exception & e)
{
return sq_throwerror(vm, e.what());
}
// Forward the call and return the result
return Exists(inst->GetID(), Type, vm);
}
};
} // Namespace:: SqMod
#endif // _TASKS_HPP_