mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 08:47:17 +01:00
Implement lightweight objects in the Sqrat binding utility that only store the object reference and don't use any firtual functions.
Also make a a few adjustments to the regular Object constructor.
This commit is contained in:
parent
32061463c0
commit
faf07319f9
@ -131,9 +131,18 @@ public:
|
|||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
template<class T>
|
template<class T>
|
||||||
Object(T* instance, HSQUIRRELVM v = DefaultVM::Get()) : vm(v), release(true) {
|
Object(T* instance, HSQUIRRELVM v = DefaultVM::Get()) : vm(v), release(true) {
|
||||||
|
// Preserve the stack state
|
||||||
|
const StackGuard sg(vm);
|
||||||
|
// Push the instance on the stack
|
||||||
ClassType<T>::PushInstance(vm, instance);
|
ClassType<T>::PushInstance(vm, instance);
|
||||||
sq_getstackobj(vm, -1, &obj);
|
// Attempt to retrieve it
|
||||||
sq_addref(vm, &obj);
|
if (SQ_FAILED(sq_getstackobj(vm, -1, &obj))) {
|
||||||
|
sq_resetobject(&obj);
|
||||||
|
// nothing to release anymore
|
||||||
|
release = false;
|
||||||
|
} else {
|
||||||
|
sq_addref(vm, &obj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -611,10 +620,7 @@ struct Var<Object> {
|
|||||||
/// This function MUST have its Error handled if it occurred.
|
/// This function MUST have its Error handled if it occurred.
|
||||||
///
|
///
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
Var(HSQUIRRELVM vm, SQInteger idx) {
|
Var(HSQUIRRELVM vm, SQInteger idx) : value(idx, vm) {
|
||||||
HSQOBJECT sqValue;
|
|
||||||
sq_getstackobj(vm, idx, &sqValue);
|
|
||||||
value = Object(sqValue, vm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -641,6 +647,241 @@ struct Var<Object&> : Var<Object> {Var(HSQUIRRELVM vm, SQInteger idx) : Var<Obje
|
|||||||
template<>
|
template<>
|
||||||
struct Var<const Object&> : Var<Object> {Var(HSQUIRRELVM vm, SQInteger idx) : Var<Object>(vm, idx) {}};
|
struct Var<const Object&> : Var<Object> {Var(HSQUIRRELVM vm, SQInteger idx) : Var<Object>(vm, idx) {}};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// A lightweight wrapper arround the Squirrel objects that implements RAII and still remains a POD type.
|
||||||
|
///
|
||||||
|
/// \remarks
|
||||||
|
/// All LightObject and derived classes MUST be destroyed before calling sq_close or your application will crash when exiting.
|
||||||
|
///
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
struct LightObject {
|
||||||
|
|
||||||
|
HSQOBJECT mObj;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Default constructor (null)
|
||||||
|
///
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
LightObject() {
|
||||||
|
sq_resetobject(&mObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Copy constructor
|
||||||
|
///
|
||||||
|
/// \param so LightObject to copy
|
||||||
|
///
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
LightObject(const LightObject& so) : mObj(so.mObj) {
|
||||||
|
sq_addref(DefaultVM::Get(), &mObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Move constructor
|
||||||
|
///
|
||||||
|
/// \param so LightObject to move
|
||||||
|
///
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
LightObject(LightObject&& so) : mObj(so.mObj) {
|
||||||
|
sq_resetobject(&so.mObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Constructs a LightObject from a Squirrel object
|
||||||
|
///
|
||||||
|
/// \param o Squirrel object
|
||||||
|
///
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
LightObject(HSQOBJECT o) : mObj(o) {
|
||||||
|
sq_addref(DefaultVM::Get(), &mObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Constructs a LightObject from a Squirrel object at a certain index on the stack
|
||||||
|
///
|
||||||
|
/// \param i Index of the Squirrel object on stack
|
||||||
|
/// \param v VM that the object will exist in
|
||||||
|
///
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
LightObject(SQInteger i, HSQUIRRELVM v = DefaultVM::Get()) {
|
||||||
|
if (SQ_FAILED(sq_getstackobj(v, i, &mObj))) {
|
||||||
|
sq_resetobject(&mObj);
|
||||||
|
} else {
|
||||||
|
sq_addref(v, &mObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Constructs an LightObject from a C++ instance
|
||||||
|
///
|
||||||
|
/// \param instance Pointer to a C++ class instance that has been bound already
|
||||||
|
/// \param v VM that the object will exist in
|
||||||
|
///
|
||||||
|
/// \tparam T Type of instance
|
||||||
|
///
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
template<class T>
|
||||||
|
LightObject(T* instance, HSQUIRRELVM v = DefaultVM::Get()) {
|
||||||
|
// Preserve the stack state
|
||||||
|
const StackGuard sg(v);
|
||||||
|
// Push the instance on the stack
|
||||||
|
ClassType<T>::PushInstance(v, instance);
|
||||||
|
// Attempt to retrieve it
|
||||||
|
if (SQ_FAILED(sq_getstackobj(v, -1, &mObj))) {
|
||||||
|
sq_resetobject(&mObj);
|
||||||
|
} else {
|
||||||
|
sq_addref(v, &mObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Destructor
|
||||||
|
///
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
~LightObject() {
|
||||||
|
Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Assignment operator
|
||||||
|
///
|
||||||
|
/// \param so LightObject to copy
|
||||||
|
///
|
||||||
|
/// \return The LightObject itself
|
||||||
|
///
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
LightObject& operator=(const LightObject& so) {
|
||||||
|
if (this != &so) {
|
||||||
|
Release();
|
||||||
|
mObj = so.mObj;
|
||||||
|
sq_addref(DefaultVM::Get(), &mObj);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Assignment operator
|
||||||
|
///
|
||||||
|
/// \param so LightObject to move
|
||||||
|
///
|
||||||
|
/// \return The LightObject itself
|
||||||
|
///
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
LightObject& operator=(LightObject&& so) {
|
||||||
|
if (this != &so) {
|
||||||
|
Release();
|
||||||
|
mObj = so.mObj;
|
||||||
|
sq_resetobject(&so.mObj);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Gets the type of the LightObject as defined by the Squirrel API
|
||||||
|
///
|
||||||
|
/// \return SQObjectType for the LightObject
|
||||||
|
///
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
SQObjectType GetType() const {
|
||||||
|
return mObj._type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Checks whether the LightObject is null
|
||||||
|
///
|
||||||
|
/// \return True if the LightObject currently has a null value, otherwise false
|
||||||
|
///
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool IsNull() const {
|
||||||
|
return sq_isnull(mObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Gets the Squirrel object for this LightObject (copy)
|
||||||
|
///
|
||||||
|
/// \return Squirrel object
|
||||||
|
///
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
virtual HSQOBJECT GetObject() const {
|
||||||
|
return mObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Gets the Squirrel object for this LightObject (reference)
|
||||||
|
///
|
||||||
|
/// \return Squirrel object
|
||||||
|
///
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
virtual HSQOBJECT& GetObject() {
|
||||||
|
return mObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Allows the LightObject to be inputted directly into places that expect a HSQOBJECT
|
||||||
|
///
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
operator HSQOBJECT&() {
|
||||||
|
return mObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Sets the LightObject to null (removing its references to underlying Squirrel objects)
|
||||||
|
///
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void Release() {
|
||||||
|
// Should we release any object?
|
||||||
|
if (!sq_isnull(mObj)) {
|
||||||
|
sq_release(DefaultVM::Get(), &mObj);
|
||||||
|
sq_resetobject(&mObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Used to get and push LightObject instances to and from the stack as references (LightObject is always a reference)
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
template<>
|
||||||
|
struct Var<LightObject> {
|
||||||
|
|
||||||
|
LightObject value; ///< The actual value of get operations
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Attempts to get the value off the stack at idx as an LightObject
|
||||||
|
///
|
||||||
|
/// \param vm Target VM
|
||||||
|
/// \param idx Index trying to be read
|
||||||
|
///
|
||||||
|
/// \remarks
|
||||||
|
/// This function MUST have its Error handled if it occurred.
|
||||||
|
///
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
Var(HSQUIRRELVM vm, SQInteger idx) : value(idx, vm) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Called by Sqrat::PushVar to put an LightObject on the stack
|
||||||
|
///
|
||||||
|
/// \param vm Target VM
|
||||||
|
/// \param value Value to push on to the VM's stack
|
||||||
|
///
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
static void push(HSQUIRRELVM vm, const LightObject& value) {
|
||||||
|
sq_pushobject(vm, value.mObj);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Used to get and push LightObject instances to and from the stack as references (LightObject is always a reference)
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
template<>
|
||||||
|
struct Var<LightObject&> : Var<LightObject> {Var(HSQUIRRELVM vm, SQInteger idx) : Var<LightObject>(vm, idx) {}};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Used to get and push LightObject instances to and from the stack as references (LightObject is always a reference)
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
template<>
|
||||||
|
struct Var<const LightObject&> : Var<LightObject> {Var(HSQUIRRELVM vm, SQInteger idx) : Var<LightObject>(vm, idx) {}};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user