mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 08:47:17 +01:00
Implement explicit persistent routines.
All checks were successful
continuous-integration/drone/tag Build is passing
All checks were successful
continuous-integration/drone/tag Build is passing
This commit is contained in:
parent
2701b6487a
commit
e685b3ffe0
@ -19,6 +19,7 @@ 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];
|
||||||
bool Routine::s_Silenced = false;
|
bool Routine::s_Silenced = false;
|
||||||
|
bool Routine::s_Persistent = false;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Routine::Process()
|
void Routine::Process()
|
||||||
@ -537,8 +538,12 @@ void Register_Routine(HSQUIRRELVM vm)
|
|||||||
.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)
|
||||||
|
.Prop(_SC("Executing"), &Routine::GetExecuting)
|
||||||
.Prop(_SC("Quiet"), &Routine::GetQuiet, &Routine::SetQuiet)
|
.Prop(_SC("Quiet"), &Routine::GetQuiet, &Routine::SetQuiet)
|
||||||
.Prop(_SC("Endure"), &Routine::GetEndure, &Routine::SetEndure)
|
.Prop(_SC("Endure"), &Routine::GetEndure, &Routine::SetEndure)
|
||||||
|
.Prop(_SC("Inactive"), &Routine::GetInactive)
|
||||||
|
.Prop(_SC("Persistent"), &Routine::GetPersistent, &Routine::SetPersistent)
|
||||||
|
.Prop(_SC("Terminated"), &Routine::GetTerminated)
|
||||||
.Prop(_SC("Arguments"), &Routine::GetArguments)
|
.Prop(_SC("Arguments"), &Routine::GetArguments)
|
||||||
// Member Methods
|
// Member Methods
|
||||||
.FmtFunc(_SC("SetTag"), &Routine::ApplyTag)
|
.FmtFunc(_SC("SetTag"), &Routine::ApplyTag)
|
||||||
@ -548,12 +553,16 @@ void Register_Routine(HSQUIRRELVM vm)
|
|||||||
.Func(_SC("SetSuspended"), &Routine::ApplySuspended)
|
.Func(_SC("SetSuspended"), &Routine::ApplySuspended)
|
||||||
.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("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)
|
||||||
.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)
|
||||||
|
.StaticFunc(_SC("ArePersistent"), &Routine::GetPersistency)
|
||||||
|
.StaticFunc(_SC("SetPersistency"), &Routine::SetPersistency)
|
||||||
);
|
);
|
||||||
// Global functions
|
// Global functions
|
||||||
RootTable(vm).SquirrelFunc(_SC("SqRoutine"), &Routine::Create);
|
RootTable(vm).SquirrelFunc(_SC("SqRoutine"), &Routine::Create);
|
||||||
|
@ -33,19 +33,21 @@ private:
|
|||||||
struct Instance
|
struct Instance
|
||||||
{
|
{
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
LightObj mEnv; // A reference to the managed environment object.
|
LightObj mEnv{}; // A reference to the managed environment object.
|
||||||
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.
|
||||||
String mTag; // An arbitrary string which represents the tag.
|
String mTag{}; // An arbitrary string which represents the tag.
|
||||||
Iterator mIterations; // Number of iterations before self destruct.
|
Iterator mIterations{0}; // Number of iterations before self destruct.
|
||||||
Interval mInterval; // Interval between routine invocations.
|
Interval mInterval{0}; // Interval between routine invocations.
|
||||||
bool mSuspended; // Whether this instance is allowed to receive calls.
|
bool mSuspended{false}; // Whether this instance is allowed to receive calls.
|
||||||
bool mQuiet; // Whether this instance is allowed to handle errors.
|
bool mExecuting{false}; // Whether this instance is currently being executed.
|
||||||
bool mEndure; // Whether this instance is allowed to terminate itself on errors.
|
bool mQuiet{false}; // Whether this instance is allowed to handle errors.
|
||||||
bool mExecuting; // Whether this instance is currently being executed.
|
bool mEndure{false}; // Whether this instance is allowed to terminate itself on errors.
|
||||||
uint8_t mArgc; // The number of arguments that the routine must forward.
|
bool mInactive{true}; // Whether this instance has finished all iterations.
|
||||||
Argument mArgv[14]; // The arguments that the routine must forward.
|
bool mPersistent{false}; // Whether this instance should not reset when finished.
|
||||||
|
uint8_t mArgc{0}; // The number of arguments that the routine must forward.
|
||||||
|
Argument mArgv[14]{}; // The arguments that the routine must forward.
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------------------
|
||||||
* Default constructor.
|
* Default constructor.
|
||||||
@ -59,9 +61,11 @@ private:
|
|||||||
, mIterations(0)
|
, mIterations(0)
|
||||||
, mInterval(0)
|
, mInterval(0)
|
||||||
, mSuspended(false)
|
, mSuspended(false)
|
||||||
|
, mExecuting(false)
|
||||||
, mQuiet(GetSilenced())
|
, mQuiet(GetSilenced())
|
||||||
, mEndure(false)
|
, mEndure(false)
|
||||||
, mExecuting(false)
|
, mInactive(true)
|
||||||
|
, mPersistent(GetPersistency())
|
||||||
, mArgc(0)
|
, mArgc(0)
|
||||||
, mArgv()
|
, mArgv()
|
||||||
{
|
{
|
||||||
@ -111,6 +115,8 @@ private:
|
|||||||
mInterval = intrv;
|
mInterval = intrv;
|
||||||
// This can't be true now
|
// This can't be true now
|
||||||
mExecuting = false;
|
mExecuting = false;
|
||||||
|
// This is now active
|
||||||
|
mInactive = mFunc.IsNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------------------
|
||||||
@ -124,6 +130,7 @@ private:
|
|||||||
mData.Release();
|
mData.Release();
|
||||||
mIterations = 0;
|
mIterations = 0;
|
||||||
mInterval = 0;
|
mInterval = 0;
|
||||||
|
mInactive = true;
|
||||||
mTag.clear();
|
mTag.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,7 +186,10 @@ private:
|
|||||||
// Decrease the number of iterations if necessary
|
// Decrease the number of iterations if necessary
|
||||||
if (mIterations && (--mIterations) == 0)
|
if (mIterations && (--mIterations) == 0)
|
||||||
{
|
{
|
||||||
Terminate(); // This routine reached the end of it's life
|
// This routine reached the end of it's life
|
||||||
|
Finalize();
|
||||||
|
// We shouldn't try this again
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
// Return the current interval
|
// Return the current interval
|
||||||
return mInterval;
|
return mInterval;
|
||||||
@ -207,6 +217,22 @@ private:
|
|||||||
Release();
|
Release();
|
||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------------------
|
||||||
|
* Finalize the routine.
|
||||||
|
*/
|
||||||
|
void Finalize()
|
||||||
|
{
|
||||||
|
// Should we persist after this?
|
||||||
|
if (!mPersistent)
|
||||||
|
{
|
||||||
|
Terminate();
|
||||||
|
}
|
||||||
|
// This routine is not active anymore
|
||||||
|
mInactive = true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -217,6 +243,7 @@ private:
|
|||||||
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 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.
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -354,7 +381,7 @@ public:
|
|||||||
}
|
}
|
||||||
// Unable to find such routine
|
// Unable to find such routine
|
||||||
STHROWF("Unable to fetch a routine with tag ({}). No such routine", tag.mPtr);
|
STHROWF("Unable to fetch a routine with tag ({}). No such routine", tag.mPtr);
|
||||||
SQ_UNREACHABLE;
|
SQ_UNREACHABLE
|
||||||
// Should not reach this point but if it did, we have to return something
|
// Should not reach this point but if it did, we have to return something
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
@ -610,6 +637,14 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* See whether the routine is currently being executed.
|
||||||
|
*/
|
||||||
|
SQMOD_NODISCARD bool GetExecuting() const
|
||||||
|
{
|
||||||
|
return GetValid().mExecuting;
|
||||||
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* See whether the routine is quite.
|
* See whether the routine is quite.
|
||||||
*/
|
*/
|
||||||
@ -660,6 +695,47 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* See whether the routine is inactive.
|
||||||
|
*/
|
||||||
|
SQMOD_NODISCARD bool GetInactive() const
|
||||||
|
{
|
||||||
|
return GetValid().mInactive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* See whether the routine is persistent.
|
||||||
|
*/
|
||||||
|
SQMOD_NODISCARD bool GetPersistent() const
|
||||||
|
{
|
||||||
|
return GetValid().mPersistent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Set whether the routine should be persistent.
|
||||||
|
*/
|
||||||
|
void SetPersistent(bool toggle)
|
||||||
|
{
|
||||||
|
GetValid().mPersistent = toggle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Set whether the routine should be persistent.
|
||||||
|
*/
|
||||||
|
Routine & ApplyPersistent(bool toggle)
|
||||||
|
{
|
||||||
|
SetPersistent(toggle);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* See whether the routine was terminated.
|
||||||
|
*/
|
||||||
|
SQMOD_NODISCARD bool GetTerminated() const
|
||||||
|
{
|
||||||
|
return (m_Slot == SQMOD_MAX_ROUTINES);
|
||||||
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Retrieve the number of arguments to be forwarded.
|
* Retrieve the number of arguments to be forwarded.
|
||||||
*/
|
*/
|
||||||
@ -687,15 +763,38 @@ public:
|
|||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Release the environment object and default to self.
|
* Release the environment object and default to self.
|
||||||
*/
|
*/
|
||||||
void DropEnv()
|
Routine & DropEnv()
|
||||||
{
|
{
|
||||||
GetValid().mEnv.Release();
|
GetValid().mEnv.Release();
|
||||||
|
// Allow chaining
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Restart the routine with the specified number of iterations.
|
||||||
|
*/
|
||||||
|
Routine & Restart(SQInteger itr)
|
||||||
|
{
|
||||||
|
Instance & inst = GetValid();
|
||||||
|
// Apply the iterations
|
||||||
|
inst.mIterations = ConvTo< Iterator >::From(itr);
|
||||||
|
// If currently executing then we need to account for the subtract
|
||||||
|
if (inst.mExecuting)
|
||||||
|
{
|
||||||
|
inst.mIterations += 1;
|
||||||
|
}
|
||||||
|
// Activate the routine again
|
||||||
|
inst.mInactive = inst.mFunc.IsNull();
|
||||||
|
// Start the clock again
|
||||||
|
s_Intervals[m_Slot] = inst.mInterval;
|
||||||
|
// Allow chaining
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* See if error reporting is enabled for all newly created routines.
|
* See if error reporting is enabled for all newly created routines.
|
||||||
*/
|
*/
|
||||||
static bool GetSilenced()
|
static bool GetSilenced() noexcept
|
||||||
{
|
{
|
||||||
return s_Silenced;
|
return s_Silenced;
|
||||||
}
|
}
|
||||||
@ -703,10 +802,26 @@ public:
|
|||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Set if error reporting should be enabled for all newly created routines.
|
* Set if error reporting should be enabled for all newly created routines.
|
||||||
*/
|
*/
|
||||||
static void SetSilenced(bool toggle)
|
static void SetSilenced(bool toggle) noexcept
|
||||||
{
|
{
|
||||||
s_Silenced = toggle;
|
s_Silenced = toggle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* See if all newly created routines should be persistent by default.
|
||||||
|
*/
|
||||||
|
static bool GetPersistency() noexcept
|
||||||
|
{
|
||||||
|
return s_Persistent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Set all newly created routines to be persistent by default.
|
||||||
|
*/
|
||||||
|
static void SetPersistency(bool toggle) noexcept
|
||||||
|
{
|
||||||
|
s_Persistent = toggle;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Namespace:: SqMod
|
} // Namespace:: SqMod
|
||||||
|
Loading…
Reference in New Issue
Block a user