2020-03-22 00:45:04 +01:00
|
|
|
#pragma once
|
2016-02-21 08:25:46 +01:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
#include "Base/Shared.hpp"
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
namespace SqMod {
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
|
|
* Execute callbacks after specific intervals of time.
|
|
|
|
*/
|
|
|
|
class Routine
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Simplify future changes to a single point of change.
|
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
typedef Int64 Time;
|
|
|
|
typedef SQInteger Interval;
|
|
|
|
typedef Uint32 Iterator;
|
2016-11-17 22:10:31 +01:00
|
|
|
typedef LightObj Argument;
|
2016-02-23 04:23:56 +01:00
|
|
|
|
2016-11-17 22:10:31 +01:00
|
|
|
private:
|
2016-02-21 08:25:46 +01:00
|
|
|
|
2016-03-10 04:57:13 +01:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Structure that represents an active routine and keeps track of the routine information.
|
2016-02-21 08:25:46 +01:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
struct Instance
|
|
|
|
{
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
LightObj mEnv; // A reference to the managed environment object.
|
|
|
|
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.
|
|
|
|
String mTag; // An arbitrary string which represents the tag.
|
|
|
|
Iterator mIterations; // Number of iterations before self destruct.
|
|
|
|
Interval mInterval; // Interval between routine invocations.
|
|
|
|
bool mSuspended; // Whether this instance is allowed to receive calls.
|
2018-01-28 21:45:09 +01:00
|
|
|
bool mQuiet; // Whether this instance is allowed to handle errors.
|
|
|
|
bool mEndure; // Whether this instance is allowed to terminate itself on errors.
|
2020-05-01 00:24:06 +02:00
|
|
|
bool mTerminated; // Whether this instance is allowed to terminate itself on errors.
|
2016-11-17 22:10:31 +01:00
|
|
|
Uint8 mArgc; // The number of arguments that the routine must forward.
|
|
|
|
Argument mArgv[14]; // The arguments that the routine must forward.
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------------------------
|
|
|
|
* Default constructor.
|
|
|
|
*/
|
2020-03-22 05:53:04 +01:00
|
|
|
Instance() noexcept
|
2016-11-17 22:10:31 +01:00
|
|
|
: mEnv()
|
|
|
|
, mFunc()
|
|
|
|
, mInst()
|
|
|
|
, mData()
|
|
|
|
, mTag()
|
|
|
|
, mIterations(0)
|
|
|
|
, mInterval(0)
|
|
|
|
, mSuspended(false)
|
2020-04-10 07:30:22 +02:00
|
|
|
, mQuiet(GetSilenced())
|
2018-01-28 21:45:09 +01:00
|
|
|
, mEndure(false)
|
2020-05-01 00:24:06 +02:00
|
|
|
, mTerminated(false)
|
2016-11-17 22:10:31 +01:00
|
|
|
, mArgc(0)
|
|
|
|
, mArgv()
|
|
|
|
{
|
|
|
|
/* ... */
|
|
|
|
}
|
2016-03-10 04:57:13 +01:00
|
|
|
|
2016-11-17 22:10:31 +01:00
|
|
|
/* ----------------------------------------------------------------------------------------
|
|
|
|
* Copy constructor. (disabled)
|
|
|
|
*/
|
|
|
|
Instance(const Instance & o) = delete;
|
2016-03-10 04:57:13 +01:00
|
|
|
|
2016-11-17 22:10:31 +01:00
|
|
|
/* ----------------------------------------------------------------------------------------
|
|
|
|
* Move constructor. (disabled)
|
|
|
|
*/
|
|
|
|
Instance(Instance && o) = delete;
|
2016-02-23 04:23:56 +01:00
|
|
|
|
2016-11-17 22:10:31 +01:00
|
|
|
/* ----------------------------------------------------------------------------------------
|
|
|
|
* Destructor.
|
|
|
|
*/
|
|
|
|
~Instance()
|
|
|
|
{
|
|
|
|
Terminate();
|
|
|
|
}
|
2016-02-21 08:25:46 +01:00
|
|
|
|
2016-11-17 22:10:31 +01:00
|
|
|
/* ----------------------------------------------------------------------------------------
|
|
|
|
* Copy assignment operator. (disabled)
|
|
|
|
*/
|
|
|
|
Instance & operator = (const Instance & o) = delete;
|
2016-02-21 08:25:46 +01:00
|
|
|
|
2016-11-17 22:10:31 +01:00
|
|
|
/* ----------------------------------------------------------------------------------------
|
|
|
|
* Move assignment operator. (disabled)
|
|
|
|
*/
|
|
|
|
Instance & operator = (Instance && o) = delete;
|
2016-02-23 04:23:56 +01:00
|
|
|
|
2016-11-17 22:10:31 +01:00
|
|
|
/* ----------------------------------------------------------------------------------------
|
|
|
|
* Initializes the routine parameters. (assumes previous values are already released)
|
|
|
|
*/
|
|
|
|
void Init(HSQOBJECT & env, HSQOBJECT & func, HSQOBJECT & inst, Interval intrv, Iterator itr)
|
|
|
|
{
|
|
|
|
// Initialize the callback objects
|
2020-05-01 00:24:06 +02:00
|
|
|
mEnv = LightObj{env};
|
|
|
|
mFunc = LightObj{func};
|
2016-11-17 22:10:31 +01:00
|
|
|
// Associate with the routine instance
|
2020-05-01 00:24:06 +02:00
|
|
|
mInst = LightObj{inst};
|
2016-11-17 22:10:31 +01:00
|
|
|
// Initialize the routine options
|
|
|
|
mIterations = itr;
|
|
|
|
mInterval = intrv;
|
|
|
|
}
|
2016-05-22 05:20:38 +02:00
|
|
|
|
2016-11-17 22:10:31 +01:00
|
|
|
/* ----------------------------------------------------------------------------------------
|
|
|
|
* Release managed script resources.
|
|
|
|
*/
|
|
|
|
void Release()
|
|
|
|
{
|
|
|
|
mEnv.Release();
|
|
|
|
mFunc.Release();
|
|
|
|
mInst.Release();
|
|
|
|
mData.Release();
|
|
|
|
mIterations = 0;
|
|
|
|
mInterval = 0;
|
|
|
|
mTag.clear();
|
|
|
|
}
|
2016-05-22 05:20:38 +02:00
|
|
|
|
2016-11-17 22:10:31 +01:00
|
|
|
/* ----------------------------------------------------------------------------------------
|
|
|
|
* Execute the managed routine.
|
|
|
|
*/
|
|
|
|
Interval Execute()
|
|
|
|
{
|
|
|
|
// is this even a valid routine?
|
|
|
|
if (mInst.IsNull())
|
|
|
|
{
|
|
|
|
return 0; // Dunno how we got here but it ends now
|
|
|
|
}
|
|
|
|
// Are we allowed to forward calls?
|
|
|
|
else if (!mSuspended)
|
|
|
|
{
|
|
|
|
// Grab the virtual machine once
|
2020-04-27 12:10:54 +02:00
|
|
|
HSQUIRRELVM vm = SqVM();
|
2016-11-17 22:10:31 +01:00
|
|
|
// Push the function on the stack
|
|
|
|
sq_pushobject(vm, mFunc);
|
|
|
|
// Push the environment on the stack
|
2019-07-26 18:59:34 +02:00
|
|
|
if (!mEnv.IsNull())
|
|
|
|
{
|
|
|
|
sq_pushobject(vm, mEnv); // Push object
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sq_pushobject(vm, mInst); // Push self
|
|
|
|
}
|
2016-11-17 22:10:31 +01:00
|
|
|
// Push function parameters, if any
|
|
|
|
for (Uint32 n = 0; n < mArgc; ++n)
|
|
|
|
{
|
|
|
|
sq_pushobject(vm, mArgv[n].mObj);
|
|
|
|
}
|
|
|
|
// Make the function call and store the result
|
2020-03-22 05:53:04 +01:00
|
|
|
const SQRESULT res = sq_call(vm, mArgc + 1, static_cast< SQBool >(false), static_cast< SQBool >(!mQuiet));
|
2018-07-05 20:01:08 +02:00
|
|
|
// Pop the callback object from the stack
|
|
|
|
sq_pop(vm, 1);
|
2016-11-17 22:10:31 +01:00
|
|
|
// Validate the result
|
|
|
|
if (SQ_FAILED(res))
|
|
|
|
{
|
2018-01-28 21:45:09 +01:00
|
|
|
// Should we endure the errors?
|
2020-05-01 00:24:06 +02:00
|
|
|
if (!mEndure && !mTerminated)
|
2018-01-28 21:45:09 +01:00
|
|
|
{
|
2020-05-01 00:24:06 +02:00
|
|
|
Terminate(); // Destroy our self on error
|
2018-01-28 21:45:09 +01:00
|
|
|
}
|
2016-11-17 22:10:31 +01:00
|
|
|
}
|
|
|
|
}
|
2020-05-01 00:24:06 +02:00
|
|
|
// See if we are using the slot of a previously terminated routine
|
|
|
|
if (mTerminated)
|
|
|
|
{
|
|
|
|
// The old routine was terminated, we're the new routine and we're not
|
|
|
|
// We don't touch the iterations and return the interval of the new routine
|
|
|
|
// to take effect on the next frame
|
|
|
|
mTerminated = false;
|
|
|
|
}
|
2016-11-17 22:10:31 +01:00
|
|
|
// Decrease the number of iterations if necessary
|
2020-05-01 00:24:06 +02:00
|
|
|
else if (mIterations && (--mIterations) == 0)
|
2016-11-17 22:10:31 +01:00
|
|
|
{
|
|
|
|
Terminate(); // This routine reached the end of it's life
|
|
|
|
}
|
|
|
|
// Return the current interval
|
|
|
|
return mInterval;
|
|
|
|
}
|
2016-05-22 05:20:38 +02:00
|
|
|
|
2016-11-17 22:10:31 +01:00
|
|
|
/* ----------------------------------------------------------------------------------------
|
|
|
|
* Clear the arguments.
|
|
|
|
*/
|
|
|
|
void Clear()
|
|
|
|
{
|
|
|
|
// Now release the arguments
|
|
|
|
for (auto & a : mArgv)
|
|
|
|
{
|
|
|
|
a.Release();
|
|
|
|
}
|
|
|
|
// Reset the counter
|
|
|
|
mArgc = 0;
|
|
|
|
}
|
2016-02-23 04:23:56 +01:00
|
|
|
|
2016-11-17 22:10:31 +01:00
|
|
|
/* ----------------------------------------------------------------------------------------
|
|
|
|
* Terminate the routine.
|
|
|
|
*/
|
|
|
|
void Terminate()
|
2016-03-12 07:47:50 +01:00
|
|
|
{
|
2016-11-17 22:10:31 +01:00
|
|
|
Release();
|
|
|
|
Clear();
|
2020-05-01 00:24:06 +02:00
|
|
|
// Don't attempt to terminate this routine again
|
|
|
|
mTerminated = true;
|
2016-03-12 07:47:50 +01:00
|
|
|
}
|
2016-11-17 22:10:31 +01:00
|
|
|
};
|
2016-02-23 04:23:56 +01:00
|
|
|
|
2016-03-12 07:47:50 +01:00
|
|
|
private:
|
2016-02-21 08:25:46 +01:00
|
|
|
|
2016-11-17 22:10:31 +01:00
|
|
|
// --------------------------------------------------------------------------------------------
|
|
|
|
static Time s_Last; // Last time point.
|
|
|
|
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.
|
2020-04-10 07:30:22 +02:00
|
|
|
static bool s_Silenced; // Error reporting independent from global setting.
|
2016-02-21 08:25:46 +01:00
|
|
|
|
2016-03-12 07:47:50 +01:00
|
|
|
private:
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* The index of the slot in the pool of active routines.
|
2016-05-22 05:20:38 +02:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
Uint32 m_Slot;
|
2016-03-12 07:47:50 +01:00
|
|
|
|
2016-11-17 22:10:31 +01:00
|
|
|
protected:
|
2016-03-12 07:47:50 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Default constructor.
|
2016-03-12 07:47:50 +01:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
Routine()
|
|
|
|
: m_Slot(SQMOD_MAX_ROUTINES)
|
|
|
|
{
|
|
|
|
/* ... */
|
|
|
|
}
|
2016-03-12 07:47:50 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Default constructor.
|
2016-03-12 07:47:50 +01:00
|
|
|
*/
|
2020-03-22 05:53:04 +01:00
|
|
|
explicit Routine(Uint32 slot)
|
2016-11-17 22:10:31 +01:00
|
|
|
: m_Slot(slot)
|
|
|
|
{
|
|
|
|
/* ... */
|
|
|
|
}
|
2016-03-12 07:47:50 +01:00
|
|
|
|
2020-03-22 05:53:04 +01:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Find an unoccupied routine slot.
|
|
|
|
*/
|
|
|
|
static SQInteger FindUnused()
|
|
|
|
{
|
|
|
|
for (const auto & r : s_Instances)
|
|
|
|
{
|
|
|
|
if (r.mInst.IsNull())
|
|
|
|
{
|
|
|
|
return (&r - s_Instances); // Return the index of this element
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// No available slot
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
2020-05-01 00:24:06 +02:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Default constructor.
|
|
|
|
*/
|
|
|
|
~Routine()
|
|
|
|
{
|
|
|
|
if (m_Slot < SQMOD_MAX_ROUTINES)
|
|
|
|
{
|
|
|
|
Terminate();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-24 17:47:18 +02:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Copy constructor. (disabled)
|
|
|
|
*/
|
|
|
|
Routine(const Routine & o) = delete;
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Move constructor. (disabled)
|
|
|
|
*/
|
|
|
|
Routine(Routine && o) = delete;
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Copy assignment operator. (disabled)
|
|
|
|
*/
|
|
|
|
Routine & operator = (const Routine & o) = delete;
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Move assignment operator. (disabled)
|
|
|
|
*/
|
|
|
|
Routine & operator = (Routine && o) = delete;
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Retrieve the number of used routine slots.
|
2016-08-24 17:47:18 +02:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
static SQInteger GetUsed()
|
2016-08-24 17:47:18 +02:00
|
|
|
{
|
2016-11-17 22:10:31 +01:00
|
|
|
SQInteger n = 0;
|
|
|
|
// Iterate routine list
|
|
|
|
for (const auto & r : s_Instances)
|
2016-11-16 12:12:49 +01:00
|
|
|
{
|
2016-11-17 22:10:31 +01:00
|
|
|
if (!r.mInst.IsNull())
|
|
|
|
{
|
|
|
|
++n;
|
|
|
|
}
|
2016-11-16 12:12:49 +01:00
|
|
|
}
|
2016-11-17 22:10:31 +01:00
|
|
|
// Return the final count
|
|
|
|
return n;
|
2016-08-24 17:47:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Retrieve the number of used routine slots.
|
2016-08-24 17:47:18 +02:00
|
|
|
*/
|
2019-02-17 16:23:59 +01:00
|
|
|
static const LightObj & FindByTag(StackStrF & tag)
|
2016-08-24 17:47:18 +02:00
|
|
|
{
|
2018-07-29 09:47:31 +02:00
|
|
|
// Is the specified tag valid?
|
2016-11-17 22:10:31 +01:00
|
|
|
if (!tag.mPtr)
|
2016-11-16 12:12:49 +01:00
|
|
|
{
|
2018-07-29 09:47:31 +02:00
|
|
|
STHROWF("Invalid routine tag");
|
2016-11-16 12:12:49 +01:00
|
|
|
}
|
2016-11-17 22:10:31 +01:00
|
|
|
// Iterate routine list
|
|
|
|
for (const auto & r : s_Instances)
|
2016-11-16 12:12:49 +01:00
|
|
|
{
|
2020-03-22 05:53:04 +01:00
|
|
|
if (!r.mInst.IsNull() && r.mTag == tag.mPtr)
|
2016-11-17 22:10:31 +01:00
|
|
|
{
|
|
|
|
return r.mInst; // Return this routine instance
|
|
|
|
}
|
2016-11-16 12:12:49 +01:00
|
|
|
}
|
2016-11-17 22:10:31 +01:00
|
|
|
// Unable to find such routine
|
|
|
|
STHROWF("Unable to find a routine with tag (%s)", tag.mPtr);
|
|
|
|
// Should not reach this point but if it did, we have to return something
|
2020-03-22 05:53:04 +01:00
|
|
|
#pragma clang diagnostic push
|
|
|
|
#pragma clang diagnostic ignored "-Warray-bounds"
|
2017-02-21 20:42:40 +01:00
|
|
|
return s_Instances[SQMOD_MAX_ROUTINES].mInst; // Intentional Buffer overflow!
|
2020-03-22 05:53:04 +01:00
|
|
|
#pragma clang diagnostic pop
|
2016-08-24 17:47:18 +02:00
|
|
|
}
|
2018-07-29 09:47:31 +02:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Check if a routine with a certain tag exists.
|
|
|
|
*/
|
2019-02-17 16:23:59 +01:00
|
|
|
static bool IsWithTag(StackStrF & tag);
|
2019-07-26 18:59:34 +02:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Check if a routine with a certain tag exists.
|
|
|
|
*/
|
|
|
|
static bool TerminateWithTag(StackStrF & tag);
|
2016-02-21 08:25:46 +01:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Process all active routines and update elapsed time.
|
2016-03-12 07:47:50 +01:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
static void Process();
|
2016-03-12 07:47:50 +01:00
|
|
|
|
2016-02-21 08:25:46 +01:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Initialize all resources and prepare for startup.
|
2016-05-22 05:20:38 +02:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
static void Initialize();
|
2016-05-22 05:20:38 +02:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Release all resources and prepare for shutdown.
|
2016-05-22 05:20:38 +02:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
static void Deinitialize();
|
2016-05-22 05:20:38 +02:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Create a routine with the specified parameters.
|
2016-05-22 05:20:38 +02:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
static SQInteger Create(HSQUIRRELVM vm);
|
2016-05-22 05:20:38 +02:00
|
|
|
|
2016-11-17 22:10:31 +01:00
|
|
|
protected:
|
2016-02-21 08:25:46 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* See whether this routine is valid otherwise throw an exception.
|
2016-02-21 08:25:46 +01:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
void Validate() const
|
|
|
|
{
|
|
|
|
if (m_Slot >= SQMOD_MAX_ROUTINES)
|
|
|
|
{
|
|
|
|
STHROWF("This instance does not reference a valid routine");
|
|
|
|
}
|
|
|
|
}
|
2016-02-21 08:25:46 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* See whether this routine is valid otherwise throw an exception.
|
2016-02-21 08:25:46 +01:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
Instance & GetValid() const
|
|
|
|
{
|
|
|
|
if (m_Slot >= SQMOD_MAX_ROUTINES)
|
|
|
|
{
|
|
|
|
STHROWF("This instance does not reference a valid routine");
|
|
|
|
}
|
|
|
|
// We know it's valid so let's return it
|
|
|
|
return s_Instances[m_Slot];
|
|
|
|
}
|
2016-02-21 08:25:46 +01:00
|
|
|
|
2016-11-17 22:10:31 +01:00
|
|
|
public:
|
2016-02-21 08:25:46 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Used by the script engine to convert an instance of this type to a string.
|
2016-02-21 08:25:46 +01:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
const String & ToString() const
|
|
|
|
{
|
|
|
|
return (m_Slot >= SQMOD_MAX_ROUTINES) ? NullString() : s_Instances[m_Slot].mTag;
|
|
|
|
}
|
2016-02-21 08:25:46 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Terminate the routine.
|
2016-02-21 08:25:46 +01:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
void Terminate()
|
|
|
|
{
|
|
|
|
GetValid().Terminate();
|
2020-04-30 22:27:24 +02:00
|
|
|
s_Intervals[m_Slot] = 0;
|
|
|
|
m_Slot = SQMOD_MAX_ROUTINES;
|
2016-11-17 22:10:31 +01:00
|
|
|
}
|
2016-02-21 08:25:46 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Retrieve the associated user tag.
|
2016-02-21 08:25:46 +01:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
const String & GetTag() const
|
|
|
|
{
|
|
|
|
return GetValid().mTag;
|
|
|
|
}
|
2016-02-21 08:25:46 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Modify the associated user tag.
|
2016-02-21 08:25:46 +01:00
|
|
|
*/
|
2019-02-17 16:23:59 +01:00
|
|
|
void SetTag(StackStrF & tag)
|
2016-11-17 22:10:31 +01:00
|
|
|
{
|
2020-03-22 05:53:04 +01:00
|
|
|
GetValid().mTag.assign(tag.mPtr, static_cast< size_t >(ClampMin(tag.mLen, 0)));
|
2016-11-17 22:10:31 +01:00
|
|
|
}
|
2016-02-21 08:25:46 +01:00
|
|
|
|
2019-07-26 18:59:34 +02:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Modify the associated user tag.
|
|
|
|
*/
|
|
|
|
Routine & ApplyTag(StackStrF & tag)
|
|
|
|
{
|
|
|
|
SetTag(tag);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2016-02-21 08:25:46 +01:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Retrieve the environment object.
|
2016-02-21 08:25:46 +01:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
const LightObj & GetEnv() const
|
|
|
|
{
|
|
|
|
return GetValid().mEnv;
|
|
|
|
}
|
2016-02-21 08:25:46 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Modify the environment object.
|
2016-02-21 08:25:46 +01:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
void SetEnv(const LightObj & env)
|
|
|
|
{
|
2020-04-17 16:42:09 +02:00
|
|
|
GetValid().mEnv = env.IsNull() ? LightObj(RootTable().GetObj()) : env;
|
2016-11-17 22:10:31 +01:00
|
|
|
}
|
2016-02-21 08:25:46 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Retrieve the function object.
|
2016-02-21 08:25:46 +01:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
const LightObj & GetFunc() const
|
|
|
|
{
|
|
|
|
return GetValid().mFunc;
|
|
|
|
}
|
2016-02-21 08:25:46 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Modify the function object.
|
2016-02-21 08:25:46 +01:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
void SetFunc(const Function & func)
|
|
|
|
{
|
|
|
|
// Validate the specified
|
|
|
|
if (!sq_isclosure(func.GetFunc()) && !sq_isnativeclosure(func.GetFunc()))
|
|
|
|
{
|
|
|
|
STHROWF("Invalid callback type %s", SqTypeName(GetValid().mFunc.GetType()));
|
|
|
|
}
|
|
|
|
// Store the function without the environment
|
|
|
|
GetValid().mFunc = LightObj(func.GetFunc());
|
|
|
|
}
|
2016-02-21 08:25:46 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Retrieve the arbitrary user data object.
|
2016-02-21 08:25:46 +01:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
const LightObj & GetData() const
|
|
|
|
{
|
|
|
|
return GetValid().mData;
|
|
|
|
}
|
2016-02-21 08:25:46 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Modify the arbitrary user data object.
|
2016-02-21 08:25:46 +01:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
void SetData(const LightObj & data)
|
|
|
|
{
|
|
|
|
GetValid().mData = data;
|
|
|
|
}
|
2016-03-12 07:47:50 +01:00
|
|
|
|
2019-06-01 21:49:24 +02:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Modify the arbitrary user data object.
|
|
|
|
*/
|
|
|
|
Routine & ApplyData(const LightObj & data)
|
|
|
|
{
|
|
|
|
SetData(data);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2016-03-12 07:47:50 +01:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Retrieve the execution interval.
|
2016-03-12 07:47:50 +01:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
SQInteger GetInterval() const
|
|
|
|
{
|
|
|
|
return ConvTo< SQInteger >::From(GetValid().mInterval);
|
|
|
|
}
|
2016-03-12 07:47:50 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Modify the execution interval.
|
2016-03-12 07:47:50 +01:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
void SetInterval(SQInteger itr)
|
|
|
|
{
|
|
|
|
GetValid().mInterval = ClampMin(ConvTo< Interval >::From(itr), static_cast< Interval >(0));
|
|
|
|
}
|
2016-03-12 07:47:50 +01:00
|
|
|
|
2019-06-01 21:49:24 +02:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Modify the execution interval.
|
|
|
|
*/
|
|
|
|
Routine & ApplyInterval(SQInteger itr)
|
|
|
|
{
|
|
|
|
SetInterval(itr);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2016-03-12 07:47:50 +01:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Retrieve the number of iterations.
|
2016-03-12 07:47:50 +01:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
SQInteger GetIterations() const
|
|
|
|
{
|
|
|
|
return ConvTo< SQInteger >::From(GetValid().mIterations);
|
|
|
|
}
|
2016-03-12 07:47:50 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Modify the number of iterations.
|
2016-03-12 07:47:50 +01:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
void SetIterations(SQInteger itr)
|
|
|
|
{
|
|
|
|
GetValid().mIterations = ConvTo< Iterator >::From(itr);
|
|
|
|
}
|
2016-03-12 07:47:50 +01:00
|
|
|
|
2019-06-01 21:49:24 +02:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Modify the number of iterations.
|
|
|
|
*/
|
|
|
|
Routine & ApplyIterations(SQInteger itr)
|
|
|
|
{
|
|
|
|
SetIterations(itr);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2016-03-12 07:47:50 +01:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* See whether the routine is suspended.
|
2016-03-12 07:47:50 +01:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
bool GetSuspended() const
|
|
|
|
{
|
|
|
|
return GetValid().mSuspended;
|
|
|
|
}
|
2016-03-12 07:47:50 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Set whether the routine should be suspended.
|
2016-03-12 07:47:50 +01:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
void SetSuspended(bool toggle)
|
|
|
|
{
|
|
|
|
GetValid().mSuspended = toggle;
|
|
|
|
}
|
2016-03-12 07:47:50 +01:00
|
|
|
|
2019-06-01 21:49:24 +02:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Set whether the routine should be suspended.
|
|
|
|
*/
|
|
|
|
Routine & ApplySuspended(bool toggle)
|
|
|
|
{
|
|
|
|
SetSuspended(toggle);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2018-01-28 21:45:09 +01:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* See whether the routine is quite.
|
|
|
|
*/
|
|
|
|
bool GetQuiet() const
|
|
|
|
{
|
|
|
|
return GetValid().mQuiet;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Set whether the routine should be quiet.
|
|
|
|
*/
|
|
|
|
void SetQuiet(bool toggle)
|
|
|
|
{
|
|
|
|
GetValid().mQuiet = toggle;
|
|
|
|
}
|
|
|
|
|
2019-06-01 21:49:24 +02:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Set whether the routine should be quiet.
|
|
|
|
*/
|
|
|
|
Routine & AppplyQuiet(bool toggle)
|
|
|
|
{
|
|
|
|
SetQuiet(toggle);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2018-01-28 21:45:09 +01:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* See whether the routine endures.
|
|
|
|
*/
|
|
|
|
bool GetEndure() const
|
|
|
|
{
|
|
|
|
return GetValid().mEndure;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Set whether the routine should endure.
|
|
|
|
*/
|
|
|
|
void SetEndure(bool toggle)
|
|
|
|
{
|
|
|
|
GetValid().mEndure = toggle;
|
|
|
|
}
|
|
|
|
|
2019-06-01 21:49:24 +02:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Set whether the routine should endure.
|
|
|
|
*/
|
|
|
|
Routine & ApplyEndure(bool toggle)
|
|
|
|
{
|
|
|
|
SetEndure(toggle);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2016-03-12 07:47:50 +01:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Retrieve the number of arguments to be forwarded.
|
2016-03-12 07:47:50 +01:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
SQInteger GetArguments() const
|
|
|
|
{
|
|
|
|
return ConvTo< SQInteger >::From(GetValid().mArgc);
|
|
|
|
}
|
2016-03-12 07:47:50 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-11-17 22:10:31 +01:00
|
|
|
* Retrieve a certain argument.
|
2016-03-12 07:47:50 +01:00
|
|
|
*/
|
2016-11-17 22:10:31 +01:00
|
|
|
const Argument & GetArgument(SQInteger arg) const
|
|
|
|
{
|
|
|
|
// Cast the index to the proper value
|
|
|
|
Uint8 idx = ConvTo< Uint8 >::From(arg);
|
|
|
|
// Validate the specified index
|
|
|
|
if (idx >= 14)
|
|
|
|
{
|
|
|
|
STHROWF("The specified index is out of range: %u >= %u", idx, 14);
|
|
|
|
}
|
|
|
|
// Return the requested argument
|
|
|
|
return GetValid().mArgv[idx];
|
|
|
|
}
|
2019-07-26 18:59:34 +02:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Release the environment object and default to self.
|
|
|
|
*/
|
|
|
|
void DropEnv()
|
|
|
|
{
|
|
|
|
GetValid().mEnv.Release();
|
|
|
|
}
|
2020-04-10 07:30:22 +02:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* See if error reporting is enabled for all newlly created routines.
|
|
|
|
*/
|
|
|
|
static bool GetSilenced()
|
|
|
|
{
|
|
|
|
return s_Silenced;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Set if error reporting should be enabled for all newlly created routines.
|
|
|
|
*/
|
|
|
|
static void SetSilenced(bool toggle)
|
|
|
|
{
|
|
|
|
s_Silenced = toggle;
|
|
|
|
}
|
2016-02-21 08:25:46 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
} // Namespace:: SqMod
|