mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 08:47:17 +01:00
Add another stack cleanup utility to the Sqrat library.
This commit is contained in:
parent
fccf288b77
commit
2e8d97f071
@ -1411,6 +1411,63 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Helper structure for popping elements from the stack.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
struct SqPopGuard
|
||||
{
|
||||
HSQUIRRELVM mVM; // The VM from which the elements must be popped.
|
||||
SQInteger mNum; // The number of elements to be popped.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Base constructor.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
SqPopGuard(HSQUIRRELVM vm, SQInteger num)
|
||||
: mVM(vm), mNum(num)
|
||||
{
|
||||
//...
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Destructor. Pops the specified elements from the stack.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
~SqPopGuard()
|
||||
{
|
||||
sq_pop(mVM, mNum);
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Increment the number of elements to be popped.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
SqPopGuard & operator ++ ()
|
||||
{
|
||||
++mNum;
|
||||
return *this;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Decrement the number of elements to be popped.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
SqPopGuard & operator -- ()
|
||||
{
|
||||
--mNum;
|
||||
return *this;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Increase the number of elements to be popped.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
SqPopGuard & operator += (SQInteger n)
|
||||
{
|
||||
mNum += n;
|
||||
return *this;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Decrease the number of elements to be popped.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
SqPopGuard & operator -= (SQInteger n)
|
||||
{
|
||||
mNum -= n;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Implements RAII to restore the VM stack to it's initial size on function exit.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -1721,6 +1778,97 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Helper structure used to make it easy to track instances of a certain type.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template < typename T > struct SqChainedInstances
|
||||
{
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Default constructor.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
SqChainedInstances()
|
||||
: m_Prev(nullptr), m_Next(nullptr)
|
||||
{
|
||||
//...
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
SqChainedInstances * m_Prev; // Previous instance in the chain.
|
||||
SqChainedInstances * m_Next; // Next instance in the chain.
|
||||
|
||||
static SqChainedInstances * s_Head; // The head of the instance chain.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Attach the instance to the chain.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void ChainInstance()
|
||||
{
|
||||
// Is there an existing head?
|
||||
if (s_Head == nullptr)
|
||||
{
|
||||
// There was no existing head
|
||||
m_Prev = m_Next = nullptr;
|
||||
// We're the head
|
||||
s_Head = this;
|
||||
}
|
||||
// Is there a preceding instance before the current head?
|
||||
else if (s_Head->m_Prev == nullptr)
|
||||
{
|
||||
// Grab the current head as the next instance in the chain
|
||||
m_Next = s_Head;
|
||||
// Become the new head and the preceding instance of the current head
|
||||
m_Next->m_Prev = s_Head = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Grab the current head as the next instance in the chain
|
||||
m_Next = s_Head;
|
||||
// Become the new head and the next instance of the preceding instance of the current head
|
||||
m_Next->m_Prev->m_Next = s_Head = this;
|
||||
// Become the preceding instance of the current head
|
||||
m_Next->m_Prev = this;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Detach the instance from the chain.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void UnchainInstance()
|
||||
{
|
||||
// Is there an instance after us?
|
||||
if (m_Next != nullptr)
|
||||
{
|
||||
// Link the next instance with the one before us
|
||||
m_Next->m_Prev = m_Prev;
|
||||
// Are we the current head?
|
||||
if (s_Head == this)
|
||||
{
|
||||
s_Head = m_Next; // Make the next one the head
|
||||
}
|
||||
}
|
||||
// Is there an instance before us?
|
||||
if (m_Prev != nullptr)
|
||||
{
|
||||
// Link the previous instance with the one after us
|
||||
m_Prev->m_Next = m_Next;
|
||||
// Are we the current head?
|
||||
if (s_Head == nullptr || s_Head == this)
|
||||
{
|
||||
// If there was no instance after us then make the previous one the head
|
||||
s_Head = m_Prev;
|
||||
}
|
||||
}
|
||||
// Are we the current and the only head?
|
||||
else if (s_Head == this)
|
||||
{
|
||||
s_Head = nullptr; // No more instances of this type
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T > SqChainedInstances< T > * SqChainedInstances< T >::s_Head = nullptr;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// @cond DEV
|
||||
/// Used internally to get and manipulate the underlying type of variables - retrieved from cppreference.com
|
||||
|
Loading…
Reference in New Issue
Block a user