mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 00:37:15 +01:00
Implemented a mechanism for tasks to alter their properties and/or terminate themselves in the middle of the execution.
Also implemented a few other features such as the ability to have a persistent storage associated with them.
This commit is contained in:
parent
5b32baa908
commit
a04fd3ba15
@ -58,6 +58,7 @@ void Tasks::Task::Release()
|
||||
mHash = 0;
|
||||
mFunc.Release();
|
||||
mInst.Release();
|
||||
mData.Release();
|
||||
mIterations = 0;
|
||||
mInterval = 0;
|
||||
mEntity = -1;
|
||||
@ -89,15 +90,13 @@ Tasks::Interval Tasks::Task::Execute()
|
||||
if (SQ_FAILED(res))
|
||||
{
|
||||
// Destroy ourself on error
|
||||
Release();
|
||||
Clear();
|
||||
Terminate();
|
||||
}
|
||||
// Decrease the number of iterations if necessary
|
||||
if (mIterations && (--mIterations) == 0)
|
||||
{
|
||||
// This routine reached the end of it's life
|
||||
Release();
|
||||
Clear();
|
||||
Terminate();
|
||||
}
|
||||
// Return the current interval
|
||||
return mInterval;
|
||||
@ -156,7 +155,19 @@ void Tasks::Register(HSQUIRRELVM vm)
|
||||
Class< Task, NoDestructor< Task > >(vm, Typename::Str)
|
||||
// Meta-methods
|
||||
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
|
||||
//.Func(_SC("_tostring"), &CBlip::ToString)
|
||||
.Func(_SC("_tostring"), &Task::ToString)
|
||||
// Properties
|
||||
.Prop(_SC("Self"), &Task::GetSelf)
|
||||
.Prop(_SC("Inst"), &Task::GetInst)
|
||||
.Prop(_SC("Func"), &Task::GetFunc, &Task::SetFunc)
|
||||
.Prop(_SC("Data"), &Task::GetData, &Task::SetData)
|
||||
.Prop(_SC("Interval"), &Task::GetInterval, &Task::SetInterval)
|
||||
.Prop(_SC("Iterations"), &Task::GetIterations, &Task::SetIterations)
|
||||
.Prop(_SC("Arguments"), &Task::GetArguments)
|
||||
.Prop(_SC("Entity"), &Task::GetInst)
|
||||
// Member Methods
|
||||
.Func(_SC("Terminate"), &Task::Terminate)
|
||||
.Func(_SC("GetArgument"), &Task::GetArgument)
|
||||
);
|
||||
}
|
||||
|
||||
@ -166,8 +177,7 @@ void Tasks::Deinitialize()
|
||||
// Release any script resources that the tasks might store
|
||||
for (auto & t : s_Tasks)
|
||||
{
|
||||
t.Release();
|
||||
t.Clear();
|
||||
t.Terminate();
|
||||
t.mSelf.Release();
|
||||
}
|
||||
}
|
||||
@ -416,8 +426,7 @@ SQInteger Tasks::Remove(Int32 id, Int32 type, HSQUIRRELVM vm)
|
||||
else
|
||||
{
|
||||
// Release task resources
|
||||
s_Tasks[pos].Release();
|
||||
s_Tasks[pos].Clear();
|
||||
s_Tasks[pos].Terminate();
|
||||
// Reset the timer
|
||||
s_Intervals[pos] = 0;
|
||||
}
|
||||
@ -450,8 +459,7 @@ void Tasks::Cleanup(Int32 id, Int32 type)
|
||||
{
|
||||
if (t.mEntity == id && t.mType == type)
|
||||
{
|
||||
t.Release();
|
||||
t.Clear();
|
||||
t.Terminate();
|
||||
// Also disable the timer
|
||||
s_Intervals[&t - s_Tasks] = 0;
|
||||
}
|
||||
|
138
source/Tasks.hpp
138
source/Tasks.hpp
@ -34,6 +34,7 @@ private:
|
||||
LightObj mSelf; // A reference to `this`as a script object.
|
||||
LightObj mFunc; // A reference to the managed function object.
|
||||
LightObj mInst; // A reference to the associated entity object.
|
||||
LightObj mData; // A reference to the arbitrary data associated with this instance.
|
||||
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.
|
||||
@ -49,6 +50,7 @@ private:
|
||||
, mSelf()
|
||||
, mFunc()
|
||||
, mInst()
|
||||
, mData()
|
||||
, mIterations(0)
|
||||
, mInterval(0)
|
||||
, mEntity(-1)
|
||||
@ -88,6 +90,14 @@ private:
|
||||
*/
|
||||
Task & operator = (Task && o) = delete;
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const
|
||||
{
|
||||
return ToStrF("%lld", static_cast< Int64 >(mInterval));
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Initializes the task parameters. (assumes previous values are already released)
|
||||
*/
|
||||
@ -112,10 +122,138 @@ private:
|
||||
*/
|
||||
void Release();
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Terminate the task
|
||||
*/
|
||||
void Terminate()
|
||||
{
|
||||
Release();
|
||||
Clear();
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Execute the managed task.
|
||||
*/
|
||||
Interval Execute();
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Retrieve the instance to self.
|
||||
*/
|
||||
const LightObj & GetSelf() const
|
||||
{
|
||||
return mSelf;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Retrieve the instance to entity instance.
|
||||
*/
|
||||
const LightObj & GetInst() const
|
||||
{
|
||||
return mInst;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Retrieve the function object.
|
||||
*/
|
||||
const LightObj & GetFunc() const
|
||||
{
|
||||
return mFunc;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Modify the function object.
|
||||
*/
|
||||
void SetFunc(const Function & func)
|
||||
{
|
||||
// Validate the specified
|
||||
if (!sq_isclosure(func.GetFunc()) && !sq_isnativeclosure(func.GetFunc()))
|
||||
{
|
||||
STHROWF("Invalid callback type %s", SqTypeName(mFunc.GetType()));
|
||||
}
|
||||
// Grab the virtual machine once
|
||||
HSQUIRRELVM vm = DefaultVM::Get();
|
||||
// Remember the current stack size
|
||||
const StackGuard sg(vm);
|
||||
// Push the callback on the stack
|
||||
sq_pushobject(vm, func.GetFunc());
|
||||
// Grab the hash of the callback object
|
||||
mHash = sq_gethash(vm, -1);
|
||||
// Now store the function without the environment
|
||||
mFunc = LightObj(func.GetFunc());
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Retrieve the arbitrary user data object.
|
||||
*/
|
||||
const LightObj & GetData() const
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Modify the arbitrary user data object.
|
||||
*/
|
||||
void SetData(const LightObj & data)
|
||||
{
|
||||
mData = data;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Retrieve the execution interval.
|
||||
*/
|
||||
SQInteger GetInterval() const
|
||||
{
|
||||
return ConvTo< SQInteger >::From(mInterval);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Modify the execution interval.
|
||||
*/
|
||||
void SetInterval(SQInteger itr)
|
||||
{
|
||||
mInterval = ClampMin(ConvTo< Interval >::From(itr), static_cast< Interval >(0));
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Retrieve the number of iterations.
|
||||
*/
|
||||
SQInteger GetIterations() const
|
||||
{
|
||||
return ConvTo< SQInteger >::From(mIterations);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Modify the number of iterations.
|
||||
*/
|
||||
void SetIterations(SQInteger itr)
|
||||
{
|
||||
mIterations = ConvTo< Iterator >::From(itr);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Retrieve the number of arguments to be forwarded.
|
||||
*/
|
||||
SQInteger GetArguments() const
|
||||
{
|
||||
return ConvTo< SQInteger >::From(mArgc);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Retrieve a certain argument.
|
||||
*/
|
||||
LightObj GetArgument(SQInteger arg) const
|
||||
{
|
||||
constexpr Uint32 argvn = (sizeof(mArgv) / sizeof(mArgv[0]));
|
||||
// Cast the index to the proper value
|
||||
Uint8 idx = ConvTo< Uint8 >::From(arg);
|
||||
// Validate the specified index
|
||||
if (idx >= argvn)
|
||||
{
|
||||
STHROWF("The specified index is out of range: %u >= %u", idx, argvn);
|
||||
}
|
||||
// Return the requested argument
|
||||
return mArgv[idx];
|
||||
}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user