1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-02-21 20:27:13 +01:00

Furher changes to the script function wrapper.

This commit is contained in:
Sandu Liviu Catalin 2018-08-02 18:33:52 +03:00
parent 4c111d4139
commit 52611bdb80

View File

@ -40,39 +40,36 @@
namespace Sqrat { namespace Sqrat {
// Represents a function in Squirrel // Represents a function in Squirrel
class Function { struct Function {
friend class TableBase; friend class TableBase;
friend class Table; friend class Table;
friend class ArrayBase; friend class ArrayBase;
friend struct Var<Function>; friend struct Var<Function>;
private: HSQOBJECT mEnv, mObj;
HSQOBJECT env, obj;
public:
// Default constructor (null) // Default constructor (null)
Function() noexcept { Function() noexcept {
sq_resetobject(&env); sq_resetobject(&mEnv);
sq_resetobject(&obj); sq_resetobject(&mObj);
} }
// Copy constructor // Copy constructor
Function(const Function& sf) noexcept : env(sf.env), obj(sf.obj) { Function(const Function& sf) noexcept : mEnv(sf.mEnv), mObj(sf.mObj) {
sq_addref(DefaultVM::Get_(), &env); sq_addref(DefaultVM::Get_(), &mEnv);
sq_addref(DefaultVM::Get_(), &obj); sq_addref(DefaultVM::Get_(), &mObj);
} }
// Move constructor // Move constructor
Function(Function&& sf) noexcept : env(sf.env), obj(sf.obj) { Function(Function&& sf) noexcept : mEnv(sf.mEnv), mObj(sf.mObj) {
sq_resetobject(&sf.GetEnv()); sq_resetobject(&sf.GetEnv());
sq_resetobject(&sf.GetFunc()); sq_resetobject(&sf.GetFunc());
} }
// Constructs a Function from a slot in an Object // Constructs a Function from a slot in an Object
Function(const Object& e, const SQChar* slot) : env(e.GetObject()) { Function(const Object& e, const SQChar* slot) : mEnv(e.GetObject()) {
sq_addref(DefaultVM::Get_(), &env); sq_addref(DefaultVM::Get_(), &mEnv);
Object so = e.GetSlot(slot); Object so = e.GetSlot(slot);
obj = so.GetObject(); mObj = so.GetObject();
sq_addref(DefaultVM::Get_(), &obj); sq_addref(DefaultVM::Get_(), &mObj);
#if !defined (SCRAT_NO_ERROR_CHECKING) #if !defined (SCRAT_NO_ERROR_CHECKING)
SQObjectType value_type = so.GetType(); SQObjectType value_type = so.GetType();
if (value_type != OT_CLOSURE && value_type != OT_NATIVECLOSURE) { if (value_type != OT_CLOSURE && value_type != OT_NATIVECLOSURE) {
@ -84,10 +81,10 @@ public:
// Constructs a Function from a value off the stack at the specified index // Constructs a Function from a value off the stack at the specified index
// Assumes the Function environment is at index 1. // Assumes the Function environment is at index 1.
Function(HSQUIRRELVM vm, SQInteger idx) { Function(HSQUIRRELVM vm, SQInteger idx) {
sq_getstackobj(vm, 1, &env); sq_getstackobj(vm, 1, &mEnv);
sq_getstackobj(vm, idx, &obj); sq_getstackobj(vm, idx, &mObj);
sq_addref(vm, &env); sq_addref(vm, &mEnv);
sq_addref(vm, &obj); sq_addref(vm, &mObj);
#if !defined (SCRAT_NO_ERROR_CHECKING) #if !defined (SCRAT_NO_ERROR_CHECKING)
SQObjectType value_type = sq_gettype(vm, idx); SQObjectType value_type = sq_gettype(vm, idx);
if (value_type != OT_CLOSURE && value_type != OT_NATIVECLOSURE) { if (value_type != OT_CLOSURE && value_type != OT_NATIVECLOSURE) {
@ -96,9 +93,9 @@ public:
#endif #endif
} }
// Constructs a Function from two Squirrel objects (one is the environment object and the other is the function object) // Constructs a Function from two Squirrel objects (one is the environment object and the other is the function object)
Function(HSQUIRRELVM vm, HSQOBJECT e, HSQOBJECT o) noexcept : env(e), obj(o) { Function(HSQUIRRELVM vm, HSQOBJECT e, HSQOBJECT o) noexcept : mEnv(e), mObj(o) {
sq_addref(vm, &env); sq_addref(vm, &mEnv);
sq_addref(vm, &obj); sq_addref(vm, &mObj);
} }
// Destructor // Destructor
~Function() { ~Function() {
@ -107,54 +104,54 @@ public:
// Copy Assignment operator // Copy Assignment operator
Function& operator=(const Function& sf) noexcept { Function& operator=(const Function& sf) noexcept {
Release(); Release();
env = sf.env; mEnv = sf.mEnv;
obj = sf.obj; mObj = sf.mObj;
if (!sf.IsNull()) { if (!sf.IsNull()) {
sq_addref(DefaultVM::Get_(), &env); sq_addref(DefaultVM::Get_(), &mEnv);
sq_addref(DefaultVM::Get_(), &obj); sq_addref(DefaultVM::Get_(), &mObj);
} }
return *this; return *this;
} }
// Move Assignment operator // Move Assignment operator
Function& operator=(Function&& sf) noexcept { Function& operator=(Function&& sf) noexcept {
Release(); Release();
env = sf.env; mEnv = sf.mEnv;
obj = sf.obj; mObj = sf.mObj;
sq_resetobject(&sf.GetEnv()); sq_resetobject(&sf.GetEnv());
sq_resetobject(&sf.GetFunc()); sq_resetobject(&sf.GetFunc());
return *this; return *this;
} }
// Checks whether the Function is null // Checks whether the Function is null
bool IsNull() const noexcept { bool IsNull() const noexcept {
return sq_isnull(obj); return sq_isnull(mObj);
} }
// Gets the Squirrel environment object for this Function (copy) // Gets the Squirrel environment object for this Function (copy)
HSQOBJECT GetEnv() const noexcept { HSQOBJECT GetEnv() const noexcept {
return env; return mEnv;
} }
// Gets the Squirrel environment object for this Function (reference) // Gets the Squirrel environment object for this Function (reference)
HSQOBJECT& GetEnv() noexcept { HSQOBJECT& GetEnv() noexcept {
return env; return mEnv;
} }
// Gets the Squirrel function object for this Function (copy) // Gets the Squirrel function object for this Function (copy)
HSQOBJECT GetFunc() const noexcept { HSQOBJECT GetFunc() const noexcept {
return obj; return mObj;
} }
// Gets the Squirrel function object for this Function (reference) // Gets the Squirrel function object for this Function (reference)
HSQOBJECT& GetFunc() noexcept { HSQOBJECT& GetFunc() noexcept {
return obj; return mObj;
} }
// Gets the Squirrel VM for this Function // Gets the Squirrel VM for this Function
HSQUIRRELVM & GetVM() const noexcept { HSQUIRRELVM GetVM() const noexcept {
return DefaultVM::Get_(); return DefaultVM::Get_();
} }
// Sets the Function to null (removing its references to underlying Squirrel objects) // Sets the Function to null (removing its references to underlying Squirrel objects)
void Release() noexcept { void Release() noexcept {
if(!IsNull()) { if(!IsNull()) {
sq_release(DefaultVM::Get_(), &env); sq_release(DefaultVM::Get_(), &mEnv);
sq_release(DefaultVM::Get_(), &obj); sq_release(DefaultVM::Get_(), &mObj);
sq_resetobject(&env); sq_resetobject(&mEnv);
sq_resetobject(&obj); sq_resetobject(&mObj);
} }
} }
// Sets the Function to null (removing its references to underlying Squirrel objects) // Sets the Function to null (removing its references to underlying Squirrel objects)
@ -162,12 +159,12 @@ public:
// Workaround for some weird squirrel behavior that generates an assert in debug mode. // Workaround for some weird squirrel behavior that generates an assert in debug mode.
void ReleaseGently() noexcept { void ReleaseGently() noexcept {
if(!IsNull()) { if(!IsNull()) {
sq_release(DefaultVM::Get_(), &env); sq_release(DefaultVM::Get_(), &mEnv);
if (sq_getrefcount(DefaultVM::Get_(), &obj) > 1) { if (sq_getrefcount(DefaultVM::Get_(), &mObj) > 1) {
sq_release(DefaultVM::Get_(), &obj); sq_release(DefaultVM::Get_(), &mObj);
} }
sq_resetobject(&env); sq_resetobject(&mEnv);
sq_resetobject(&obj); sq_resetobject(&mObj);
} }
} }
// Runs the Function and returns its value as a SharedPtr // Runs the Function and returns its value as a SharedPtr
@ -176,8 +173,8 @@ public:
HSQUIRRELVM vm = DefaultVM::Get_(); HSQUIRRELVM vm = DefaultVM::Get_();
SQInteger top = sq_gettop(vm); SQInteger top = sq_gettop(vm);
// Push the environment followed by the function // Push the environment followed by the function
sq_pushobject(vm, obj); sq_pushobject(vm, mObj);
sq_pushobject(vm, env); sq_pushobject(vm, mEnv);
// Validate the funtion parameter count // Validate the funtion parameter count
#if !defined (SCRAT_NO_ERROR_CHECKING) #if !defined (SCRAT_NO_ERROR_CHECKING)
SQUnsignedInteger nparams; SQUnsignedInteger nparams;
@ -215,8 +212,8 @@ public:
HSQUIRRELVM vm = DefaultVM::Get_(); HSQUIRRELVM vm = DefaultVM::Get_();
SQInteger top = sq_gettop(vm); SQInteger top = sq_gettop(vm);
// Push the environment followed by the function // Push the environment followed by the function
sq_pushobject(vm, obj); sq_pushobject(vm, mObj);
sq_pushobject(vm, env); sq_pushobject(vm, mEnv);
// Validate the funtion parameter count // Validate the funtion parameter count
#if !defined (SCRAT_NO_ERROR_CHECKING) #if !defined (SCRAT_NO_ERROR_CHECKING)
SQUnsignedInteger nparams; SQUnsignedInteger nparams;