mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 08:47:17 +01:00
Enhance the routine implementation further by allowing it to be used as the environment itself and include a few extra helpers to avoid extra checks and lookups.
This commit is contained in:
parent
aa976c7f89
commit
113d74e868
@ -16,15 +16,6 @@
|
|||||||
namespace SqMod {
|
namespace SqMod {
|
||||||
namespace Algo {
|
namespace Algo {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
#ifdef _WIN32
|
|
||||||
#define sqmod_stricmp(a,b) stricmp(a,b)
|
|
||||||
#define sqmod_strnicmp(a,b,n) strnicmp(a,b,n)
|
|
||||||
#else
|
|
||||||
#define sqmod_stricmp(a,b) strcasecmp(a,b)
|
|
||||||
#define sqmod_strnicmp(a,b,n) strncasecmp(a,b,n)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------------------------------
|
||||||
* Returns a pointer to the first occurrence of 'needle' in 'haystack'.
|
* Returns a pointer to the first occurrence of 'needle' in 'haystack'.
|
||||||
*/
|
*/
|
||||||
|
@ -108,8 +108,34 @@ SQInteger Routine::Create(HSQUIRRELVM vm)
|
|||||||
SQRESULT res = SQ_OK;
|
SQRESULT res = SQ_OK;
|
||||||
// Prepare an object for the environment
|
// Prepare an object for the environment
|
||||||
HSQOBJECT env;
|
HSQOBJECT env;
|
||||||
|
// Get the type of the environment object
|
||||||
|
const SQObjectType etype = sq_gettype(vm, 2);
|
||||||
|
// Whether to default to the root table
|
||||||
|
bool use_root = etype == OT_NULL;
|
||||||
|
// Is the specified environment a boolean (true) value?
|
||||||
|
if (etype == OT_STRING)
|
||||||
|
{
|
||||||
|
// Attempt to generate the string value
|
||||||
|
StackStrF val(vm, 2);
|
||||||
|
// Have we failed to retrieve the string?
|
||||||
|
if (SQ_FAILED(val.Proc()))
|
||||||
|
{
|
||||||
|
return val.mRes; // Propagate the error!
|
||||||
|
}
|
||||||
|
// If the string is empty or "root" then we use the root table
|
||||||
|
else if (!val.mLen || sqmod_stricmp(val.mPtr, "root") == 0)
|
||||||
|
{
|
||||||
|
use_root = true;
|
||||||
|
}
|
||||||
|
// If the string is "self" then we leave it null and default to self
|
||||||
|
else if (sqmod_stricmp(val.mPtr, "self") == 0)
|
||||||
|
{
|
||||||
|
sq_resetobject(&env); // Make sure environment is null
|
||||||
|
use_root = false; // Just in case
|
||||||
|
}
|
||||||
|
}
|
||||||
// Is the specified environment a null value?
|
// Is the specified environment a null value?
|
||||||
if (sq_gettype(vm, 2) == OT_NULL)
|
if (use_root)
|
||||||
{
|
{
|
||||||
// Preserve the stack state
|
// Preserve the stack state
|
||||||
const StackGuard sg(vm);
|
const StackGuard sg(vm);
|
||||||
@ -118,7 +144,8 @@ SQInteger Routine::Create(HSQUIRRELVM vm)
|
|||||||
// Attempt to retrieve the table object
|
// Attempt to retrieve the table object
|
||||||
res = sq_getstackobj(vm, -1, &env);
|
res = sq_getstackobj(vm, -1, &env);
|
||||||
}
|
}
|
||||||
else
|
// Should we treat it as a valid environment object?
|
||||||
|
else if (etype != OT_STRING)
|
||||||
{
|
{
|
||||||
sq_getstackobj(vm, 2, &env); // Just retrieve the specified environment
|
sq_getstackobj(vm, 2, &env); // Just retrieve the specified environment
|
||||||
}
|
}
|
||||||
@ -250,6 +277,26 @@ bool Routine::IsWithTag(StackStrF & tag)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
bool Routine::TerminateWithTag(StackStrF & tag)
|
||||||
|
{
|
||||||
|
// Is the specified tag valid?
|
||||||
|
if (tag.mPtr != nullptr)
|
||||||
|
{
|
||||||
|
// Iterate routine list
|
||||||
|
for (auto & r : s_Instances)
|
||||||
|
{
|
||||||
|
if (!r.mInst.IsNull() && r.mTag.compare(tag.mPtr) == 0)
|
||||||
|
{
|
||||||
|
r.Terminate(); // Yup, we're doing this
|
||||||
|
return true; // A routine was terminated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Unable to find such routine
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------------------------------
|
||||||
* Forward the call to process routines.
|
* Forward the call to process routines.
|
||||||
*/
|
*/
|
||||||
@ -294,7 +341,7 @@ void Register_Routine(HSQUIRRELVM vm)
|
|||||||
.Prop(_SC("Endure"), &Routine::GetEndure, &Routine::SetEndure)
|
.Prop(_SC("Endure"), &Routine::GetEndure, &Routine::SetEndure)
|
||||||
.Prop(_SC("Arguments"), &Routine::GetArguments)
|
.Prop(_SC("Arguments"), &Routine::GetArguments)
|
||||||
// Member Methods
|
// Member Methods
|
||||||
.FmtFunc(_SC("SetTag"), &Routine::SetTag)
|
.FmtFunc(_SC("SetTag"), &Routine::ApplyTag)
|
||||||
.Func(_SC("SetData"), &Routine::ApplyData)
|
.Func(_SC("SetData"), &Routine::ApplyData)
|
||||||
.Func(_SC("SetInterval"), &Routine::ApplyInterval)
|
.Func(_SC("SetInterval"), &Routine::ApplyInterval)
|
||||||
.Func(_SC("SetIterations"), &Routine::ApplyIterations)
|
.Func(_SC("SetIterations"), &Routine::ApplyIterations)
|
||||||
@ -303,11 +350,13 @@ void Register_Routine(HSQUIRRELVM vm)
|
|||||||
.Func(_SC("SetEndure"), &Routine::ApplyEndure)
|
.Func(_SC("SetEndure"), &Routine::ApplyEndure)
|
||||||
.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)
|
||||||
);
|
);
|
||||||
// Global functions
|
// Global functions
|
||||||
RootTable(vm).SquirrelFunc(_SC("SqRoutine"), &Routine::Create);
|
RootTable(vm).SquirrelFunc(_SC("SqRoutine"), &Routine::Create);
|
||||||
RootTable(vm).FmtFunc(_SC("SqFindRoutineByTag"), &Routine::FindByTag);
|
RootTable(vm).FmtFunc(_SC("SqFindRoutineByTag"), &Routine::FindByTag);
|
||||||
RootTable(vm).FmtFunc(_SC("SqIsRoutineWithTag"), &Routine::IsWithTag);
|
RootTable(vm).FmtFunc(_SC("SqIsRoutineWithTag"), &Routine::IsWithTag);
|
||||||
|
RootTable(vm).FmtFunc(_SC("SqTerminateRoutineWithTag"), &Routine::TerminateWithTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // Namespace:: SqMod
|
} // Namespace:: SqMod
|
||||||
|
@ -97,10 +97,19 @@ private:
|
|||||||
void Init(HSQOBJECT & env, HSQOBJECT & func, HSQOBJECT & inst, Interval intrv, Iterator itr)
|
void Init(HSQOBJECT & env, HSQOBJECT & func, HSQOBJECT & inst, Interval intrv, Iterator itr)
|
||||||
{
|
{
|
||||||
// Initialize the callback objects
|
// Initialize the callback objects
|
||||||
|
if (!sq_isnull(env))
|
||||||
|
{
|
||||||
mEnv = LightObj(env);
|
mEnv = LightObj(env);
|
||||||
|
}
|
||||||
|
if (!sq_isnull(func))
|
||||||
|
{
|
||||||
mFunc = LightObj(func);
|
mFunc = LightObj(func);
|
||||||
|
}
|
||||||
// Associate with the routine instance
|
// Associate with the routine instance
|
||||||
|
if (!sq_isnull(inst))
|
||||||
|
{
|
||||||
mInst = LightObj(inst);
|
mInst = LightObj(inst);
|
||||||
|
}
|
||||||
// Initialize the routine options
|
// Initialize the routine options
|
||||||
mIterations = itr;
|
mIterations = itr;
|
||||||
mInterval = intrv;
|
mInterval = intrv;
|
||||||
@ -138,7 +147,14 @@ private:
|
|||||||
// Push the function on the stack
|
// Push the function on the stack
|
||||||
sq_pushobject(vm, mFunc);
|
sq_pushobject(vm, mFunc);
|
||||||
// Push the environment on the stack
|
// Push the environment on the stack
|
||||||
sq_pushobject(vm, mEnv);
|
if (!mEnv.IsNull())
|
||||||
|
{
|
||||||
|
sq_pushobject(vm, mEnv); // Push object
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sq_pushobject(vm, mInst); // Push self
|
||||||
|
}
|
||||||
// Push function parameters, if any
|
// Push function parameters, if any
|
||||||
for (Uint32 n = 0; n < mArgc; ++n)
|
for (Uint32 n = 0; n < mArgc; ++n)
|
||||||
{
|
{
|
||||||
@ -309,6 +325,10 @@ public:
|
|||||||
* Check if a routine with a certain tag exists.
|
* Check if a routine with a certain tag exists.
|
||||||
*/
|
*/
|
||||||
static bool IsWithTag(StackStrF & tag);
|
static bool IsWithTag(StackStrF & tag);
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Check if a routine with a certain tag exists.
|
||||||
|
*/
|
||||||
|
static bool TerminateWithTag(StackStrF & tag);
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Process all active routines and update elapsed time.
|
* Process all active routines and update elapsed time.
|
||||||
*/
|
*/
|
||||||
@ -389,6 +409,15 @@ public:
|
|||||||
GetValid().mTag.assign(tag.mPtr, ClampMin(tag.mLen, 0));
|
GetValid().mTag.assign(tag.mPtr, ClampMin(tag.mLen, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Modify the associated user tag.
|
||||||
|
*/
|
||||||
|
Routine & ApplyTag(StackStrF & tag)
|
||||||
|
{
|
||||||
|
SetTag(tag);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Retrieve the environment object.
|
* Retrieve the environment object.
|
||||||
*/
|
*/
|
||||||
@ -600,6 +629,14 @@ public:
|
|||||||
// Return the requested argument
|
// Return the requested argument
|
||||||
return GetValid().mArgv[idx];
|
return GetValid().mArgv[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Release the environment object and default to self.
|
||||||
|
*/
|
||||||
|
void DropEnv()
|
||||||
|
{
|
||||||
|
GetValid().mEnv.Release();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Namespace:: SqMod
|
} // Namespace:: SqMod
|
||||||
|
@ -473,6 +473,15 @@ enum EntityType
|
|||||||
#define SQMOD_CONCAT_(a,b) a##b
|
#define SQMOD_CONCAT_(a,b) a##b
|
||||||
#define SQMOD_CONCAT(a,b) SQMOD_CONCAT_(a,b)
|
#define SQMOD_CONCAT(a,b) SQMOD_CONCAT_(a,b)
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define sqmod_stricmp(a,b) stricmp(a,b)
|
||||||
|
#define sqmod_strnicmp(a,b,n) strnicmp(a,b,n)
|
||||||
|
#else
|
||||||
|
#define sqmod_stricmp(a,b) strcasecmp(a,b)
|
||||||
|
#define sqmod_strnicmp(a,b,n) strncasecmp(a,b,n)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------------------------------
|
||||||
* OS SPECIFFIC OPTIONS
|
* OS SPECIFFIC OPTIONS
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user