mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 00:37:15 +01:00
Add yielding results for routines.
Also add a way to retrieve currently executed routine.
This commit is contained in:
parent
2088a825e3
commit
79b5641b9f
@ -18,6 +18,7 @@ Routine::Time Routine::s_Last = 0;
|
||||
Routine::Time Routine::s_Prev = 0;
|
||||
Routine::Interval Routine::s_Intervals[SQMOD_MAX_ROUTINES];
|
||||
Routine::Instance Routine::s_Instances[SQMOD_MAX_ROUTINES];
|
||||
SQInteger Routine::s_Current = SQMOD_MAX_ROUTINES;
|
||||
bool Routine::s_Silenced = false;
|
||||
bool Routine::s_Persistent = false;
|
||||
|
||||
@ -48,11 +49,14 @@ void Routine::Process()
|
||||
// Have we completed the routine interval?
|
||||
if ((*itr) <= 0)
|
||||
{
|
||||
s_Current = static_cast< SQInteger >(itr - s_Intervals);
|
||||
// Execute and reset the elapsed time
|
||||
(*itr) = s_Instances[itr - s_Intervals].Execute();
|
||||
(*itr) = s_Instances[s_Current].Execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Clear currently executed routine
|
||||
s_Current = SQMOD_MAX_ROUTINES;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -535,6 +539,7 @@ void Register_Routine(HSQUIRRELVM vm)
|
||||
.Prop(_SC("Env"), &Routine::GetEnv, &Routine::SetEnv)
|
||||
.Prop(_SC("Func"), &Routine::GetFunc, &Routine::SetFunc)
|
||||
.Prop(_SC("Data"), &Routine::GetData, &Routine::SetData)
|
||||
.Prop(_SC("Result"), &Routine::GetResult, &Routine::SetResult)
|
||||
.Prop(_SC("Interval"), &Routine::GetInterval, &Routine::SetInterval)
|
||||
.Prop(_SC("Iterations"), &Routine::GetIterations, &Routine::SetIterations)
|
||||
.Prop(_SC("Suspended"), &Routine::GetSuspended, &Routine::SetSuspended)
|
||||
@ -543,6 +548,7 @@ void Register_Routine(HSQUIRRELVM vm)
|
||||
.Prop(_SC("Endure"), &Routine::GetEndure, &Routine::SetEndure)
|
||||
.Prop(_SC("Inactive"), &Routine::GetInactive)
|
||||
.Prop(_SC("Persistent"), &Routine::GetPersistent, &Routine::SetPersistent)
|
||||
.Prop(_SC("Yields"), &Routine::GetYields, &Routine::SetYields)
|
||||
.Prop(_SC("Terminated"), &Routine::GetTerminated)
|
||||
.Prop(_SC("Arguments"), &Routine::GetArguments)
|
||||
// Member Methods
|
||||
@ -554,10 +560,12 @@ void Register_Routine(HSQUIRRELVM vm)
|
||||
.Func(_SC("SetQuiet"), &Routine::ApplyQuiet)
|
||||
.Func(_SC("SetEndure"), &Routine::ApplyEndure)
|
||||
.Func(_SC("SetPersistent"), &Routine::ApplyPersistent)
|
||||
.Func(_SC("SetYields"), &Routine::ApplyYields)
|
||||
.Func(_SC("Terminate"), &Routine::Terminate)
|
||||
.Func(_SC("GetArgument"), &Routine::GetArgument)
|
||||
.Func(_SC("DropEnv"), &Routine::DropEnv)
|
||||
.Func(_SC("Restart"), &Routine::Restart)
|
||||
.StaticFunc(_SC("Current"), &Routine::GetCurrent)
|
||||
.StaticFunc(_SC("UsedCount"), &Routine::GetUsed)
|
||||
.StaticFunc(_SC("AreSilenced"), &Routine::GetSilenced)
|
||||
.StaticFunc(_SC("SetSilenced"), &Routine::SetSilenced)
|
||||
|
@ -37,6 +37,7 @@ private:
|
||||
LightObj mFunc{}; // A reference to the managed function object.
|
||||
LightObj mInst{}; // Reference to the routine associated with this instance.
|
||||
LightObj mData{}; // A reference to the arbitrary data associated with this instance.
|
||||
LightObj mResult{}; // A reference to the value returned by the callback on last invocation.
|
||||
String mTag{}; // An arbitrary string which represents the tag.
|
||||
Iterator mIterations{0}; // Number of iterations before self destruct.
|
||||
Interval mInterval{0}; // Interval between routine invocations.
|
||||
@ -46,6 +47,7 @@ private:
|
||||
bool mEndure{false}; // Whether this instance is allowed to terminate itself on errors.
|
||||
bool mInactive{true}; // Whether this instance has finished all iterations.
|
||||
bool mPersistent{false}; // Whether this instance should not reset when finished.
|
||||
bool mYields{false}; // Whether this instance may yield a value when callback is invoked.
|
||||
uint8_t mArgc{0}; // The number of arguments that the routine must forward.
|
||||
Argument mArgv[14]{}; // The arguments that the routine must forward.
|
||||
|
||||
@ -57,6 +59,7 @@ private:
|
||||
, mFunc()
|
||||
, mInst()
|
||||
, mData()
|
||||
, mResult()
|
||||
, mTag()
|
||||
, mIterations(0)
|
||||
, mInterval(0)
|
||||
@ -66,6 +69,7 @@ private:
|
||||
, mEndure(false)
|
||||
, mInactive(true)
|
||||
, mPersistent(GetPersistency())
|
||||
, mYields(false)
|
||||
, mArgc(0)
|
||||
, mArgv()
|
||||
{
|
||||
@ -128,6 +132,7 @@ private:
|
||||
mFunc.Release();
|
||||
mInst.Release();
|
||||
mData.Release();
|
||||
mResult.Release();
|
||||
mIterations = 0;
|
||||
mInterval = 0;
|
||||
mInactive = true;
|
||||
@ -168,9 +173,30 @@ private:
|
||||
// This routine is currently executing
|
||||
mExecuting = true;
|
||||
// Make the function call and store the result
|
||||
const SQRESULT res = sq_call(vm, mArgc + 1, static_cast< SQBool >(false), static_cast< SQBool >(!mQuiet));
|
||||
const SQRESULT res = sq_call(vm, mArgc + 1, static_cast< SQBool >(mYields), static_cast< SQBool >(!mQuiet));
|
||||
// This routine has finished executing
|
||||
mExecuting = false;
|
||||
// Should we look for a yielded value?
|
||||
if (mYields)
|
||||
{
|
||||
// Release previous value, if any
|
||||
if (!sq_isnull(mResult.mObj))
|
||||
{
|
||||
sq_release(vm, &(mResult.mObj));
|
||||
}
|
||||
// Attempt to retrieve the new value if possible
|
||||
if (SQ_SUCCEEDED(res) && SQ_SUCCEEDED(sq_getstackobj(vm, -1, &(mResult.mObj))))
|
||||
{
|
||||
sq_addref(vm, &(mResult.mObj)); // Don't destroy once popped
|
||||
}
|
||||
else
|
||||
{
|
||||
sq_resetobject(&(mResult.mObj)); // Discard anything so far
|
||||
}
|
||||
// Pop the returned value from the stack
|
||||
sq_pop(vm, 1);
|
||||
}
|
||||
|
||||
// Pop the callback object from the stack
|
||||
sq_pop(vm, 1);
|
||||
// Validate the result
|
||||
@ -242,6 +268,7 @@ private:
|
||||
static Time s_Prev; // Previous time point.
|
||||
static Interval s_Intervals[SQMOD_MAX_ROUTINES]; // List of intervals to be processed.
|
||||
static Instance s_Instances[SQMOD_MAX_ROUTINES]; // List of routines to be executed.
|
||||
static SQInteger s_Current; // Currently executed routine index (SQMOD_MAX_ROUTINES if none).
|
||||
static bool s_Silenced; // Error reporting independent from global setting.
|
||||
static bool s_Persistent; // Whether all routines should be persistent by default.
|
||||
|
||||
@ -562,6 +589,22 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the value that the callback has yielded last invocation.
|
||||
*/
|
||||
SQMOD_NODISCARD const LightObj & GetResult() const
|
||||
{
|
||||
return GetValid().mResult;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the value that the callback has yielded last invocation.
|
||||
*/
|
||||
void SetResult(const LightObj & value)
|
||||
{
|
||||
GetValid().mResult = value;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the execution interval.
|
||||
*/
|
||||
@ -728,6 +771,31 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether the routine is yielding a value.
|
||||
*/
|
||||
SQMOD_NODISCARD bool GetYields() const
|
||||
{
|
||||
return GetValid().mYields;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set whether the routine should be yielding values.
|
||||
*/
|
||||
void SetYields(bool toggle)
|
||||
{
|
||||
GetValid().mYields = toggle;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set whether the routine should be yielding values.
|
||||
*/
|
||||
Routine & ApplyYields(bool toggle)
|
||||
{
|
||||
SetYields(toggle);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether the routine was terminated.
|
||||
*/
|
||||
@ -791,6 +859,14 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the currently executed routine, if any.
|
||||
*/
|
||||
static LightObj & GetCurrent()
|
||||
{
|
||||
return (s_Current != SQMOD_MAX_ROUTINES) ? s_Instances[s_Current].mInst : NullLightObj();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See if error reporting is enabled for all newly created routines.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user