mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 08:47:17 +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::Time Routine::s_Prev = 0;
|
||||||
Routine::Interval Routine::s_Intervals[SQMOD_MAX_ROUTINES];
|
Routine::Interval Routine::s_Intervals[SQMOD_MAX_ROUTINES];
|
||||||
Routine::Instance Routine::s_Instances[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_Silenced = false;
|
||||||
bool Routine::s_Persistent = false;
|
bool Routine::s_Persistent = false;
|
||||||
|
|
||||||
@ -48,11 +49,14 @@ void Routine::Process()
|
|||||||
// Have we completed the routine interval?
|
// Have we completed the routine interval?
|
||||||
if ((*itr) <= 0)
|
if ((*itr) <= 0)
|
||||||
{
|
{
|
||||||
|
s_Current = static_cast< SQInteger >(itr - s_Intervals);
|
||||||
// Execute and reset the elapsed time
|
// 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("Env"), &Routine::GetEnv, &Routine::SetEnv)
|
||||||
.Prop(_SC("Func"), &Routine::GetFunc, &Routine::SetFunc)
|
.Prop(_SC("Func"), &Routine::GetFunc, &Routine::SetFunc)
|
||||||
.Prop(_SC("Data"), &Routine::GetData, &Routine::SetData)
|
.Prop(_SC("Data"), &Routine::GetData, &Routine::SetData)
|
||||||
|
.Prop(_SC("Result"), &Routine::GetResult, &Routine::SetResult)
|
||||||
.Prop(_SC("Interval"), &Routine::GetInterval, &Routine::SetInterval)
|
.Prop(_SC("Interval"), &Routine::GetInterval, &Routine::SetInterval)
|
||||||
.Prop(_SC("Iterations"), &Routine::GetIterations, &Routine::SetIterations)
|
.Prop(_SC("Iterations"), &Routine::GetIterations, &Routine::SetIterations)
|
||||||
.Prop(_SC("Suspended"), &Routine::GetSuspended, &Routine::SetSuspended)
|
.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("Endure"), &Routine::GetEndure, &Routine::SetEndure)
|
||||||
.Prop(_SC("Inactive"), &Routine::GetInactive)
|
.Prop(_SC("Inactive"), &Routine::GetInactive)
|
||||||
.Prop(_SC("Persistent"), &Routine::GetPersistent, &Routine::SetPersistent)
|
.Prop(_SC("Persistent"), &Routine::GetPersistent, &Routine::SetPersistent)
|
||||||
|
.Prop(_SC("Yields"), &Routine::GetYields, &Routine::SetYields)
|
||||||
.Prop(_SC("Terminated"), &Routine::GetTerminated)
|
.Prop(_SC("Terminated"), &Routine::GetTerminated)
|
||||||
.Prop(_SC("Arguments"), &Routine::GetArguments)
|
.Prop(_SC("Arguments"), &Routine::GetArguments)
|
||||||
// Member Methods
|
// Member Methods
|
||||||
@ -554,10 +560,12 @@ void Register_Routine(HSQUIRRELVM vm)
|
|||||||
.Func(_SC("SetQuiet"), &Routine::ApplyQuiet)
|
.Func(_SC("SetQuiet"), &Routine::ApplyQuiet)
|
||||||
.Func(_SC("SetEndure"), &Routine::ApplyEndure)
|
.Func(_SC("SetEndure"), &Routine::ApplyEndure)
|
||||||
.Func(_SC("SetPersistent"), &Routine::ApplyPersistent)
|
.Func(_SC("SetPersistent"), &Routine::ApplyPersistent)
|
||||||
|
.Func(_SC("SetYields"), &Routine::ApplyYields)
|
||||||
.Func(_SC("Terminate"), &Routine::Terminate)
|
.Func(_SC("Terminate"), &Routine::Terminate)
|
||||||
.Func(_SC("GetArgument"), &Routine::GetArgument)
|
.Func(_SC("GetArgument"), &Routine::GetArgument)
|
||||||
.Func(_SC("DropEnv"), &Routine::DropEnv)
|
.Func(_SC("DropEnv"), &Routine::DropEnv)
|
||||||
.Func(_SC("Restart"), &Routine::Restart)
|
.Func(_SC("Restart"), &Routine::Restart)
|
||||||
|
.StaticFunc(_SC("Current"), &Routine::GetCurrent)
|
||||||
.StaticFunc(_SC("UsedCount"), &Routine::GetUsed)
|
.StaticFunc(_SC("UsedCount"), &Routine::GetUsed)
|
||||||
.StaticFunc(_SC("AreSilenced"), &Routine::GetSilenced)
|
.StaticFunc(_SC("AreSilenced"), &Routine::GetSilenced)
|
||||||
.StaticFunc(_SC("SetSilenced"), &Routine::SetSilenced)
|
.StaticFunc(_SC("SetSilenced"), &Routine::SetSilenced)
|
||||||
|
@ -37,6 +37,7 @@ private:
|
|||||||
LightObj mFunc{}; // A reference to the managed function object.
|
LightObj mFunc{}; // A reference to the managed function object.
|
||||||
LightObj mInst{}; // Reference to the routine associated with this instance.
|
LightObj mInst{}; // Reference to the routine associated with this instance.
|
||||||
LightObj mData{}; // A reference to the arbitrary data 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.
|
String mTag{}; // An arbitrary string which represents the tag.
|
||||||
Iterator mIterations{0}; // Number of iterations before self destruct.
|
Iterator mIterations{0}; // Number of iterations before self destruct.
|
||||||
Interval mInterval{0}; // Interval between routine invocations.
|
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 mEndure{false}; // Whether this instance is allowed to terminate itself on errors.
|
||||||
bool mInactive{true}; // Whether this instance has finished all iterations.
|
bool mInactive{true}; // Whether this instance has finished all iterations.
|
||||||
bool mPersistent{false}; // Whether this instance should not reset when finished.
|
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.
|
uint8_t mArgc{0}; // The number of arguments that the routine must forward.
|
||||||
Argument mArgv[14]{}; // The arguments that the routine must forward.
|
Argument mArgv[14]{}; // The arguments that the routine must forward.
|
||||||
|
|
||||||
@ -57,6 +59,7 @@ private:
|
|||||||
, mFunc()
|
, mFunc()
|
||||||
, mInst()
|
, mInst()
|
||||||
, mData()
|
, mData()
|
||||||
|
, mResult()
|
||||||
, mTag()
|
, mTag()
|
||||||
, mIterations(0)
|
, mIterations(0)
|
||||||
, mInterval(0)
|
, mInterval(0)
|
||||||
@ -66,6 +69,7 @@ private:
|
|||||||
, mEndure(false)
|
, mEndure(false)
|
||||||
, mInactive(true)
|
, mInactive(true)
|
||||||
, mPersistent(GetPersistency())
|
, mPersistent(GetPersistency())
|
||||||
|
, mYields(false)
|
||||||
, mArgc(0)
|
, mArgc(0)
|
||||||
, mArgv()
|
, mArgv()
|
||||||
{
|
{
|
||||||
@ -128,6 +132,7 @@ private:
|
|||||||
mFunc.Release();
|
mFunc.Release();
|
||||||
mInst.Release();
|
mInst.Release();
|
||||||
mData.Release();
|
mData.Release();
|
||||||
|
mResult.Release();
|
||||||
mIterations = 0;
|
mIterations = 0;
|
||||||
mInterval = 0;
|
mInterval = 0;
|
||||||
mInactive = true;
|
mInactive = true;
|
||||||
@ -168,9 +173,30 @@ private:
|
|||||||
// This routine is currently executing
|
// This routine is currently executing
|
||||||
mExecuting = true;
|
mExecuting = true;
|
||||||
// Make the function call and store the result
|
// 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
|
// This routine has finished executing
|
||||||
mExecuting = false;
|
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
|
// Pop the callback object from the stack
|
||||||
sq_pop(vm, 1);
|
sq_pop(vm, 1);
|
||||||
// Validate the result
|
// Validate the result
|
||||||
@ -242,6 +268,7 @@ private:
|
|||||||
static Time s_Prev; // Previous time point.
|
static Time s_Prev; // Previous time point.
|
||||||
static Interval s_Intervals[SQMOD_MAX_ROUTINES]; // List of intervals to be processed.
|
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 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_Silenced; // Error reporting independent from global setting.
|
||||||
static bool s_Persistent; // Whether all routines should be persistent by default.
|
static bool s_Persistent; // Whether all routines should be persistent by default.
|
||||||
|
|
||||||
@ -562,6 +589,22 @@ public:
|
|||||||
return *this;
|
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.
|
* Retrieve the execution interval.
|
||||||
*/
|
*/
|
||||||
@ -728,6 +771,31 @@ public:
|
|||||||
return *this;
|
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.
|
* See whether the routine was terminated.
|
||||||
*/
|
*/
|
||||||
@ -791,6 +859,14 @@ public:
|
|||||||
return *this;
|
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.
|
* See if error reporting is enabled for all newly created routines.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user