feat: Added NoNut core
This commit is contained in:
20
src/NoNut/core/Array.cpp
Normal file
20
src/NoNut/core/Array.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "CommonHeader.h"
|
||||
#include "Array.h"
|
||||
|
||||
namespace nonut
|
||||
{
|
||||
Array::Array(const SQObject object) : object(object), cachedSize(size())
|
||||
{
|
||||
}
|
||||
|
||||
Array::~Array() = default;
|
||||
|
||||
size_t Array::size() const
|
||||
{
|
||||
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
|
||||
sq_pushobject(vm, object);
|
||||
const auto result = sq_getsize(vm, -1);
|
||||
sq_pop(vm, 1);
|
||||
return static_cast<size_t>(result);
|
||||
}
|
||||
}
|
||||
51
src/NoNut/core/Array.h
Normal file
51
src/NoNut/core/Array.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifndef NONUT_CORE_ARRAY_H
|
||||
#define NONUT_CORE_ARRAY_H
|
||||
#include "CommonHeader.h"
|
||||
|
||||
#include "Utils.h"
|
||||
#include <sqapi.h>
|
||||
|
||||
namespace nonut
|
||||
{
|
||||
class Array
|
||||
{
|
||||
public:
|
||||
explicit Array(SQObject object);
|
||||
~Array();
|
||||
|
||||
[[nodiscard]] size_t size() const;
|
||||
|
||||
template <typename T>
|
||||
T get(const String index)
|
||||
{
|
||||
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
|
||||
T result{};
|
||||
sq_pushobject(vm, object);
|
||||
sq_pushstring(vm, index.c_str(), index.length());
|
||||
|
||||
if (SQ_FAILED(sq_get(vm, -2)))
|
||||
{
|
||||
sq_pop(vm, 1);
|
||||
return result;
|
||||
}
|
||||
if constexpr (std::is_same_v<T, String>)
|
||||
{
|
||||
const SQChar* intermediateResult = nullptr;
|
||||
sq_getstring(vm, -1, &intermediateResult);
|
||||
result = intermediateResult;
|
||||
}
|
||||
else
|
||||
{
|
||||
sqGetValue(vm, -1, &result);
|
||||
}
|
||||
|
||||
sq_pop(vm, 2);
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
SQObject object;
|
||||
size_t cachedSize;
|
||||
};
|
||||
}
|
||||
#endif // NONUT_CORE_ARRAY_H
|
||||
31
src/NoNut/core/Bind.h
Normal file
31
src/NoNut/core/Bind.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef NONUT_CORE_BIND_H
|
||||
#define NONUT_CORE_BIND_H
|
||||
|
||||
#include "CommonHeader.h"
|
||||
#include <vector>
|
||||
|
||||
namespace nonut
|
||||
{
|
||||
//TODO: Finish Bind and remove placeholder
|
||||
|
||||
class Bind
|
||||
{
|
||||
public:
|
||||
static void registerFunction(String funcName, const SQFUNCTION func, size_t funcSize)
|
||||
{
|
||||
const auto top = sq_gettop(vm);
|
||||
sq_pushroottable(vm);
|
||||
sq_pushstring(vm, funcName.c_str(), funcName.length());
|
||||
sq_newclosure(vm, func, 0); //create a new function
|
||||
sq_newslot(vm, -3, SQFalse);
|
||||
sq_settop(vm, top);
|
||||
}
|
||||
|
||||
//template<typename F>
|
||||
//static void Function(String functionName, F& function)
|
||||
//{
|
||||
//
|
||||
//}
|
||||
};
|
||||
}
|
||||
#endif // NONUT_CORE_BIND_H
|
||||
63
src/NoNut/core/Class.cpp
Normal file
63
src/NoNut/core/Class.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
#include "CommonHeader.h"
|
||||
#include "Class.h"
|
||||
|
||||
namespace nonut
|
||||
{
|
||||
Class::Class(const String& className, const SQObject classObjectInstance)
|
||||
{
|
||||
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
|
||||
if (classObjectInstance._type == OT_NULL)
|
||||
{
|
||||
const auto top = sq_gettop(vm);
|
||||
|
||||
sq_pushroottable(vm); //push root table
|
||||
sq_pushstring(vm, className.c_str(), className.length()); //push class name
|
||||
|
||||
if (sq_get(vm, -2) == SQ_OK) //retrieve class
|
||||
{
|
||||
sq_getstackobj(vm, -1, &classObject);
|
||||
sq_addref(vm, &classObject);
|
||||
if (sq_createinstance(vm, -1) == SQ_OK) //create class instance
|
||||
{
|
||||
//1. Get object ptr
|
||||
sq_getstackobj(vm, -1, &this->classObjectInstance); //retrieve object
|
||||
sq_addref(vm, &this->classObjectInstance);
|
||||
//Add ref thanks to which object will not be immediately deleted
|
||||
sq_pop(vm, 1); // pop class instance
|
||||
}
|
||||
}
|
||||
sq_settop(vm, top); // TODO: FIX LEAK PROPERLY
|
||||
}
|
||||
else
|
||||
{
|
||||
this->classObjectInstance = classObjectInstance;
|
||||
const auto top = sq_gettop(vm);
|
||||
sq_addref(vm, &this->classObjectInstance);
|
||||
|
||||
sq_pushroottable(vm); //push root table
|
||||
sq_pushstring(vm, className.c_str(), className.length()); //push class name
|
||||
|
||||
if (sq_get(vm, -2) == SQ_OK) //retrieve class
|
||||
{
|
||||
sq_getstackobj(vm, -1, &classObject);
|
||||
sq_addref(vm, &classObject);
|
||||
}
|
||||
|
||||
sq_settop(vm, top);
|
||||
}
|
||||
}
|
||||
|
||||
Class::~Class()
|
||||
{
|
||||
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
|
||||
sq_release(vm, &classObject);
|
||||
sq_release(vm, &classObjectInstance);
|
||||
sq_resetobject(&classObject);
|
||||
sq_resetobject(&classObjectInstance);
|
||||
}
|
||||
|
||||
SQObject Class::getInstance() const
|
||||
{
|
||||
return classObjectInstance;
|
||||
}
|
||||
}
|
||||
42
src/NoNut/core/Class.h
Normal file
42
src/NoNut/core/Class.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef NONUT_CORE_CLASS_H
|
||||
#define NONUT_CORE_CLASS_H
|
||||
#include "CommonHeader.h"
|
||||
#include <string>
|
||||
|
||||
#include "Function.h"
|
||||
// ReSharper disable once CppUnusedIncludeDirective
|
||||
#include "Property.h"
|
||||
#include "Instance.h"
|
||||
|
||||
#define METHOD_CTOR(methodName) methodName(#methodName, this->classObjectInstance, this->classObject)
|
||||
#define PROPERTY_CTOR(propertyName) propertyName(#propertyName, this->classObjectInstance)
|
||||
#define COPY_CTOR(type) type(const type& other) : type(other.getInstance()){} \
|
||||
type& operator=(const type& other) = delete
|
||||
|
||||
namespace nonut
|
||||
{
|
||||
static constexpr auto CONSTRUCTOR_NAME = "constructor";
|
||||
|
||||
class Class : public Instance
|
||||
{
|
||||
public:
|
||||
Class(const String& className, SQObject classObjectInstance = SQ_NULL);
|
||||
virtual ~Class();
|
||||
|
||||
[[nodiscard]] SQObject getInstance() const override;
|
||||
|
||||
protected:
|
||||
// Object holding information about class
|
||||
SQObject classObject{};
|
||||
// Class object instance
|
||||
SQObject classObjectInstance{};
|
||||
|
||||
template <typename... Args>
|
||||
void classCtor(Args ... args)
|
||||
{
|
||||
Function<void, Args...> ctor(CONSTRUCTOR_NAME, classObjectInstance, classObject);
|
||||
ctor(std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif // NONUT_CORE_CLASS_H
|
||||
21
src/NoNut/core/CommonHeader.h
Normal file
21
src/NoNut/core/CommonHeader.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef CORE_COMMONHEADER_H_
|
||||
#define CORE_COMMONHEADER_H_
|
||||
|
||||
#include "sqrat.h"
|
||||
|
||||
namespace nonut
|
||||
{
|
||||
using Int = SQInteger;
|
||||
using UInt = SQUnsignedInteger;
|
||||
using UInt32 = SQUnsignedInteger32;
|
||||
using Float = SQFloat;
|
||||
using Bool = SQBool;
|
||||
using String = std::string;
|
||||
|
||||
constexpr SQObject SQ_NULL{ OT_NULL };
|
||||
}
|
||||
|
||||
namespace nonut::g2o{}
|
||||
namespace g2o = nonut::g2o;
|
||||
|
||||
#endif // CORE_COMMONHEADER_H_
|
||||
14
src/NoNut/core/Constant.cpp
Normal file
14
src/NoNut/core/Constant.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#include "Constant.h"
|
||||
|
||||
namespace nonut
|
||||
{
|
||||
SQObject getConstTable()
|
||||
{
|
||||
SQObject obj;
|
||||
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
|
||||
sq_pushconsttable(vm);
|
||||
sq_getstackobj(vm, -1, &obj);
|
||||
sq_pop(vm, 1); // No addref needed, since the consttable is always around
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
10
src/NoNut/core/Constant.h
Normal file
10
src/NoNut/core/Constant.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef NONUT_CORE_CONSTANT_H
|
||||
#define NONUT_CORE_CONSTANT_H
|
||||
#include "CommonHeader.h"
|
||||
#include <sqapi.h>
|
||||
|
||||
namespace nonut
|
||||
{
|
||||
SQObject getConstTable();
|
||||
};
|
||||
#endif // NONUT_CORE_CONSTANT_H
|
||||
166
src/NoNut/core/Function.h
Normal file
166
src/NoNut/core/Function.h
Normal file
@@ -0,0 +1,166 @@
|
||||
#ifndef NONUT_CORE_FUNCTION_H
|
||||
#define NONUT_CORE_FUNCTION_H
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include <sqapi.h>
|
||||
#include "Utils.h"
|
||||
|
||||
#define FUNCTION_CTOR(function) function(#function)
|
||||
|
||||
namespace nonut
|
||||
{
|
||||
class Class;
|
||||
|
||||
template <typename ReturnType, typename... Args>
|
||||
class Function
|
||||
{
|
||||
public:
|
||||
// Ctor for functions
|
||||
Function(const String& functionName, const SQObject env = getRootTable()) : envObj(env)
|
||||
{
|
||||
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
|
||||
sq_pushobject(vm, envObj);
|
||||
sq_pushstring(vm, functionName.c_str(), functionName.length());
|
||||
|
||||
// get the function from the root table
|
||||
if (SQ_FAILED(sq_get(vm, -2)))
|
||||
{
|
||||
sq_pop(vm, 1);
|
||||
throw;
|
||||
}
|
||||
|
||||
// check the type
|
||||
if (const SQObjectType value_type = sq_gettype(vm, -1); value_type != OT_CLOSURE && value_type !=
|
||||
OT_NATIVECLOSURE)
|
||||
{
|
||||
sq_pop(vm, 2);
|
||||
throw;
|
||||
}
|
||||
|
||||
// get function and add ref
|
||||
sq_getstackobj(vm, -1, &funcObj);
|
||||
sq_addref(vm, &funcObj);
|
||||
|
||||
sq_pop(vm, 2);
|
||||
}
|
||||
|
||||
// Ctor for class methods
|
||||
Function(const String& functionName, const SQObject classObjectInstance,
|
||||
const SQObject classObject) : envObj(classObjectInstance)
|
||||
{
|
||||
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
|
||||
isClassMethod = true; // Prevent release of the resources cause we don't own them
|
||||
sq_pushobject(vm, classObject);
|
||||
sq_pushstring(vm, functionName.c_str(), functionName.length());
|
||||
|
||||
// get the function from the root table
|
||||
if (SQ_FAILED(sq_get(vm, -2)))
|
||||
{
|
||||
sq_pop(vm, 1);
|
||||
throw;
|
||||
}
|
||||
|
||||
// check the type
|
||||
if (const SQObjectType value_type = sq_gettype(vm, -1); value_type != OT_CLOSURE && value_type !=
|
||||
OT_NATIVECLOSURE)
|
||||
{
|
||||
sq_pop(vm, 2);
|
||||
throw;
|
||||
}
|
||||
|
||||
// get function and add ref
|
||||
sq_getstackobj(vm, -1, &funcObj);
|
||||
sq_addref(vm, &funcObj);
|
||||
|
||||
sq_pop(vm, 2);
|
||||
}
|
||||
|
||||
~Function()
|
||||
{
|
||||
if (!isClassMethod)
|
||||
{
|
||||
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
|
||||
sq_release(vm, &funcObj);
|
||||
sq_release(vm, &envObj);
|
||||
sq_resetobject(&funcObj);
|
||||
sq_resetobject(&envObj);
|
||||
}
|
||||
}
|
||||
|
||||
ReturnType operator()(Args ... args)
|
||||
{
|
||||
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
|
||||
const auto top = sq_gettop(vm);
|
||||
sq_pushobject(vm, funcObj);
|
||||
sq_pushobject(vm, envObj);
|
||||
auto debug = sq_gettop(vm);
|
||||
(sqPushValue(vm, args), ...);
|
||||
|
||||
if constexpr (std::is_same_v<ReturnType, void>)
|
||||
{
|
||||
debug = sq_gettop(vm);
|
||||
auto returnCode = sq_call(vm, ARG_COUNT + 1, SQFalse, SQFalse); // TODO: HANDLE ERROR RETURN CODE
|
||||
sq_pop(vm, 2);
|
||||
sq_settop(vm, top);
|
||||
return void();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto returnCode = sq_call(vm, ARG_COUNT + 1, SQTrue, SQFalse); // TODO: HANDLE ERROR RETURN CODE
|
||||
|
||||
std::optional<ReturnType> result;
|
||||
|
||||
if constexpr (std::derived_from<ReturnType, CustomType>)
|
||||
{
|
||||
result = std::make_optional<ReturnType>();
|
||||
auto intermediateResult = returnVar<SQObject>();
|
||||
result.value().convert(intermediateResult);
|
||||
sq_release(vm, &intermediateResult);
|
||||
sq_resetobject(&intermediateResult);
|
||||
}
|
||||
else if constexpr (std::derived_from<ReturnType, Class>)
|
||||
{
|
||||
auto intermediateResult = returnVar<SQObject>();
|
||||
//result = std::make_optional<ReturnType>(ReturnType(intermediateResult));
|
||||
result.emplace(ReturnType(intermediateResult));
|
||||
|
||||
sq_release(vm, &intermediateResult);
|
||||
sq_resetobject(&intermediateResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = std::make_optional<ReturnType>(returnVar<ReturnType>());
|
||||
}
|
||||
|
||||
sq_pop(vm, 2);
|
||||
sq_settop(vm, top);
|
||||
return result.value();
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] SQObject getObject() const
|
||||
{
|
||||
return funcObj;
|
||||
}
|
||||
|
||||
private:
|
||||
SQObject funcObj{};
|
||||
SQObject envObj{};
|
||||
bool isClassMethod = false;
|
||||
static constexpr auto ARG_COUNT{sizeof...(Args)};
|
||||
|
||||
static SQObject getRootTable()
|
||||
{
|
||||
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
|
||||
SQObject rootTable{};
|
||||
sq_pushroottable(vm);
|
||||
sq_getstackobj(vm, -1, &rootTable);
|
||||
sq_addref(vm, &rootTable);
|
||||
sq_pop(vm, 1); // pop root table
|
||||
return rootTable;
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif // NONUT_CORE_FUNCTION_H
|
||||
12
src/NoNut/core/Instance.h
Normal file
12
src/NoNut/core/Instance.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef NONUT_CORE_INSTANCE_H
|
||||
#define NONUT_CORE_INSTANCE_H
|
||||
|
||||
namespace nonut
|
||||
{
|
||||
class Instance
|
||||
{
|
||||
public:
|
||||
[[nodiscard]] virtual SQObject getInstance() const = 0;
|
||||
};
|
||||
}
|
||||
#endif //NONUT_CORE_INSTANCE_H
|
||||
135
src/NoNut/core/Property.h
Normal file
135
src/NoNut/core/Property.h
Normal file
@@ -0,0 +1,135 @@
|
||||
#ifndef NONUT_CORE_PROPERTY_H
|
||||
#define NONUT_CORE_PROPERTY_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <sqapi.h>
|
||||
#include "Utils.h"
|
||||
#include "Class.h"
|
||||
|
||||
namespace nonut
|
||||
{
|
||||
template <typename T>
|
||||
T getProperty(const SQObject& object, const String& name)
|
||||
{
|
||||
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
|
||||
const auto top = sq_gettop(vm);
|
||||
|
||||
sq_pushobject(vm, object);
|
||||
sq_pushstring(vm, name.c_str(), name.length());
|
||||
|
||||
if constexpr (std::derived_from<T, Class>)
|
||||
{
|
||||
SQObject intermediateResult{};
|
||||
if (SQ_SUCCEEDED(sq_get(vm, -2))) // pops property
|
||||
{
|
||||
sqGetValue(vm, -1, &intermediateResult);
|
||||
sq_pop(vm, 1); // pops result
|
||||
}
|
||||
|
||||
sq_pop(vm, 1); // pops object
|
||||
sq_settop(vm, top);
|
||||
return T(intermediateResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
T result{};
|
||||
|
||||
if (SQ_SUCCEEDED(sq_get(vm, -2))) // pops property
|
||||
{
|
||||
sqGetValue(vm, -1, &result);
|
||||
sq_pop(vm, 1); // pops result
|
||||
}
|
||||
|
||||
sq_pop(vm, 1); // pops object
|
||||
sq_settop(vm, top);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool getProperty<bool>(const SQObject& object, const String& name)
|
||||
{
|
||||
return getProperty<Bool>(object, name);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline String getProperty<String>(const SQObject& object, const String& name)
|
||||
{
|
||||
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
|
||||
const Int top = sq_gettop(vm);
|
||||
const SQChar* result{};
|
||||
|
||||
sq_pushobject(vm, object);
|
||||
sq_pushstring(vm, name.c_str(), name.length());
|
||||
|
||||
if (SQ_SUCCEEDED(sq_get(vm, -2))) // pops property
|
||||
{
|
||||
sq_getstring(vm, -1, &result);
|
||||
sq_pop(vm, 1); // pops result
|
||||
}
|
||||
|
||||
sq_pop(vm, 1); // pops object
|
||||
sq_settop(vm, top);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void setProperty(SQObject& object, String& name, T value)
|
||||
{
|
||||
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
|
||||
sq_pushobject(vm, object);
|
||||
sq_pushstring(vm, name.c_str(), name.length());
|
||||
if constexpr (std::derived_from<T, Class>)
|
||||
{
|
||||
sqPushValue(vm, value.getInstance());
|
||||
}
|
||||
else
|
||||
{
|
||||
sqPushValue(vm, value);
|
||||
}
|
||||
|
||||
|
||||
auto result = sq_set(vm, -3); // pops name and value
|
||||
|
||||
sq_pop(vm, 1); // pops object
|
||||
}
|
||||
|
||||
template <typename T, bool IsReadOnly = false>
|
||||
class Property
|
||||
{
|
||||
public:
|
||||
Property(String propertyName, const SQObject object) : object(object),
|
||||
propertyName(std::move(propertyName))
|
||||
{
|
||||
}
|
||||
|
||||
Property<T>& operator=(const T& other) noexcept
|
||||
{
|
||||
set(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator T()
|
||||
{
|
||||
return this->get();
|
||||
}
|
||||
|
||||
[[nodiscard]] T get() const
|
||||
{
|
||||
return getProperty<T>(object, propertyName);
|
||||
}
|
||||
|
||||
void set(T value)
|
||||
{
|
||||
static_assert(!IsReadOnly, "Cannot set read-only property.");
|
||||
setProperty<T>(object, propertyName, value);
|
||||
}
|
||||
|
||||
private:
|
||||
SQObject object;
|
||||
String propertyName;
|
||||
};
|
||||
}
|
||||
#endif // NONUT_CORE_PROPERTY_H
|
||||
32
src/NoNut/core/StaticClass.cpp
Normal file
32
src/NoNut/core/StaticClass.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#include "StaticClass.h"
|
||||
|
||||
namespace nonut
|
||||
{
|
||||
StaticClass::StaticClass(const String& className)
|
||||
{
|
||||
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
|
||||
const auto top = sq_gettop(vm);
|
||||
|
||||
sq_pushroottable(vm); //push root table
|
||||
sq_pushstring(vm, className.c_str(), className.length()); //push class instance name
|
||||
|
||||
if (sq_get(vm, -2) == SQ_OK) //retrieve class instance
|
||||
{
|
||||
sq_getstackobj(vm, -1, &classObjectInstance);
|
||||
sq_addref(vm, &classObjectInstance);
|
||||
sq_getclass(vm, -1);
|
||||
sq_getstackobj(vm, -1, &classObject);
|
||||
sq_addref(vm, &classObject);
|
||||
}
|
||||
sq_settop(vm, top); // TODO: FIX LEAK PROPERLY
|
||||
}
|
||||
|
||||
StaticClass::~StaticClass()
|
||||
{
|
||||
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
|
||||
sq_release(vm, &classObject);
|
||||
sq_release(vm, &classObjectInstance);
|
||||
sq_resetobject(&classObject);
|
||||
sq_resetobject(&classObjectInstance);
|
||||
}
|
||||
}
|
||||
25
src/NoNut/core/StaticClass.h
Normal file
25
src/NoNut/core/StaticClass.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef NONUT_CORE_STATIC_CLASS_H
|
||||
#define NONUT_CORE_STATIC_CLASS_H
|
||||
|
||||
#include "Function.h"
|
||||
#include "Property.h"
|
||||
|
||||
#define METHOD_CTOR(methodName) methodName(#methodName, this->classObjectInstance, this->classObject)
|
||||
#define PROPERTY_CTOR(propertyName) propertyName(#propertyName, this->classObjectInstance)
|
||||
|
||||
namespace nonut
|
||||
{
|
||||
class StaticClass
|
||||
{
|
||||
public:
|
||||
explicit StaticClass(const String& className);
|
||||
~StaticClass();
|
||||
|
||||
protected:
|
||||
// Object holding information about class
|
||||
SQObject classObject{};
|
||||
// Class object instance
|
||||
SQObject classObjectInstance{};
|
||||
};
|
||||
}
|
||||
#endif // NONUT_CORE_STATIC_CLASS_H
|
||||
347
src/NoNut/core/StringHelpers.h
Normal file
347
src/NoNut/core/StringHelpers.h
Normal file
@@ -0,0 +1,347 @@
|
||||
#ifndef NONUT_CORE_STRING_HELPERS_H
|
||||
#define NONUT_CORE_STRING_HELPERS_H
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace nonut
|
||||
{
|
||||
const std::unordered_map<unsigned char, std::string_view> WINDOWS1250_UTF8_MAP
|
||||
{
|
||||
{'\x80', "\xe2\x82\xac"}, // euro sign
|
||||
{'\x82', "\xe2\x80\x9a"}, // lower quotation mark
|
||||
{'\x84', "\xe2\x80\x9e"}, // lower quotation marks
|
||||
{'\x85', "\xe2\x80\xa6"}, // ellipsis
|
||||
{'\x86', "\xe2\x80\xa0"}, // dagger
|
||||
{'\x87', "\xe2\x80\xa1"}, // double dagger
|
||||
{'\x89', "\xe2\x80\xb0"}, // per mille
|
||||
{'\x8a', "\xc5\xa0"}, // S with caron
|
||||
{'\x8b', "\xe2\x80\xb9"}, // left guillemet
|
||||
{'\x8c', "\xc5\x9a"}, // S with acute
|
||||
{'\x8d', "\xc5\xa4"}, // T with caron
|
||||
{'\x8e', "\xc5\xbd"}, // Z with caron
|
||||
{'\x8f', "\xc5\xb9"}, // Z with acute
|
||||
|
||||
{'\x91', "\xe2\x80\x98"}, // upper quotation mark (opening)
|
||||
{'\x92', "\xe2\x80\x99"}, // upper quotation mark (closing)
|
||||
{'\x93', "\xe2\x80\x9c"}, // upper quotation marks (opening)
|
||||
{'\x94', "\xe2\x80\x9d"}, // upper quotation marks (closing)
|
||||
{'\x95', "\xe2\x80\xa2"}, // bullet sign
|
||||
{'\x96', "\xe2\x80\x93"}, // en dash
|
||||
{'\x97', "\xe2\x80\x94"}, // em dash
|
||||
{'\x99', "\xe2\x84\xa2"}, // trademark sign
|
||||
{'\x9a', "\xc5\xa1"}, // s with caron
|
||||
{'\x9b', "\xe2\x80\xba"}, // right guillemet
|
||||
{'\x9c', "\xc5\x9b"}, // s with acute
|
||||
{'\x9d', "\xc5\xa5"}, // t with caron
|
||||
{'\x9e', "\xc5\xbe"}, // z with caron
|
||||
{'\x9f', "\xc5\xba"}, // z with acute
|
||||
|
||||
{'\xa0', "\x20"}, // NBSP
|
||||
{'\xa1', "\xcb\x87"}, // caron
|
||||
{'\xa2', "\xcb\x98"}, // breve
|
||||
{'\xa3', "\xc5\x81"}, // L with stroke
|
||||
{'\xa4', "\xc2\xa4"}, // currency sign
|
||||
{'\xa5', "\xc4\x84"}, // A with ogonek
|
||||
{'\xa6', "\xc2\xa6"}, // vertical bar
|
||||
{'\xa7', "\xc2\xa7"}, // section sign
|
||||
{'\xa8', "\xc2\xa8"}, // diaeresis
|
||||
{'\xa9', "\xc2\xa9"}, // copyright sign
|
||||
{'\xaa', "\xc5\x9e"}, // S-cedilla
|
||||
{'\xab', "\xc2\xab"}, // left guillemets
|
||||
{'\xac', "\xc2\xac"}, // negation
|
||||
{'\xad', "\xc2\xad"}, // soft hyphen
|
||||
{'\xae', "\xc2\xae"}, // registered trademark sign
|
||||
{'\xaf', "\xc5\xbb"}, // Z with dot above
|
||||
|
||||
{'\xb0', "\xc2\xb0"}, // degree sign
|
||||
{'\xb1', "\xc2\xb1"}, // plus-minus sign
|
||||
{'\xb2', "\xcb\x9b"}, // ogonek
|
||||
{'\xb3', "\xc5\x82"}, // l with stroke
|
||||
{'\xb4', "\xc2\xb4"}, // acute accent
|
||||
{'\xb5', "\xc2\xb5"}, // Mu letter
|
||||
{'\xb6', "\xc2\xb6"}, // pilcrow
|
||||
{'\xb7', "\xc2\xb7"}, // middle dot
|
||||
{'\xb8', "\xc2\xb8"}, // cedilla
|
||||
{'\xb9', "\xc4\x85"}, // a with ogonek
|
||||
{'\xba', "\xc5\x9f"}, // s-cedilla
|
||||
{'\xbb', "\xc2\xbb"}, // right guillemets
|
||||
{'\xbc', "\xc4\xbd"}, // Lj-
|
||||
{'\xbd', "\xcb\x9d"}, // double acute accent
|
||||
{'\xbe', "\xc4\xbe"}, // lj-
|
||||
{'\xbf', "\xc5\xbc"}, // z with dot above
|
||||
|
||||
{'\xc0', "\xc5\x94"}, // R with acute
|
||||
{'\xc1', "\xc3\x81"}, // A with acute
|
||||
{'\xc2', "\xc3\x82"}, // A-circumflex
|
||||
{'\xc3', "\xc4\x82"}, // A-breve
|
||||
{'\xc4', "\xc3\x84"}, // A with diaeresis
|
||||
{'\xc5', "\xc4\xb9"}, // L with acute
|
||||
{'\xc6', "\xc4\x86"}, // C with acute
|
||||
{'\xc7', "\xc3\x87"}, // C-cedilla
|
||||
{'\xc8', "\xc4\x8c"}, // C with caron
|
||||
{'\xc9', "\xc3\x89"}, // C with acute
|
||||
{'\xca', "\xc4\x98"}, // E with ogonek
|
||||
{'\xcb', "\xc3\x8b"}, // E with diaeresis
|
||||
{'\xcc', "\xc3\x8b"}, // E with caron
|
||||
{'\xcd', "\xc3\x8d"}, // I with acute
|
||||
{'\xce', "\xc3\x8e"}, // I-circumflex
|
||||
{'\xcf', "\xc4\x8e"}, // D with caron
|
||||
|
||||
{'\xd0', "\xc4\x90"}, // crossed D
|
||||
{'\xd1', "\xc5\x83"}, // N with acute
|
||||
{'\xd2', "\xc5\x87"}, // N with caron
|
||||
{'\xd3', "\xc3\x93"}, // O with acute
|
||||
{'\xd4', "\xc3\x94"}, // O-circumflex
|
||||
{'\xd5', "\xc5\x90"}, // O with dobule accute
|
||||
{'\xd6', "\xc3\x96"}, // O with diaeresis
|
||||
{'\xd7', "\xc3\x97"}, // multiplication sign
|
||||
{'\xd8', "\xc5\x98"}, // R with caron
|
||||
{'\xd9', "\xc5\xae"}, // U with diacritic
|
||||
{'\xda', "\xc3\x9a"}, // U with acute
|
||||
{'\xdb', "\xc5\xb0"}, // U with double accent
|
||||
{'\xdc', "\xc3\x9c"}, // U with diaeresis
|
||||
{'\xdd', "\xc3\x9d"}, // Y with acute
|
||||
{'\xdf', "\xc5\xa2"}, // T-cedilla
|
||||
|
||||
{'\xe0', "\xc5\x95"}, // r with acute
|
||||
{'\xe1', "\xc3\xa1"}, // a with acute
|
||||
{'\xe2', "\xc3\xa2"}, // a-circumflex
|
||||
{'\xe3', "\xc4\x83"}, // a-breve
|
||||
{'\xe4', "\xc3\xa4"}, // a with diaeresis
|
||||
{'\xe5', "\xc4\xba"}, // l with acute
|
||||
{'\xe6', "\xc4\x87"}, // c with acute
|
||||
{'\xe7', "\xc3\xa7"}, // c-cedilla
|
||||
{'\xe8', "\xc4\x8d"}, // c with caron
|
||||
{'\xe9', "\xc3\xa9"}, // c with acute
|
||||
{'\xea', "\xc4\x99"}, // e with ogonek
|
||||
{'\xeb', "\xc3\xab"}, // e with diaeresis
|
||||
{'\xec', "\xc4\x9b"}, // e with caron
|
||||
{'\xed', "\xc3\xad"}, // i with acute
|
||||
{'\xee', "\xc3\xae"}, // i-circumflex
|
||||
{'\xef', "\xc4\x8f"}, // d with caron
|
||||
|
||||
{'\xf0', "\xc4\x91"}, // crossed d
|
||||
{'\xf1', "\xc5\x84"}, // n with acute
|
||||
{'\xf2', "\xc5\x88"}, // n with caron
|
||||
{'\xf3', "\xc3\xb3"}, // o with acute
|
||||
{'\xf4', "\xc3\xb4"}, // o-circumflex
|
||||
{'\xf5', "\xc5\x91"}, // o with double accent
|
||||
{'\xf6', "\xc3\xb6"}, // o with diaeresis
|
||||
{'\xf7', "\xc3\xb7"}, // division sign
|
||||
{'\xf8', "\xc5\x99"}, // r with caron
|
||||
{'\xf9', "\xc5\xaf"}, // u with diacritic
|
||||
{'\xfa', "\xc3\xba"}, // u with acute
|
||||
{'\xfb', "\xc5\xb1"}, // u with double accent
|
||||
{'\xfc', "\xc3\xbc"}, // u with diaeresis
|
||||
{'\xfd', "\xc3\xbd"}, // y with acute
|
||||
{'\xfe', "\xc5\xa3"}, // t-cedilla
|
||||
{'\xff', "\xcb\x99"}, // diactric dot
|
||||
};
|
||||
|
||||
const std::unordered_map<std::string_view, unsigned char> UTF8_WINDOWS1250_MAP
|
||||
{
|
||||
{"\xe2\x82\xac", '\x80'}, // euro sign
|
||||
{"\xe2\x80\x9a", '\x82'}, // lower quotation mark
|
||||
{"\xe2\x80\x9e", '\x84'}, // lower quotation marks
|
||||
{"\xe2\x80\xa6", '\x85'}, // ellipsis
|
||||
{"\xe2\x80\xa0", '\x86'}, // dagger
|
||||
{"\xe2\x80\xa1", '\x87'}, // double dagger
|
||||
{"\xe2\x80\xb0", '\x89'}, // per mille
|
||||
{"\xc5\xa0", '\x8a'}, // S with caron
|
||||
{"\xe2\x80\xb9", '\x8b'}, // left guillemet
|
||||
{"\xc5\x9a", '\x8c'}, // S with acute
|
||||
{"\xc5\xa4", '\x8d'}, // T with caron
|
||||
{"\xc5\xbd", '\x8e'}, // Z with caron
|
||||
{"\xc5\xb9", '\x8f'}, // Z with acute
|
||||
|
||||
{"\xe2\x80\x98", '\x91'}, // upper quotation mark (opening)
|
||||
{"\xe2\x80\x99", '\x92'}, // upper quotation mark (closing)
|
||||
{"\xe2\x80\x9c", '\x93'}, // upper quotation marks (opening)
|
||||
{"\xe2\x80\x9d", '\x94'}, // upper quotation marks (closing)
|
||||
{"\xe2\x80\xa2", '\x95'}, // bullet sign
|
||||
{"\xe2\x80\x93", '\x96'}, // en dash
|
||||
{"\xe2\x80\x94", '\x97'}, // em dash
|
||||
{"\xe2\x84\xa2", '\x99'}, // trademark sign
|
||||
{"\xc5\xa1", '\x9a'}, // s with caron
|
||||
{"\xe2\x80\xba", '\x9b'}, // right guillemet
|
||||
{"\xc5\x9b", '\x9c'}, // s with acute
|
||||
{"\xc5\xa5", '\x9d'}, // t with caron
|
||||
{"\xc5\xbe", '\x9e'}, // z with caron
|
||||
{"\xc5\xba", '\x9f'}, // z with acute
|
||||
|
||||
{"\x20", '\xa0'}, // NBSP
|
||||
{"\xcb\x87", '\xa1'}, // caron
|
||||
{"\xcb\x98", '\xa2'}, // breve
|
||||
{"\xc5\x81", '\xa3'}, // L with stroke
|
||||
{"\xc2\xa4", '\xa4'}, // currency sign
|
||||
{"\xc4\x84", '\xa5'}, // A with ogonek
|
||||
{"\xc2\xa6", '\xa6'}, // vertical bar
|
||||
{"\xc2\xa7", '\xa7'}, // section sign
|
||||
{"\xc2\xa8", '\xa8'}, // diaeresis
|
||||
{"\xc2\xa9", '\xa9'}, // copyright sign
|
||||
{"\xc5\x9e", '\xaa'}, // S-cedilla
|
||||
{"\xc2\xab", '\xab'}, // left guillemets
|
||||
{"\xc2\xac", '\xac'}, // negation
|
||||
{"\xc2\xad", '\xad'}, // soft hyphen
|
||||
{"\xc2\xae", '\xae'}, // registered trademark sign
|
||||
{"\xc5\xbb", '\xaf'}, // Z with dot above
|
||||
|
||||
{"\xc2\xb0", '\xb0'}, // degree sign
|
||||
{"\xc2\xb1", '\xb1'}, // plus-minus sign
|
||||
{"\xcb\x9b", '\xb2'}, // ogonek
|
||||
{"\xc5\x82", '\xb3'}, // l with stroke
|
||||
{"\xc2\xb4", '\xb4'}, // acute accent
|
||||
{"\xc2\xb5", '\xb5'}, // Mu letter
|
||||
{"\xc2\xb6", '\xb6'}, // pilcrow
|
||||
{"\xc2\xb7", '\xb7'}, // middle dot
|
||||
{"\xc2\xb8", '\xb8'}, // cedilla
|
||||
{"\xc4\x85", '\xb9'}, // a with ogonek
|
||||
{"\xc5\x9f", '\xba'}, // s-cedilla
|
||||
{"\xc2\xbb", '\xbb'}, // right guillemets
|
||||
{"\xc4\xbd", '\xbc'}, // Lj-
|
||||
{"\xcb\x9d", '\xbd'}, // double acute accent
|
||||
{"\xc4\xbe", '\xbe'}, // lj-
|
||||
{"\xc5\xbc", '\xbf'}, // z with dot above
|
||||
|
||||
{"\xc5\x94", '\xc0'}, // R with acute
|
||||
{"\xc3\x81", '\xc1'}, // A with acute
|
||||
{"\xc3\x82", '\xc2'}, // A-circumflex
|
||||
{"\xc4\x82", '\xc3'}, // A-breve
|
||||
{"\xc3\x84", '\xc4'}, // A with diaeresis
|
||||
{"\xc4\xb9", '\xc5'}, // L with acute
|
||||
{"\xc4\x86", '\xc6'}, // C with acute
|
||||
{"\xc3\x87", '\xc7'}, // C-cedilla
|
||||
{"\xc4\x8c", '\xc8'}, // C with caron
|
||||
{"\xc3\x89", '\xc9'}, // C with acute
|
||||
{"\xc4\x98", '\xca'}, // E with ogonek
|
||||
{"\xc3\x8b", '\xcb'}, // E with diaeresis
|
||||
{"\xc3\x8b", '\xcc'}, // E with caron
|
||||
{"\xc3\x8d", '\xcd'}, // I with acute
|
||||
{"\xc3\x8e", '\xce'}, // I-circumflex
|
||||
{"\xc4\x8e", '\xcf'}, // D with caron
|
||||
|
||||
{"\xc4\x90", '\xd0'}, // crossed D
|
||||
{"\xc5\x83", '\xd1'}, // N with acute
|
||||
{"\xc5\x87", '\xd2'}, // N with caron
|
||||
{"\xc3\x93", '\xd3'}, // O with acute
|
||||
{"\xc3\x94", '\xd4'}, // O-circumflex
|
||||
{"\xc5\x90", '\xd5'}, // O with dobule accute
|
||||
{"\xc3\x96", '\xd6'}, // O with diaeresis
|
||||
{"\xc3\x97", '\xd7'}, // multiplication sign
|
||||
{"\xc5\x98", '\xd8'}, // R with caron
|
||||
{"\xc5\xae", '\xd9'}, // U with diacritic
|
||||
{"\xc3\x9a", '\xda'}, // U with acute
|
||||
{"\xc5\xb0", '\xdb'}, // U with double accent
|
||||
{"\xc3\x9c", '\xdc'}, // U with diaeresis
|
||||
{"\xc3\x9d", '\xdd'}, // Y with acute
|
||||
{"\xc5\xa2", '\xdf'}, // T-cedilla
|
||||
|
||||
{"\xc5\x95", '\xe0'}, // r with acute
|
||||
{"\xc3\xa1", '\xe1'}, // a with acute
|
||||
{"\xc3\xa2", '\xe2'}, // a-circumflex
|
||||
{"\xc4\x83", '\xe3'}, // a-breve
|
||||
{"\xc3\xa4", '\xe4'}, // a with diaeresis
|
||||
{"\xc4\xba", '\xe5'}, // l with acute
|
||||
{"\xc4\x87", '\xe6'}, // c with acute
|
||||
{"\xc3\xa7", '\xe7'}, // c-cedilla
|
||||
{"\xc4\x8d", '\xe8'}, // c with caron
|
||||
{"\xc3\xa9", '\xe9'}, // c with acute
|
||||
{"\xc4\x99", '\xea'}, // e with ogonek
|
||||
{"\xc3\xab", '\xeb'}, // e with diaeresis
|
||||
{"\xc4\x9b", '\xec'}, // e with caron
|
||||
{"\xc3\xad", '\xed'}, // i with acute
|
||||
{"\xc3\xae", '\xee'}, // i-circumflex
|
||||
{"\xc4\x8f", '\xef'}, // d with caron
|
||||
|
||||
{"\xc4\x91", '\xf0'}, // crossed d
|
||||
{"\xc5\x84", '\xf1'}, // n with acute
|
||||
{"\xc5\x88", '\xf2'}, // n with caron
|
||||
{"\xc3\xb3", '\xf3'}, // o with acute
|
||||
{"\xc3\xb4", '\xf4'}, // o-circumflex
|
||||
{"\xc5\x91", '\xf5'}, // o with double accent
|
||||
{"\xc3\xb6", '\xf6'}, // o with diaeresis
|
||||
{"\xc3\xb7", '\xf7'}, // division sign
|
||||
{"\xc5\x99", '\xf8'}, // r with caron
|
||||
{"\xc5\xaf", '\xf9'}, // u with diacritic
|
||||
{"\xc3\xba", '\xfa'}, // u with acute
|
||||
{"\xc5\xb1", '\xfb'}, // u with double accent
|
||||
{"\xc3\xbc", '\xfc'}, // u with diaeresis
|
||||
{"\xc3\xbd", '\xfd'}, // y with acute
|
||||
{"\xc5\xa3", '\xfe'}, // t-cedilla
|
||||
{"\xcb\x99", '\xff'}, // diactric dot
|
||||
};
|
||||
|
||||
inline std::string win1250ToUTF8(const std::string& strRef)
|
||||
{
|
||||
std::string result;
|
||||
result.reserve(strRef.size() * 2);
|
||||
|
||||
for (auto&& c : strRef)
|
||||
{
|
||||
if (WINDOWS1250_UTF8_MAP.contains(static_cast<unsigned char>(c)))
|
||||
result += WINDOWS1250_UTF8_MAP.at(static_cast<unsigned char>(c));
|
||||
else
|
||||
result += c;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline std::string UTF8ToWin1250(const std::string& strRef)
|
||||
{
|
||||
std::string result;
|
||||
result.reserve(strRef.size());
|
||||
size_t charSize = 1;
|
||||
|
||||
for (size_t i = 0; i < strRef.length(); ++i)
|
||||
{
|
||||
if (const int c = static_cast<unsigned char>(strRef[i]); c >= 128)
|
||||
{
|
||||
if (c < 224)
|
||||
charSize = 2;
|
||||
else if (c < 240)
|
||||
charSize = 3;
|
||||
else if (c < 248)
|
||||
charSize = 4;
|
||||
else if (c == 252)
|
||||
charSize = 5;
|
||||
else
|
||||
charSize = 6;
|
||||
}
|
||||
// Update loop index according to UTF8 charSize;
|
||||
i += charSize - 1;
|
||||
|
||||
if (charSize == 1)
|
||||
{
|
||||
result += strRef[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i + charSize > strRef.length())
|
||||
{
|
||||
result += '?';
|
||||
return result;
|
||||
}
|
||||
|
||||
String utfChar;
|
||||
utfChar.reserve(charSize);
|
||||
|
||||
for (size_t j = 0; j < charSize; ++j)
|
||||
{
|
||||
utfChar += strRef[i + j];
|
||||
}
|
||||
|
||||
if (UTF8_WINDOWS1250_MAP.contains(utfChar))
|
||||
{
|
||||
result += static_cast<char>(UTF8_WINDOWS1250_MAP.at(utfChar));
|
||||
}
|
||||
else
|
||||
{
|
||||
result += '?';
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
#endif // NONUT_CORE_STRING_HELPERS_H
|
||||
22
src/NoNut/core/Stringify.h
Normal file
22
src/NoNut/core/Stringify.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef NONUT_CORE_STRINGIFY_H
|
||||
#define NONUT_CORE_STRINGIFY_H
|
||||
|
||||
#include "CommonHeader.h"
|
||||
#define QUOTIFY(arg) #arg
|
||||
#define STRINGIFY(arg) QUOTIFY(arg)
|
||||
|
||||
namespace nonut
|
||||
{
|
||||
template <typename T>
|
||||
class Stringify
|
||||
{
|
||||
public:
|
||||
virtual ~Stringify() = default;
|
||||
|
||||
[[nodiscard]] virtual String toString() const
|
||||
{
|
||||
return STRINGIFY(T);
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif //NONUT_CORE_STRINGIFY_H
|
||||
13
src/NoNut/core/UserData.h
Normal file
13
src/NoNut/core/UserData.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef NONUT_CORE_USER_DATA_H
|
||||
#define NONUT_CORE_USER_DATA_H
|
||||
|
||||
namespace nonut
|
||||
{
|
||||
class UserData
|
||||
{
|
||||
public:
|
||||
SQUserPointer userPtr = nullptr;
|
||||
SQUserPointer tagPtr = nullptr;
|
||||
};
|
||||
}
|
||||
#endif //NONUT_CORE_INSTANCE_H
|
||||
108
src/NoNut/core/Utils.h
Normal file
108
src/NoNut/core/Utils.h
Normal file
@@ -0,0 +1,108 @@
|
||||
#ifndef NONUT_CORE_UTILS_H
|
||||
#define NONUT_CORE_UTILS_H
|
||||
|
||||
#include "Instance.h"
|
||||
#include "CommonHeader.h"
|
||||
|
||||
namespace nonut
|
||||
{
|
||||
struct CustomType
|
||||
{
|
||||
virtual void convert(HSQOBJECT object) = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void sqGetValue(SQVM* vm, SQInteger idx, T outPtr)
|
||||
{
|
||||
static_assert(
|
||||
std::is_same_v<T, Bool*> ||
|
||||
std::is_same_v<T, Int*> ||
|
||||
std::is_same_v<T, Float*> ||
|
||||
std::is_same_v<T, SQChar**> ||
|
||||
std::is_same_v<T, HSQOBJECT*> ||
|
||||
std::is_same_v<T, SQUserPointer*>,
|
||||
"Not supported return type");
|
||||
|
||||
if constexpr (std::is_same_v<T, Bool*>)
|
||||
sq_getbool(vm, idx, outPtr);
|
||||
if constexpr (std::is_same_v<T, Int*>)
|
||||
sq_getinteger(vm, idx, outPtr);
|
||||
if constexpr (std::is_same_v<T, Float*>)
|
||||
sq_getfloat(vm, idx, outPtr);
|
||||
if constexpr (std::is_same_v<T, SQChar**>)
|
||||
sq_getstring(vm, idx, outPtr);
|
||||
if constexpr (std::is_same_v<T, HSQOBJECT*>)
|
||||
{
|
||||
sq_getstackobj(vm, idx, outPtr);
|
||||
sq_addref(vm, outPtr);
|
||||
}
|
||||
if constexpr (std::is_same_v<T, SQUserPointer*>)
|
||||
{
|
||||
sq_getuserpointer(vm, idx, outPtr);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void sqPushValue(SQVM* vm, T value)
|
||||
{
|
||||
static_assert(
|
||||
std::is_same_v<T, bool> ||
|
||||
std::is_same_v<T, Bool> ||
|
||||
std::is_same_v<T, Int> ||
|
||||
std::is_same_v<T, Float> ||
|
||||
std::is_same_v<T, const SQChar*> ||
|
||||
std::is_same_v<T, SQObject> ||
|
||||
std::is_same_v<T, String> ||
|
||||
std::is_same_v<T, String&> ||
|
||||
std::is_same_v<T, SQUserPointer> ||
|
||||
std::derived_from<T, Instance>,
|
||||
"Not supported return type");
|
||||
|
||||
if constexpr (std::is_same_v<T, bool>)
|
||||
sq_pushbool(vm, value);
|
||||
if constexpr (std::is_same_v<T, Bool>)
|
||||
sq_pushbool(vm, value);
|
||||
if constexpr (std::is_same_v<T, Int>)
|
||||
sq_pushinteger(vm, value);
|
||||
if constexpr (std::is_same_v<T, Float>)
|
||||
sq_pushfloat(vm, value);
|
||||
if constexpr (std::is_same_v<T, SQChar*>)
|
||||
sq_pushstring(vm, value, -1);
|
||||
if constexpr (std::is_same_v<T, SQObject>)
|
||||
sq_pushobject(vm, value);
|
||||
if constexpr (std::is_same_v<T, String> || std::is_same_v<T, String&>)
|
||||
sq_pushstring(vm, value.c_str(), value.length());
|
||||
if constexpr (std::is_same_v<T, SQUserPointer>)
|
||||
sq_pushuserpointer(vm, value);
|
||||
if constexpr (std::derived_from<T, Instance>)
|
||||
sq_pushobject(vm, value.getInstance());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T returnVar()
|
||||
{
|
||||
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
|
||||
static_assert(
|
||||
std::is_same_v<T, SQObject> ||
|
||||
std::is_same_v<T, Bool> ||
|
||||
std::is_same_v<T, Float> ||
|
||||
std::is_same_v<T, Int> ||
|
||||
std::is_same_v<T, String>,
|
||||
"Not supported return type");
|
||||
|
||||
T result{};
|
||||
sqGetValue(vm, -1, &result);
|
||||
sq_pop(vm, 1); // pops result
|
||||
return result;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline String returnVar<String>()
|
||||
{
|
||||
const SQChar* result = "";
|
||||
sq_getstring(Sqrat::DefaultVM::Get(), -1, &result);
|
||||
sq_pop(Sqrat::DefaultVM::Get(), 1); // pops result
|
||||
return result;
|
||||
}
|
||||
}
|
||||
#endif // NONUT_CORE_UTILS_H
|
||||
Reference in New Issue
Block a user