2021-01-30 07:51:39 +01:00
|
|
|
//
|
|
|
|
// SqratTable: Table Binding
|
|
|
|
//
|
|
|
|
|
|
|
|
//
|
|
|
|
// Copyright (c) 2009 Brandon Jones
|
|
|
|
//
|
|
|
|
// This software is provided 'as-is', without any express or implied
|
|
|
|
// warranty. In no event will the authors be held liable for any damages
|
|
|
|
// arising from the use of this software.
|
|
|
|
//
|
|
|
|
// Permission is granted to anyone to use this software for any purpose,
|
|
|
|
// including commercial applications, and to alter it and redistribute it
|
|
|
|
// freely, subject to the following restrictions:
|
|
|
|
//
|
|
|
|
// 1. The origin of this software must not be misrepresented; you must not
|
|
|
|
// claim that you wrote the original software. If you use this software
|
|
|
|
// in a product, an acknowledgment in the product documentation would be
|
|
|
|
// appreciated but is not required.
|
|
|
|
//
|
|
|
|
// 2. Altered source versions must be plainly marked as such, and must not be
|
|
|
|
// misrepresented as being the original software.
|
|
|
|
//
|
|
|
|
// 3. This notice may not be removed or altered from any source
|
|
|
|
// distribution.
|
|
|
|
//
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <squirrelex.h>
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "sqratObject.h"
|
|
|
|
#include "sqratFunction.h"
|
|
|
|
#include "sqratGlobalMethods.h"
|
|
|
|
|
|
|
|
namespace Sqrat {
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// The base class for Table that implements almost all of its functionality
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
class TableBase : public Object {
|
|
|
|
public:
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Default constructor (null)
|
|
|
|
///
|
|
|
|
/// \param v VM that the table will exist in
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
TableBase() : Object(true) {
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Construct the TableBase from an Object that already exists
|
|
|
|
///
|
|
|
|
/// \param obj An Object that should already represent a Squirrel table
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
TableBase(const Object& obj) : Object(obj) {
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Construct the TableBase from an Object that already exists
|
|
|
|
///
|
|
|
|
/// \param obj An Object that should already represent a Squirrel table
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
2021-03-20 10:49:02 +01:00
|
|
|
TableBase(Object&& obj) noexcept : Object(std::move(obj)) {
|
2021-01-30 07:51:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Construct the TableBase from an Object that already exists
|
|
|
|
///
|
|
|
|
/// \param obj An Object that should already represent a Squirrel table
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
TableBase(const LightObj& obj) : Object(obj) {
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Construct the TableBase from an Object that already exists
|
|
|
|
///
|
|
|
|
/// \param obj An Object that should already represent a Squirrel table
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
2021-03-20 10:49:02 +01:00
|
|
|
TableBase(LightObj&& obj) : Object(std::move(obj)) {
|
2021-01-30 07:51:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Construct the TableBase from a HSQOBJECT and HSQUIRRELVM that already exist
|
|
|
|
///
|
|
|
|
/// \param o Squirrel object that should already represent a Squirrel table
|
|
|
|
/// \param v Squirrel VM that contains the Squirrel object given
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
TableBase(HSQOBJECT o, HSQUIRRELVM v = SqVM()) : Object(o, v) {
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Copy constructor
|
|
|
|
///
|
|
|
|
/// \param st TableBase to copy
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
TableBase(const TableBase& st) : Object(st) {
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Move constructor
|
|
|
|
///
|
|
|
|
/// \param st TableBase to move
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
2021-03-20 10:49:02 +01:00
|
|
|
TableBase(TableBase&& st) noexcept : Object(std::move(st)) {
|
2021-01-30 07:51:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Assignment operator
|
|
|
|
///
|
|
|
|
/// \param st TableBase to copy
|
|
|
|
///
|
|
|
|
/// \return The TableBase itself
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
TableBase& operator=(const TableBase& st) {
|
|
|
|
Object::operator = (st);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Assignment operator
|
|
|
|
///
|
|
|
|
/// \param st TableBase to move
|
|
|
|
///
|
|
|
|
/// \return The TableBase itself
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
TableBase& operator=(TableBase&& st) noexcept {
|
2021-03-20 10:49:02 +01:00
|
|
|
Object::operator = (std::move(st));
|
2021-01-30 07:51:39 +01:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Binds a Table or Class to the Table (can be used to facilitate namespaces)
|
|
|
|
///
|
|
|
|
/// \param name The key in the table being assigned a Table or Class
|
|
|
|
/// \param obj Table or Class that is being placed in the table
|
|
|
|
///
|
|
|
|
/// \remarks
|
|
|
|
/// Bind cannot be called "inline" like other functions because it introduces order-of-initialization bugs.
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void Bind(const SQChar* name, Object& obj) {
|
|
|
|
HSQUIRRELVM vm = SqVM();
|
|
|
|
sq_pushobject(vm, GetObj());
|
|
|
|
sq_pushstring(vm, name, -1);
|
|
|
|
sq_pushobject(vm, obj.GetObj());
|
|
|
|
sq_newslot(vm, -3, false);
|
|
|
|
sq_pop(vm,1); // pop table
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Binds a Table or Class to the Table (can be used to facilitate namespaces)
|
|
|
|
///
|
|
|
|
/// \param name The key in the table being assigned a Table or Class
|
|
|
|
/// \param obj Table or Class that is being placed in the table
|
|
|
|
///
|
|
|
|
/// \remarks
|
|
|
|
/// Bind cannot be called "inline" like other functions because it introduces order-of-initialization bugs.
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void Bind(const SQChar* name, LightObj& obj) {
|
|
|
|
HSQUIRRELVM vm = SqVM();
|
|
|
|
sq_pushobject(vm, GetObj());
|
|
|
|
sq_pushstring(vm, name, -1);
|
|
|
|
sq_pushobject(vm, obj.GetObj());
|
|
|
|
sq_newslot(vm, -3, false);
|
|
|
|
sq_pop(vm,1); // pop table
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Binds a raw Squirrel closure to the Table
|
|
|
|
///
|
|
|
|
/// \param name The key in the table being assigned a function
|
|
|
|
/// \param func Squirrel function that is being placed in the Table
|
|
|
|
///
|
|
|
|
/// \return The Table itself so the call can be chained
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
TableBase& SquirrelFunc(const SQChar* name, SQFUNCTION func) {
|
|
|
|
HSQUIRRELVM vm = SqVM();
|
|
|
|
sq_pushobject(vm, GetObj());
|
|
|
|
sq_pushstring(vm, name, -1);
|
|
|
|
sq_newclosure(vm, func, 0);
|
|
|
|
// Set the closure name (for debug purposes)
|
|
|
|
sq_setnativeclosurename(vm, -1, name);
|
|
|
|
sq_newslot(vm, -3, false);
|
|
|
|
sq_pop(vm,1); // pop table
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Binds a raw Squirrel closure to the Table
|
|
|
|
///
|
|
|
|
/// \param name The key in the table being assigned a function
|
|
|
|
/// \param func Squirrel function that is being placed in the Table
|
|
|
|
/// \param pnum Number of parameters the function expects.
|
|
|
|
/// \param mask Types of parameters the function expects.
|
|
|
|
///
|
|
|
|
/// \return The Table itself so the call can be chained
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
TableBase& SquirrelFunc(const SQChar* name, SQFUNCTION func, SQInteger pnum, const SQChar * mask) {
|
|
|
|
HSQUIRRELVM vm = SqVM();
|
|
|
|
sq_pushobject(vm, GetObj());
|
|
|
|
sq_pushstring(vm, name, -1);
|
|
|
|
sq_newclosure(vm, func, 0);
|
|
|
|
// Set the closure name (for debug purposes)
|
|
|
|
sq_setnativeclosurename(vm, -1, name);
|
|
|
|
// Set parameter validation
|
|
|
|
sq_setparamscheck(vm, pnum, mask);
|
|
|
|
sq_newslot(vm, -3, false);
|
|
|
|
sq_pop(vm,1); // pop table
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Sets a key in the Table to a specific value
|
|
|
|
///
|
|
|
|
/// \param name The key in the table being assigned a value
|
|
|
|
/// \param val Value that is being placed in the Table
|
|
|
|
///
|
|
|
|
/// \tparam V Type of value (usually doesnt need to be defined explicitly)
|
|
|
|
///
|
|
|
|
/// \return The Table itself so the call can be chained
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
template<class V>
|
|
|
|
TableBase& SetValue(const SQChar* name, const V& val) {
|
|
|
|
BindValue<V>(name, val, false);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Sets an index in the Table to a specific value
|
|
|
|
///
|
|
|
|
/// \param index The index in the table being assigned a value
|
|
|
|
/// \param val Value that is being placed in the Table
|
|
|
|
///
|
|
|
|
/// \tparam V Type of value (usually doesnt need to be defined explicitly)
|
|
|
|
///
|
|
|
|
/// \return The Table itself so the call can be chained
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
template<class V>
|
|
|
|
TableBase& SetValue(const SQInteger index, const V& val) {
|
|
|
|
BindValue<V>(index, val, false);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Sets a key in the Table to a specific instance (like a reference)
|
|
|
|
///
|
|
|
|
/// \param name The key in the table being assigned a value
|
|
|
|
/// \param val Pointer to the instance that is being placed in the Table
|
|
|
|
///
|
|
|
|
/// \tparam V Type of instance (usually doesnt need to be defined explicitly)
|
|
|
|
///
|
|
|
|
/// \return The Table itself so the call can be chained
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
template<class V>
|
|
|
|
TableBase& SetInstance(const SQChar* name, V* val) {
|
|
|
|
BindInstance<V>(name, val, false);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Sets an index in the Table to a specific instance (like a reference)
|
|
|
|
///
|
|
|
|
/// \param index The index in the table being assigned a value
|
|
|
|
/// \param val Pointer to the instance that is being placed in the Table
|
|
|
|
///
|
|
|
|
/// \tparam V Type of instance (usually doesnt need to be defined explicitly)
|
|
|
|
///
|
|
|
|
/// \return The Table itself so the call can be chained
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
template<class V>
|
|
|
|
TableBase& SetInstance(const SQInteger index, V* val) {
|
|
|
|
BindInstance<V>(index, val, false);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Sets a key in the Table to a specific function
|
|
|
|
///
|
|
|
|
/// \param name The key in the table being assigned a value
|
|
|
|
/// \param method Function that is being placed in the Table
|
|
|
|
///
|
|
|
|
/// \tparam F Type of function (only define this if you need to choose a certain template specialization or overload)
|
|
|
|
///
|
|
|
|
/// \return The Table itself so the call can be chained
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
template<class F>
|
|
|
|
TableBase& Func(const SQChar* name, F method) {
|
|
|
|
BindFunc(name, &method, sizeof(method), SqGlobalFunc(method));
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Sets a key in the Table to a specific function with formatting support
|
|
|
|
///
|
|
|
|
/// \param name The key in the table being assigned a value
|
|
|
|
/// \param method Function that is being placed in the Table
|
|
|
|
///
|
|
|
|
/// \tparam F Type of function (only define this if you need to choose a certain template specialization or overload)
|
|
|
|
///
|
|
|
|
/// \return The Table itself so the call can be chained
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
template<class F>
|
|
|
|
TableBase& FmtFunc(const SQChar* name, F method) {
|
|
|
|
BindFunc(name, &method, sizeof(method), SqGlobalFunc(method));
|
|
|
|
return *this;
|
|
|
|
}
|
2021-07-03 18:46:39 +02:00
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Sets a key in the Table to a specific function with callback support
|
|
|
|
///
|
|
|
|
/// \param name The key in the table being assigned a value
|
|
|
|
/// \param method Function that is being placed in the Table
|
|
|
|
///
|
|
|
|
/// \tparam F Type of function (only define this if you need to choose a certain template specialization or overload)
|
|
|
|
///
|
|
|
|
/// \return The Table itself so the call can be chained
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
template<class F>
|
|
|
|
TableBase& CbFunc(const SQChar* name, F method) {
|
|
|
|
BindFunc(name, &method, sizeof(method), SqGlobalFunc(method));
|
|
|
|
return *this;
|
|
|
|
}
|
2021-01-30 07:51:39 +01:00
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Sets a key in the Table to a specific function and allows the key to be overloaded with functions of a different amount of arguments
|
|
|
|
///
|
|
|
|
/// \param name The key in the table being assigned a value
|
|
|
|
/// \param method Function that is being placed in the Table
|
|
|
|
///
|
|
|
|
/// \tparam F Type of function (only define this if you need to choose a certain template specialization or overload)
|
|
|
|
///
|
|
|
|
/// \return The Table itself so the call can be chained
|
|
|
|
///
|
|
|
|
/// \remarks
|
|
|
|
/// Overloading in Sqrat does not work for functions with the same amount of arguments (just like in Squirrel).
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
template<class F>
|
|
|
|
TableBase& Overload(const SQChar* name, F method) {
|
|
|
|
BindOverload(name, &method, sizeof(method), SqGlobalOverloadedFunc(method), SqOverloadFunc(method), SqGetArgCount(method));
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Checks if the given key exists in the table
|
|
|
|
///
|
|
|
|
/// \param name Key to check
|
|
|
|
///
|
|
|
|
/// \return True on success, otherwise false
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool HasKey(const SQChar* name) {
|
|
|
|
HSQUIRRELVM vm = SqVM();
|
|
|
|
sq_pushobject(vm, mObj);
|
|
|
|
sq_pushstring(vm, name, -1);
|
|
|
|
if (SQ_FAILED(sq_get(vm, -2))) {
|
|
|
|
sq_pop(vm, 1);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
sq_pop(vm, 2);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Returns the value at a given key
|
|
|
|
///
|
|
|
|
/// \param name Key of the element
|
|
|
|
///
|
|
|
|
/// \tparam T Type of value (fails if value is not of this type)
|
|
|
|
///
|
|
|
|
/// \return SharedPtr containing the value (or null if failed)
|
|
|
|
///
|
|
|
|
/// \remarks
|
|
|
|
/// This function MUST have its Error handled if it occurred.
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
template <typename T>
|
|
|
|
SharedPtr<T> GetValue(const SQChar* name) {
|
|
|
|
HSQUIRRELVM vm = SqVM();
|
|
|
|
sq_pushobject(vm, mObj);
|
|
|
|
sq_pushstring(vm, name, -1);
|
|
|
|
#if !defined (SCRAT_NO_ERROR_CHECKING)
|
|
|
|
if (SQ_FAILED(sq_get(vm, -2))) {
|
|
|
|
sq_pop(vm, 1);
|
|
|
|
SQTHROW(vm, _SC("illegal index"));
|
|
|
|
return SharedPtr<T>();
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
sq_get(vm, -2);
|
|
|
|
#endif
|
|
|
|
SQTRY()
|
|
|
|
Var<SharedPtr<T> > entry(vm, -1);
|
|
|
|
SQCATCH_NOEXCEPT(vm) {
|
|
|
|
sq_pop(vm, 2);
|
|
|
|
return SharedPtr<T>();
|
|
|
|
}
|
|
|
|
sq_pop(vm, 2);
|
|
|
|
return entry.value;
|
|
|
|
SQCATCH(vm) {
|
|
|
|
#if defined (SCRAT_USE_EXCEPTIONS)
|
|
|
|
SQUNUSED(e); // avoid "unreferenced local variable" warning
|
|
|
|
#endif
|
|
|
|
sq_pop(vm, 2);
|
|
|
|
SQRETHROW(vm);
|
|
|
|
}
|
|
|
|
return SharedPtr<T>(); // avoid "not all control paths return a value" warning
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Returns the value at a given index
|
|
|
|
///
|
|
|
|
/// \param index Index of the element
|
|
|
|
///
|
|
|
|
/// \tparam T Type of value (fails if value is not of this type)
|
|
|
|
///
|
|
|
|
/// \return SharedPtr containing the value (or null if failed)
|
|
|
|
///
|
|
|
|
/// \remarks
|
|
|
|
/// This function MUST have its Error handled if it occurred.
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
template <typename T>
|
|
|
|
SharedPtr<T> GetValue(int index) {
|
|
|
|
HSQUIRRELVM vm = SqVM();
|
|
|
|
sq_pushobject(vm, mObj);
|
|
|
|
sq_pushinteger(vm, index);
|
|
|
|
#if !defined (SCRAT_NO_ERROR_CHECKING)
|
|
|
|
if (SQ_FAILED(sq_get(vm, -2))) {
|
|
|
|
sq_pop(vm, 1);
|
|
|
|
SQTHROW(vm, _SC("illegal index"));
|
|
|
|
return SharedPtr<T>();
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
sq_get(vm, -2);
|
|
|
|
#endif
|
|
|
|
SQTRY()
|
|
|
|
Var<SharedPtr<T> > entry(vm, -1);
|
|
|
|
SQCATCH_NOEXCEPT(vm) {
|
|
|
|
sq_pop(vm, 2);
|
|
|
|
return SharedPtr<T>();
|
|
|
|
}
|
|
|
|
sq_pop(vm, 2);
|
|
|
|
return entry.value;
|
|
|
|
SQCATCH(vm) {
|
|
|
|
#if defined (SCRAT_USE_EXCEPTIONS)
|
|
|
|
SQUNUSED(e); // avoid "unreferenced local variable" warning
|
|
|
|
#endif
|
|
|
|
sq_pop(vm, 2);
|
|
|
|
SQRETHROW(vm);
|
|
|
|
}
|
|
|
|
return SharedPtr<T>(); // avoid "not all control paths return a value" warning
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Gets a Function from a key in the Table
|
|
|
|
///
|
|
|
|
/// \param name The key in the table that contains the Function
|
|
|
|
///
|
|
|
|
/// \return Function found in the Table (null if failed)
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
Function GetFunction(const SQChar* name) {
|
|
|
|
HSQUIRRELVM vm = SqVM();
|
|
|
|
HSQOBJECT funcObj;
|
|
|
|
sq_pushobject(vm, GetObj());
|
|
|
|
sq_pushstring(vm, name, -1);
|
|
|
|
#if !defined (SCRAT_NO_ERROR_CHECKING)
|
|
|
|
if(SQ_FAILED(sq_get(vm, -2))) {
|
|
|
|
sq_pop(vm, 1);
|
|
|
|
return Function();
|
|
|
|
}
|
|
|
|
SQObjectType value_type = sq_gettype(vm, -1);
|
|
|
|
if (value_type != OT_CLOSURE && value_type != OT_NATIVECLOSURE) {
|
|
|
|
sq_pop(vm, 2);
|
|
|
|
return Function();
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
sq_get(vm, -2);
|
|
|
|
#endif
|
|
|
|
sq_getstackobj(vm, -1, &funcObj);
|
|
|
|
Function ret(GetObj(), funcObj, vm); // must addref before the pop!
|
|
|
|
sq_pop(vm, 2);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Gets a Function from an index in the Table
|
|
|
|
///
|
|
|
|
/// \param index The index in the table that contains the Function
|
|
|
|
///
|
|
|
|
/// \return Function found in the Table (null if failed)
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
Function GetFunction(const SQInteger index) {
|
|
|
|
HSQUIRRELVM vm = SqVM();
|
|
|
|
HSQOBJECT funcObj;
|
|
|
|
sq_pushobject(vm, GetObj());
|
|
|
|
sq_pushinteger(vm, index);
|
|
|
|
#if !defined (SCRAT_NO_ERROR_CHECKING)
|
|
|
|
if(SQ_FAILED(sq_get(vm, -2))) {
|
|
|
|
sq_pop(vm, 1);
|
|
|
|
return Function();
|
|
|
|
}
|
|
|
|
SQObjectType value_type = sq_gettype(vm, -1);
|
|
|
|
if (value_type != OT_CLOSURE && value_type != OT_NATIVECLOSURE) {
|
|
|
|
sq_pop(vm, 2);
|
|
|
|
return Function();
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
sq_get(vm, -2);
|
|
|
|
#endif
|
|
|
|
sq_getstackobj(vm, -1, &funcObj);
|
|
|
|
Function ret(GetObj(), funcObj, vm); // must addref before the pop!
|
|
|
|
sq_pop(vm, 2);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Represents a table in Squirrel
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
class Table : public TableBase {
|
|
|
|
public:
|
|
|
|
using TableBase::TableBase;
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Default constructor (null)
|
|
|
|
///
|
|
|
|
/// \remarks
|
|
|
|
/// The Table is invalid until it is given a VM to exist in.
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
Table() : TableBase() {
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Constructs a Table
|
|
|
|
///
|
|
|
|
/// \param v VM to create the Table in
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
Table(HSQUIRRELVM vm) : TableBase() {
|
|
|
|
sq_newtable(vm);
|
|
|
|
sq_getstackobj(vm,-1,&mObj);
|
|
|
|
sq_addref(vm, &mObj);
|
|
|
|
sq_pop(vm,1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Construct the Table from an Object that already exists
|
|
|
|
///
|
|
|
|
/// \param obj An Object that should already represent a Squirrel table
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
Table(const Object& obj) : TableBase(obj) {
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Construct the Table from an Object that already exists
|
|
|
|
///
|
|
|
|
/// \param obj An Object that should already represent a Squirrel table
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
2021-03-20 10:49:02 +01:00
|
|
|
Table(Object&& obj) noexcept : TableBase(std::move(obj)) {
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Construct the Table from an LightObj that already exists
|
|
|
|
///
|
|
|
|
/// \param obj An LightObj that should already represent a Squirrel table
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
Table(const LightObj& obj) : TableBase(obj) {
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Construct the Table from an LightObj that already exists
|
|
|
|
///
|
|
|
|
/// \param obj An LightObj that should already represent a Squirrel table
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
Table(LightObj&& obj) noexcept : TableBase(std::move(obj)) {
|
2021-01-30 07:51:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Construct the Table from a HSQOBJECT and HSQUIRRELVM that already exist
|
|
|
|
///
|
|
|
|
/// \param o Squirrel object that should already represent a Squirrel table
|
|
|
|
/// \param v Squirrel VM that contains the Squirrel object given
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
Table(HSQOBJECT o, HSQUIRRELVM v = SqVM()) : TableBase(o, v) {
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Construct the TableBase with an initial capacity
|
|
|
|
///
|
|
|
|
/// \param v VM to create the Table in
|
|
|
|
/// \param c The initial capacity of the created table
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
Table(HSQUIRRELVM vm, SQInteger c) : TableBase() {
|
|
|
|
sq_newtableex(vm, c);
|
|
|
|
sq_getstackobj(vm,-1,&mObj);
|
|
|
|
sq_addref(vm, &mObj);
|
|
|
|
sq_pop(vm,1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Copy constructor
|
|
|
|
///
|
|
|
|
/// \param st Table to copy
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
Table(const Table& st) : TableBase(st) {
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Move constructor
|
|
|
|
///
|
|
|
|
/// \param st Table to move
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
2021-03-20 10:49:02 +01:00
|
|
|
Table(Table&& st) noexcept : TableBase(std::move(st)) {
|
2021-01-30 07:51:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Assignment operator
|
|
|
|
///
|
|
|
|
/// \param st Table to copy
|
|
|
|
///
|
|
|
|
/// \return The Table itself
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
Table& operator=(const Table& st) {
|
|
|
|
TableBase::operator = (st);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Assignment operator
|
|
|
|
///
|
|
|
|
/// \param st Table to move
|
|
|
|
///
|
|
|
|
/// \return The Table itself
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
Table& operator=(Table&& st) noexcept {
|
2021-03-20 10:49:02 +01:00
|
|
|
TableBase::operator = (std::move(st));
|
2021-01-30 07:51:39 +01:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Table that is a reference to the Squirrel root table for a given VM
|
|
|
|
/// The Squirrel root table is usually where all globals are stored by the Squirrel language.
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
class RootTable : public TableBase {
|
|
|
|
public:
|
|
|
|
using TableBase::TableBase;
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Constructs a RootTable object to represent the given VM's root table
|
|
|
|
///
|
|
|
|
/// \param v VM to get the RootTable for
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
RootTable(HSQUIRRELVM vm = SqVM()) : TableBase() {
|
|
|
|
sq_pushroottable(vm);
|
|
|
|
sq_getstackobj(vm,-1,&mObj);
|
|
|
|
sq_addref(vm, &mObj);
|
|
|
|
sq_pop(vm,1); // pop root table
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Table that is a reference to the Squirrel registry table for a given VM
|
|
|
|
/// The Squirrel registry table is where non-Squirrel code can store Squirrel objects without worrying about Squirrel code messing with them.
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
class RegistryTable : public TableBase {
|
|
|
|
public:
|
|
|
|
using TableBase::TableBase;
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Constructs a RegistryTable object to represent the given VM's registry table
|
|
|
|
///
|
|
|
|
/// \param v VM to get the RegistryTable for
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
RegistryTable(HSQUIRRELVM vm = SqVM()) : TableBase() {
|
|
|
|
sq_pushregistrytable(vm);
|
|
|
|
sq_getstackobj(vm,-1,&mObj);
|
|
|
|
sq_addref(vm, &mObj);
|
|
|
|
sq_pop(vm,1); // pop the registry table
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Used to get and push Table instances to and from the stack as references (tables are always references in Squirrel)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
template<>
|
|
|
|
struct Var<Table> {
|
|
|
|
|
|
|
|
Table value; ///< The actual value of get operations
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Attempts to get the value off the stack at idx as a Table
|
|
|
|
///
|
|
|
|
/// \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) {
|
|
|
|
HSQOBJECT obj;
|
|
|
|
sq_resetobject(&obj);
|
|
|
|
sq_getstackobj(vm,idx,&obj);
|
|
|
|
value = Table(obj, vm);
|
|
|
|
#if !defined (SCRAT_NO_ERROR_CHECKING)
|
|
|
|
SQObjectType value_type = sq_gettype(vm, idx);
|
|
|
|
if (value_type != OT_TABLE) {
|
|
|
|
SQTHROW(vm, FormatTypeError(vm, idx, _SC("table")));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Called by Sqrat::PushVar to put an Table reference on the stack
|
|
|
|
///
|
|
|
|
/// \param vm Target VM
|
|
|
|
/// \param value Value to push on to the VM's stack
|
|
|
|
///
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
static void push(HSQUIRRELVM vm, const Table& value) {
|
|
|
|
HSQOBJECT obj;
|
|
|
|
sq_resetobject(&obj);
|
|
|
|
obj = value.GetObj();
|
|
|
|
sq_pushobject(vm,obj);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Used to get and push Table instances to and from the stack as references (tables are always references in Squirrel)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
template<>
|
|
|
|
struct Var<Table&> : Var<Table> {Var(HSQUIRRELVM vm, SQInteger idx) : Var<Table>(vm, idx) {}};
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Used to get and push Table instances to and from the stack as references (tables are always references in Squirrel)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
template<>
|
|
|
|
struct Var<const Table&> : Var<Table> {Var(HSQUIRRELVM vm, SQInteger idx) : Var<Table>(vm, idx) {}};
|
|
|
|
|
|
|
|
}
|