mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 00:37:15 +01:00
Prevent issues with routine slot recycling.
Prevent possible memory leak on object creation exceptions. Other miscellaneous changes.
This commit is contained in:
parent
3e7adb8fea
commit
4a53ec8676
@ -136,12 +136,12 @@ SQInteger Routine::Create(HSQUIRRELVM vm)
|
|||||||
// Is the specified environment a null value?
|
// Is the specified environment a null value?
|
||||||
if (use_root)
|
if (use_root)
|
||||||
{
|
{
|
||||||
// Preserve the stack state
|
|
||||||
const StackGuard sg(vm);
|
|
||||||
// Push the root table on the stack
|
// Push the root table on the stack
|
||||||
sq_pushroottable(vm);
|
sq_pushroottable(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);
|
||||||
|
// Preserve the stack state
|
||||||
|
sq_poptop(vm);
|
||||||
}
|
}
|
||||||
// Should we treat it as a valid environment object?
|
// Should we treat it as a valid environment object?
|
||||||
else if (etype != OT_STRING)
|
else if (etype != OT_STRING)
|
||||||
@ -192,7 +192,9 @@ SQInteger Routine::Create(HSQUIRRELVM vm)
|
|||||||
// Attempt to create a routine instance
|
// Attempt to create a routine instance
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ClassType< Routine >::PushInstance(vm, new Routine());
|
DeleteGuard< Routine > dg(new Routine());
|
||||||
|
ClassType< Routine >::PushInstance(vm, dg.Get());
|
||||||
|
dg.Release();
|
||||||
}
|
}
|
||||||
catch (const Sqrat::Exception & e)
|
catch (const Sqrat::Exception & e)
|
||||||
{
|
{
|
||||||
|
@ -39,6 +39,7 @@ private:
|
|||||||
bool mSuspended; // Whether this instance is allowed to receive calls.
|
bool mSuspended; // Whether this instance is allowed to receive calls.
|
||||||
bool mQuiet; // Whether this instance is allowed to handle errors.
|
bool mQuiet; // Whether this instance is allowed to handle errors.
|
||||||
bool mEndure; // Whether this instance is allowed to terminate itself on errors.
|
bool mEndure; // Whether this instance is allowed to terminate itself on errors.
|
||||||
|
bool mTerminated; // Whether this instance is allowed to terminate itself on errors.
|
||||||
Uint8 mArgc; // The number of arguments that the routine must forward.
|
Uint8 mArgc; // 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.
|
||||||
|
|
||||||
@ -56,6 +57,7 @@ private:
|
|||||||
, mSuspended(false)
|
, mSuspended(false)
|
||||||
, mQuiet(GetSilenced())
|
, mQuiet(GetSilenced())
|
||||||
, mEndure(false)
|
, mEndure(false)
|
||||||
|
, mTerminated(false)
|
||||||
, mArgc(0)
|
, mArgc(0)
|
||||||
, mArgv()
|
, mArgv()
|
||||||
{
|
{
|
||||||
@ -96,19 +98,10 @@ 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};
|
||||||
{
|
mFunc = LightObj{func};
|
||||||
mEnv = LightObj(env);
|
|
||||||
}
|
|
||||||
if (!sq_isnull(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;
|
||||||
@ -167,14 +160,22 @@ private:
|
|||||||
if (SQ_FAILED(res))
|
if (SQ_FAILED(res))
|
||||||
{
|
{
|
||||||
// Should we endure the errors?
|
// Should we endure the errors?
|
||||||
if (!mEndure)
|
if (!mEndure && !mTerminated)
|
||||||
{
|
{
|
||||||
Terminate(); // Destroy ourself on error
|
Terminate(); // Destroy our self on error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
// Decrease the number of iterations if necessary
|
// Decrease the number of iterations if necessary
|
||||||
if (mIterations && (--mIterations) == 0)
|
else if (mIterations && (--mIterations) == 0)
|
||||||
{
|
{
|
||||||
Terminate(); // This routine reached the end of it's life
|
Terminate(); // This routine reached the end of it's life
|
||||||
}
|
}
|
||||||
@ -203,6 +204,8 @@ private:
|
|||||||
{
|
{
|
||||||
Release();
|
Release();
|
||||||
Clear();
|
Clear();
|
||||||
|
// Don't attempt to terminate this routine again
|
||||||
|
mTerminated = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -260,6 +263,17 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Default constructor.
|
||||||
|
*/
|
||||||
|
~Routine()
|
||||||
|
{
|
||||||
|
if (m_Slot < SQMOD_MAX_ROUTINES)
|
||||||
|
{
|
||||||
|
Terminate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------
|
||||||
* Copy constructor. (disabled)
|
* Copy constructor. (disabled)
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user