mirror of
				https://github.com/VCMP-SqMod/SqMod.git
				synced 2025-11-04 00:07:19 +01:00 
			
		
		
		
	Fix routines once and forever.
By simply preventing reuse of slots that have been terminated during their execution.
This commit is contained in:
		@@ -39,7 +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 was terminated once.
 | 
					        bool        mExecuting; // Whether this instance is currently being executed.
 | 
				
			||||||
        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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -57,7 +57,7 @@ private:
 | 
				
			|||||||
            , mSuspended(false)
 | 
					            , mSuspended(false)
 | 
				
			||||||
            , mQuiet(GetSilenced())
 | 
					            , mQuiet(GetSilenced())
 | 
				
			||||||
            , mEndure(false)
 | 
					            , mEndure(false)
 | 
				
			||||||
            , mTerminated(false)
 | 
					            , mExecuting(false)
 | 
				
			||||||
            , mArgc(0)
 | 
					            , mArgc(0)
 | 
				
			||||||
            , mArgv()
 | 
					            , mArgv()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -105,6 +105,8 @@ private:
 | 
				
			|||||||
            // Initialize the routine options
 | 
					            // Initialize the routine options
 | 
				
			||||||
            mIterations = itr;
 | 
					            mIterations = itr;
 | 
				
			||||||
            mInterval = intrv;
 | 
					            mInterval = intrv;
 | 
				
			||||||
 | 
					            // This can't be true now
 | 
				
			||||||
 | 
					            mExecuting = false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* ----------------------------------------------------------------------------------------
 | 
					        /* ----------------------------------------------------------------------------------------
 | 
				
			||||||
@@ -126,7 +128,7 @@ private:
 | 
				
			|||||||
        */
 | 
					        */
 | 
				
			||||||
        Interval Execute()
 | 
					        Interval Execute()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            // is this even a valid routine?
 | 
					            // Is this even a valid routine?
 | 
				
			||||||
            if (mInst.IsNull())
 | 
					            if (mInst.IsNull())
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return 0; // Dunno how we got here but it ends now
 | 
					                return 0; // Dunno how we got here but it ends now
 | 
				
			||||||
@@ -152,30 +154,26 @@ private:
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    sq_pushobject(vm, mArgv[n].mObj);
 | 
					                    sq_pushobject(vm, mArgv[n].mObj);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					                // This routine is currently executing
 | 
				
			||||||
 | 
					                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 >(false), static_cast< SQBool >(!mQuiet));
 | 
				
			||||||
 | 
					                // This routine has finished executing
 | 
				
			||||||
 | 
					                mExecuting = false;
 | 
				
			||||||
                // 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
 | 
				
			||||||
                if (SQ_FAILED(res))
 | 
					                if (SQ_FAILED(res))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    // Should we endure the errors?
 | 
					                    // Should we endure the errors?
 | 
				
			||||||
                    if (!mEndure && !mTerminated)
 | 
					                    if (!mEndure)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        Terminate(); // Destroy our self 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
 | 
				
			||||||
            else if (mIterations && (--mIterations) == 0)
 | 
					            if (mIterations && (--mIterations) == 0)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                Terminate(); // This routine reached the end of it's life
 | 
					                Terminate(); // This routine reached the end of it's life
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -204,8 +202,6 @@ private:
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            Release();
 | 
					            Release();
 | 
				
			||||||
            Clear();
 | 
					            Clear();
 | 
				
			||||||
            // Don't attempt to terminate this routine again
 | 
					 | 
				
			||||||
            mTerminated = true;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -252,7 +248,8 @@ protected:
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        for (const auto & r : s_Instances)
 | 
					        for (const auto & r : s_Instances)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (r.mInst.IsNull())
 | 
					            // Either not used or not currently being executing
 | 
				
			||||||
 | 
					            if (r.mInst.IsNull() && !(r.mExecuting))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return (&r - s_Instances); // Return the index of this element
 | 
					                return (&r - s_Instances); // Return the index of this element
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user