mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 00:37:15 +01:00
Implement the user tags feature in tasks.
This commit is contained in:
parent
2e0b7b6c7f
commit
ff8df39a13
@ -157,14 +157,16 @@ void Tasks::Register(HSQUIRRELVM vm)
|
||||
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
|
||||
.Func(_SC("_tostring"), &Task::ToString)
|
||||
// Properties
|
||||
.Prop(_SC("Inst"), &Task::GetInst)
|
||||
.Prop(_SC("Tag"), &Task::GetTag, &Task::SetTag)
|
||||
.Prop(_SC("Entity"), &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)
|
||||
.Prop(_SC("Inst"), &Task::GetInst)
|
||||
// Member Methods
|
||||
.FmtFunc(_SC("SetTag"), &Task::SetTag)
|
||||
.Func(_SC("Terminate"), &Task::Terminate)
|
||||
.Func(_SC("GetArgument"), &Task::GetArgument)
|
||||
);
|
||||
@ -323,8 +325,10 @@ SQInteger Tasks::Create(Int32 id, Int32 type, HSQUIRRELVM vm)
|
||||
s_Intervals[slot] = intrv;
|
||||
// Increase the number of used slots
|
||||
++s_Used;
|
||||
// Specify that this function doesn't return anything
|
||||
return 0;
|
||||
// Push the tag instance on the stack
|
||||
sq_pushobject(vm, task.mSelf);
|
||||
// Specify that this function returns a value
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -451,6 +455,23 @@ SQInteger Tasks::Exists(Int32 id, Int32 type, HSQUIRRELVM vm)
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Tasks::Task & Tasks::FindByTag(Int32 id, Int32 type, const StackStrF & tag)
|
||||
{
|
||||
// Attempt to find the requested task
|
||||
for (const auto & t : s_Tasks)
|
||||
{
|
||||
if (t.mEntity == id && t.mType == type && t.mTag.compare(tag.mPtr) == 0)
|
||||
{
|
||||
return t; // Return this task instance
|
||||
}
|
||||
}
|
||||
// Unable to find such task
|
||||
STHROWF("Unable to find a task with tag (%s)", tag.mPtr);
|
||||
// Should not reach this point but if it did, we have to return something
|
||||
return s_Tasks[SQMOD_MAX_TASKS]; // Intentional Buffer overflow!
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Tasks::Cleanup(Int32 id, Int32 type)
|
||||
{
|
||||
|
@ -31,6 +31,7 @@ private:
|
||||
{
|
||||
// ----------------------------------------------------------------------------------------
|
||||
SQHash mHash; // The hash of the referenced function object.
|
||||
String mTag; // An arbitrary string which represents the tag.
|
||||
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.
|
||||
@ -47,6 +48,7 @@ private:
|
||||
*/
|
||||
Task()
|
||||
: mHash(0)
|
||||
, mTag()
|
||||
, mSelf()
|
||||
, mFunc()
|
||||
, mInst()
|
||||
@ -136,6 +138,22 @@ private:
|
||||
*/
|
||||
Interval Execute();
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Retrieve the associated user tag.
|
||||
*/
|
||||
const String & GetTag() const
|
||||
{
|
||||
return mTag;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Modify the associated user tag.
|
||||
*/
|
||||
void SetTag(const StackStrF & tag)
|
||||
{
|
||||
mTag.assign(tag.mPtr, ClampMin(tag.mLen, 0));
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Retrieve the instance to entity instance.
|
||||
*/
|
||||
@ -339,6 +357,11 @@ protected:
|
||||
*/
|
||||
static SQInteger Exists(Int32 id, Int32 type, HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Cleanup all tasks associated with the specified entity.
|
||||
*/
|
||||
static const Task & FindByTag(Int32 id, Int32 type, const StackStrF & tag);
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
@ -429,6 +452,58 @@ public:
|
||||
// Forward the call and return the result
|
||||
return Exists(inst->GetID(), Type, vm);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Forwards calls to find tasks.
|
||||
*/
|
||||
template < typename Entity, Int32 Type > static SQInteger FindTask(HSQUIRRELVM vm)
|
||||
{
|
||||
// Was the tag string specified?
|
||||
if (sq_gettop(vm) <= 1)
|
||||
{
|
||||
return sq_throwerror(vm, "Missing tag string");
|
||||
}
|
||||
// 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());
|
||||
}
|
||||
// Attempt to generate the string value
|
||||
const StackStrF tag(vm, 2);
|
||||
// Have we failed to retrieve the string?
|
||||
if (SQ_FAILED(tag.mRes))
|
||||
{
|
||||
return tag.mRes; // Propagate the error!
|
||||
}
|
||||
// Attempt to find the specified task
|
||||
try
|
||||
{
|
||||
// Perform the search
|
||||
const Task & task = FindByTag(inst->GetID(), Type, tag);
|
||||
// Now push the instance on the stack
|
||||
sq_pushobject(vm, task.mSelf.mObj);
|
||||
}
|
||||
catch (const Sqrat::Exception & e)
|
||||
{
|
||||
return sq_throwerror(vm, e.what());
|
||||
}
|
||||
// Specify that this function returns a value
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
Loading…
Reference in New Issue
Block a user