mirror of
https://github.com/edubart/otclient.git
synced 2025-10-20 06:23:26 +02:00
make otml simpler and easier to use, improve error handling/exceptions
This commit is contained in:
@@ -39,7 +39,7 @@ namespace luabinder
|
||||
/// C++ function caller that can push results to lua
|
||||
template<typename Ret, typename F, typename... Args>
|
||||
typename std::enable_if<!std::is_void<Ret>::value, int>::type
|
||||
call_fun_and_push_result(const F& f, LuaInterface* lua, Args... args) {
|
||||
call_fun_and_push_result(const F& f, LuaInterface* lua, const Args&... args) {
|
||||
Ret ret = f(args...);
|
||||
lua->polymorphicPush(ret);
|
||||
return 1;
|
||||
@@ -48,7 +48,7 @@ namespace luabinder
|
||||
/// C++ void function caller
|
||||
template<typename Ret, typename F, typename... Args>
|
||||
typename std::enable_if<std::is_void<Ret>::value, int>::type
|
||||
call_fun_and_push_result(const F& f, LuaInterface* lua, Args... args) {
|
||||
call_fun_and_push_result(const F& f, LuaInterface* lua, const Args&... args) {
|
||||
f(args...);
|
||||
return 0;
|
||||
}
|
||||
@@ -57,14 +57,14 @@ namespace luabinder
|
||||
template<int N, typename Ret>
|
||||
struct expand_fun_arguments {
|
||||
template<typename Tuple, typename F, typename... Args>
|
||||
static int call(const Tuple& tuple, const F& f, LuaInterface* lua, Args... args) {
|
||||
return expand_fun_arguments<N-1,Ret>::call(tuple, f, lua, std::cref(std::get<N-1>(tuple)), args...);
|
||||
static int call(const Tuple& tuple, const F& f, LuaInterface* lua, const Args&... args) {
|
||||
return expand_fun_arguments<N-1,Ret>::call(tuple, f, lua, std::get<N-1>(tuple), args...);
|
||||
}
|
||||
};
|
||||
template<typename Ret>
|
||||
struct expand_fun_arguments<0,Ret> {
|
||||
template<typename Tuple, typename F, typename... Args>
|
||||
static int call(const Tuple& tuple, const F& f, LuaInterface* lua, Args... args) {
|
||||
static int call(const Tuple& tuple, const F& f, LuaInterface* lua, const Args&... args) {
|
||||
return call_fun_and_push_result<Ret>(f, lua, args...);
|
||||
}
|
||||
};
|
||||
@@ -178,7 +178,7 @@ namespace luabinder
|
||||
template<typename Ret, typename Obj, typename... Args>
|
||||
LuaCppFunction bind_mem_fun(Ret (Obj::*f)(Args...)) {
|
||||
auto mf = std::mem_fn(f);
|
||||
typedef typename std::tuple<Obj*, typename remove_const_ref<Args>::type...> Tuple;
|
||||
typedef typename std::tuple<std::shared_ptr<Obj>, typename remove_const_ref<Args>::type...> Tuple;
|
||||
return bind_fun_specializer<typename remove_const_ref<Ret>::type,
|
||||
decltype(mf),
|
||||
Tuple>(mf);
|
||||
@@ -186,7 +186,7 @@ namespace luabinder
|
||||
template<typename Ret, typename Obj, typename... Args>
|
||||
LuaCppFunction bind_mem_fun(Ret (Obj::*f)(Args...) const) {
|
||||
auto mf = std::mem_fn(f);
|
||||
typedef typename std::tuple<Obj*, typename remove_const_ref<Args>::type...> Tuple;
|
||||
typedef typename std::tuple<std::shared_ptr<Obj>, typename remove_const_ref<Args>::type...> Tuple;
|
||||
return bind_fun_specializer<typename remove_const_ref<Ret>::type,
|
||||
decltype(mf),
|
||||
Tuple>(mf);
|
||||
@@ -197,7 +197,7 @@ namespace luabinder
|
||||
LuaCppFunction bind_mem_fun(int (Obj::*f)(LuaInterface*)) {
|
||||
auto mf = std::mem_fn(f);
|
||||
return [=](LuaInterface* lua) {
|
||||
auto obj = lua->castValue<Obj*>(1);
|
||||
auto obj = lua->castValue<std::shared_ptr<Obj>>(1);
|
||||
lua->remove(1);
|
||||
return mf(obj, lua);
|
||||
};
|
||||
|
202
src/framework/luascript/luavaluecasts.cpp
Normal file
202
src/framework/luascript/luavaluecasts.cpp
Normal file
@@ -0,0 +1,202 @@
|
||||
#include "luavaluecasts.h"
|
||||
#include "luainterface.h"
|
||||
#include <framework/otml/otmlnode.h>
|
||||
|
||||
// bool
|
||||
void push_luavalue(bool b)
|
||||
{
|
||||
g_lua.pushBoolean(b);
|
||||
}
|
||||
|
||||
bool luavalue_cast(int index, bool& b)
|
||||
{
|
||||
b = g_lua.toBoolean(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
// int
|
||||
void push_luavalue(int i)
|
||||
{
|
||||
g_lua.pushInteger(i);
|
||||
}
|
||||
|
||||
bool luavalue_cast(int index, int& i)
|
||||
{
|
||||
i = g_lua.toInteger(index);
|
||||
if(i == 0 && !g_lua.isNumber(index))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// double
|
||||
void push_luavalue(double d)
|
||||
{
|
||||
g_lua.pushNumber(d);
|
||||
}
|
||||
|
||||
bool luavalue_cast(int index, double& d)
|
||||
{
|
||||
d = g_lua.toNumber(index);
|
||||
if(d == 0 && !g_lua.isNumber(index))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// string
|
||||
void push_luavalue(const char* cstr)
|
||||
{
|
||||
g_lua.pushCString(cstr);
|
||||
}
|
||||
|
||||
void push_luavalue(const std::string& str)
|
||||
{
|
||||
g_lua.pushString(str);
|
||||
}
|
||||
|
||||
bool luavalue_cast(int index, std::string& str)
|
||||
{
|
||||
str = g_lua.toString(index);
|
||||
if(str.empty() && !g_lua.isString(index))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// lua cpp function
|
||||
void push_luavalue(const LuaCppFunction& func)
|
||||
{
|
||||
g_lua.pushCppFunction(func);
|
||||
}
|
||||
|
||||
// color
|
||||
void push_luavalue(const Color& color)
|
||||
{
|
||||
g_lua.newTable();
|
||||
g_lua.pushInteger(color.r());
|
||||
g_lua.setField("r");
|
||||
g_lua.pushInteger(color.g());
|
||||
g_lua.setField("g");
|
||||
g_lua.pushInteger(color.b());
|
||||
g_lua.setField("b");
|
||||
g_lua.pushInteger(color.a());
|
||||
g_lua.setField("a");
|
||||
}
|
||||
|
||||
bool luavalue_cast(int index, Color& color)
|
||||
{
|
||||
if(g_lua.isTable(index)) {
|
||||
g_lua.getField("r", index);
|
||||
color.setRed(g_lua.popInteger());
|
||||
g_lua.getField("g", index);
|
||||
color.setGreen(g_lua.popInteger());
|
||||
g_lua.getField("b", index);
|
||||
color.setBlue(g_lua.popInteger());
|
||||
g_lua.getField("a", index);
|
||||
color.setAlpha(g_lua.popInteger());
|
||||
return true;
|
||||
} else if(g_lua.isString()) {
|
||||
return fw::cast(g_lua.toString(index), color);
|
||||
} else if(g_lua.isNil()) {
|
||||
color = Color::white;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// rect
|
||||
void push_luavalue(const Rect& rect)
|
||||
{
|
||||
g_lua.newTable();
|
||||
g_lua.pushInteger(rect.x());
|
||||
g_lua.setField("x");
|
||||
g_lua.pushInteger(rect.y());
|
||||
g_lua.setField("y");
|
||||
g_lua.pushInteger(rect.width());
|
||||
g_lua.setField("width");
|
||||
g_lua.pushInteger(rect.height());
|
||||
g_lua.setField("height");
|
||||
}
|
||||
|
||||
bool luavalue_cast(int index, Rect& rect)
|
||||
{
|
||||
if(g_lua.isTable(index)) {
|
||||
g_lua.getField("x", index);
|
||||
rect.setX(g_lua.popInteger());
|
||||
g_lua.getField("y", index);
|
||||
rect.setY(g_lua.popInteger());
|
||||
g_lua.getField("width", index);
|
||||
rect.setWidth(g_lua.popInteger());
|
||||
g_lua.getField("height", index);
|
||||
rect.setHeight(g_lua.popInteger());
|
||||
} else if(g_lua.isString()) {
|
||||
return fw::cast(g_lua.toString(index), rect);
|
||||
} else if(g_lua.isNil()) {
|
||||
rect = Rect();
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// point
|
||||
void push_luavalue(const Point& point)
|
||||
{
|
||||
g_lua.newTable();
|
||||
g_lua.pushInteger(point.x);
|
||||
g_lua.setField("x");
|
||||
g_lua.pushInteger(point.y);
|
||||
g_lua.setField("y");
|
||||
}
|
||||
|
||||
bool luavalue_cast(int index, Point& point)
|
||||
{
|
||||
if(g_lua.isTable(index)) {
|
||||
g_lua.getField("x", index);
|
||||
point.x = g_lua.popInteger();
|
||||
g_lua.getField("y", index);
|
||||
point.y = g_lua.popInteger();
|
||||
return true;
|
||||
} else if(g_lua.isString()) {
|
||||
return fw::cast(g_lua.toString(index), point);
|
||||
} else if(g_lua.isNil()) {
|
||||
point = Point();
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// otml nodes
|
||||
void push_luavalue(const OTMLNodePtr& node)
|
||||
{
|
||||
if(node->hasValue()) {
|
||||
g_lua.pushString(node->value());
|
||||
} else if(node->hasChildren()) {
|
||||
g_lua.newTable();
|
||||
bool pushedChild = false;
|
||||
for(const OTMLNodePtr& cnode : node->children()) {
|
||||
if(cnode->isUnique()) {
|
||||
push_luavalue(cnode);
|
||||
if(!g_lua.isNil()) {
|
||||
g_lua.setField(cnode->tag());
|
||||
pushedChild = true;
|
||||
} else
|
||||
g_lua.pop();
|
||||
}
|
||||
}
|
||||
if(!pushedChild) {
|
||||
g_lua.pop();
|
||||
g_lua.pushNil();
|
||||
}
|
||||
} else
|
||||
g_lua.pushNil();
|
||||
}
|
||||
|
||||
// object ptr
|
||||
bool luavalue_cast(int index, LuaObjectPtr& obj) {
|
||||
if(g_lua.isUserdata(index)) {
|
||||
obj = g_lua.toObject(index);
|
||||
return true;
|
||||
} else if(g_lua.isNil(index)) {
|
||||
obj = nullptr;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
@@ -2,137 +2,123 @@
|
||||
#define LUAVALUECASTS_H
|
||||
|
||||
// this file is and must be included only from luainterface.h
|
||||
#include "luainterface.h"
|
||||
#include "luaexception.h"
|
||||
|
||||
/// Pushes bool
|
||||
inline void push_luavalue(bool v) {
|
||||
g_lua.pushBoolean(v);
|
||||
}
|
||||
#include "declarations.h"
|
||||
#include <framework/otml/declarations.h>
|
||||
|
||||
/// Pushes int
|
||||
inline void push_luavalue(int v) {
|
||||
g_lua.pushInteger(v);
|
||||
}
|
||||
// bool
|
||||
void push_luavalue(bool b);
|
||||
bool luavalue_cast(int index, bool& b);
|
||||
|
||||
/// Pushes double
|
||||
inline void push_luavalue(double v) {
|
||||
g_lua.pushNumber(v);
|
||||
}
|
||||
// int
|
||||
void push_luavalue(int i);
|
||||
bool luavalue_cast(int index, int& i);
|
||||
|
||||
/// Pushes std::string
|
||||
inline void push_luavalue(const std::string& v) {
|
||||
g_lua.pushString(v);
|
||||
}
|
||||
// double
|
||||
void push_luavalue(double d);
|
||||
bool luavalue_cast(int index, double& d);
|
||||
|
||||
/// Pushes const char*
|
||||
inline void push_luavalue(const char* v) {
|
||||
g_lua.pushCString(v);
|
||||
}
|
||||
// string
|
||||
void push_luavalue(const char* cstr);
|
||||
void push_luavalue(const std::string& str);
|
||||
bool luavalue_cast(int index, std::string& str);
|
||||
|
||||
/// Pushes LuaCppFunction
|
||||
inline void push_luavalue(const LuaCppFunction& v) {
|
||||
g_lua.pushCppFunction(v);
|
||||
}
|
||||
// lua cpp function
|
||||
void push_luavalue(const LuaCppFunction& func);
|
||||
|
||||
/// Pushes LuaObjectPtr
|
||||
// color
|
||||
void push_luavalue(const Color& color);
|
||||
bool luavalue_cast(int index, Color& color);
|
||||
|
||||
// rect
|
||||
void push_luavalue(const Rect& rect);
|
||||
bool luavalue_cast(int index, Rect& rect);
|
||||
|
||||
// point
|
||||
void push_luavalue(const Point& point);
|
||||
bool luavalue_cast(int index, Point& point);
|
||||
|
||||
// size
|
||||
void push_luavalue(const Size& size);
|
||||
bool luavalue_cast(int index, Size& size);
|
||||
|
||||
// otml nodes
|
||||
void push_luavalue(const OTMLNodePtr& node);
|
||||
|
||||
// enum
|
||||
template<class T>
|
||||
typename std::enable_if<std::is_enum<T>::value, bool>::type
|
||||
luavalue_cast(int index, T& myenum);
|
||||
|
||||
// LuaObject pointers
|
||||
template<class T>
|
||||
typename std::enable_if<std::is_base_of<LuaObject, typename T::element_type>::value, void>::type
|
||||
push_luavalue(const T& v) {
|
||||
if(v)
|
||||
return g_lua.pushObject(v);
|
||||
push_luavalue(const T& obj);
|
||||
|
||||
bool luavalue_cast(int index, LuaObjectPtr& obj);
|
||||
|
||||
template<class T>
|
||||
typename std::enable_if<std::is_base_of<LuaObject, T>::value, bool>::type
|
||||
luavalue_cast(int index, std::shared_ptr<T>& ptr);
|
||||
|
||||
// std::function
|
||||
template<typename Ret, typename... Args>
|
||||
void push_luavalue(const std::function<Ret(Args...)>& func);
|
||||
|
||||
template<typename... Args>
|
||||
bool luavalue_cast(int index, std::function<void(Args...)>& func);
|
||||
|
||||
template<typename Ret, typename... Args>
|
||||
typename std::enable_if<!std::is_void<Ret>::value, bool>::type
|
||||
luavalue_cast(int index, std::function<Ret(Args...)>& func);
|
||||
|
||||
|
||||
// start definitions
|
||||
|
||||
#include "luaexception.h"
|
||||
#include "luainterface.h"
|
||||
|
||||
template<class T>
|
||||
typename std::enable_if<std::is_enum<T>::value, bool>::type
|
||||
luavalue_cast(int index, T& myenum) {
|
||||
return luavalue_cast(index, (int&)myenum);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
typename std::enable_if<std::is_base_of<LuaObject, typename T::element_type>::value, void>::type
|
||||
push_luavalue(const T& obj) {
|
||||
if(obj)
|
||||
return g_lua.pushObject(obj);
|
||||
return g_lua.pushNil();
|
||||
}
|
||||
|
||||
/// Push std::function types
|
||||
template<class T>
|
||||
typename std::enable_if<std::is_base_of<LuaObject, T>::value, bool>::type
|
||||
luavalue_cast(int index, std::shared_ptr<T>& ptr) {
|
||||
LuaObjectPtr obj;
|
||||
if(!luavalue_cast(index, obj))
|
||||
return false;
|
||||
ptr = std::dynamic_pointer_cast<T>(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename Ret, typename... Args>
|
||||
void push_luavalue(const std::function<Ret(Args...)>& v) {
|
||||
if(v) {
|
||||
LuaCppFunction f = luabinder::bind_fun(v);
|
||||
void push_luavalue(const std::function<Ret(Args...)>& func) {
|
||||
if(func) {
|
||||
LuaCppFunction f = luabinder::bind_fun(func);
|
||||
g_lua.pushCppFunction(f);
|
||||
} else
|
||||
g_lua.pushNil();
|
||||
}
|
||||
|
||||
/// Casts lua value to bool
|
||||
inline bool luavalue_cast(int index, bool& o) {
|
||||
o = g_lua.toBoolean(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Casts lua value to int
|
||||
inline bool luavalue_cast(int index, int& o) {
|
||||
o = g_lua.toInteger(index);
|
||||
if(o == 0 && !g_lua.isNumber(index))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Casts lua value to double
|
||||
inline bool luavalue_cast(int index, double& o) {
|
||||
o = g_lua.toNumber(index);
|
||||
if(o == 0 && !g_lua.isNumber(index))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Casts lua value to std::string
|
||||
inline bool luavalue_cast(int index, std::string& o) {
|
||||
o = g_lua.toString(index);
|
||||
if(o.empty() && !g_lua.isString(index))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Casts lua value to LuaObjectPtr
|
||||
inline bool luavalue_cast(int index, LuaObjectPtr& o) {
|
||||
if(g_lua.isUserdata(index)) {
|
||||
o = g_lua.toObject(index);
|
||||
return true;
|
||||
} else if(g_lua.isNil(index)) {
|
||||
o = nullptr;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Casts lua value to enum
|
||||
template<class T>
|
||||
typename std::enable_if<std::is_enum<T>::value, bool>::type
|
||||
luavalue_cast(int index, T& o) {
|
||||
return luavalue_cast(index, (int&)o);
|
||||
}
|
||||
|
||||
/// Cast lua userdata to a class pointer
|
||||
template<class T>
|
||||
typename std::enable_if<std::is_base_of<LuaObject, T>::value, bool>::type
|
||||
luavalue_cast(int index, T*& o) {
|
||||
LuaObjectPtr obj;
|
||||
if(!luavalue_cast(index, obj))
|
||||
return false;
|
||||
o = std::dynamic_pointer_cast<T>(obj).get();
|
||||
return !!o;
|
||||
}
|
||||
|
||||
/// Cast lua userdata to a class shared pointer
|
||||
template<class T>
|
||||
bool luavalue_cast(int index, std::shared_ptr<T>& o) {
|
||||
LuaObjectPtr obj;
|
||||
if(!luavalue_cast(index, obj))
|
||||
return false;
|
||||
o = std::dynamic_pointer_cast<T>(obj);
|
||||
return !!o;
|
||||
}
|
||||
|
||||
/// Cast a lua function to a std::function
|
||||
template<typename... Args>
|
||||
bool luavalue_cast(int index, std::function<void(Args...)>& o) {
|
||||
bool luavalue_cast(int index, std::function<void(Args...)>& func) {
|
||||
if(g_lua.isFunction(index)) {
|
||||
g_lua.pushValue(index);
|
||||
// weak references are used here, this means that the script must hold another reference
|
||||
// to this function, otherwise it will expire
|
||||
int funcWeakRef = g_lua.weakRef();
|
||||
o = [=](Args... args...) {
|
||||
func = [=](Args... args...) {
|
||||
// note that we must catch exceptions, because this lambda can be called from anywhere
|
||||
// and most of them won't catch exceptions (e.g. dispatcher)
|
||||
g_lua.getWeakRef(funcWeakRef);
|
||||
@@ -150,22 +136,21 @@ bool luavalue_cast(int index, std::function<void(Args...)>& o) {
|
||||
};
|
||||
return true;
|
||||
} else if(g_lua.isNil(index)) {
|
||||
o = std::function<void(Args...)>();
|
||||
func = std::function<void(Args...)>();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Cast a lua function to a std::function that can return
|
||||
template<typename Ret, typename... Args>
|
||||
typename std::enable_if<!std::is_void<Ret>::value, bool>::type
|
||||
luavalue_cast(int index, std::function<Ret(Args...)>& o) {
|
||||
luavalue_cast(int index, std::function<Ret(Args...)>& func) {
|
||||
if(g_lua.isFunction(index)) {
|
||||
g_lua.pushValue(index);
|
||||
// weak references are used here, this means that the script must hold another reference
|
||||
// to this function, otherwise it will expire
|
||||
int funcWeakRef = g_lua.weakRef();
|
||||
o = [=](Args... args...) -> Ret {
|
||||
func = [=](Args... args...) -> Ret {
|
||||
// note that we must catch exceptions, because this lambda can be called from anywhere
|
||||
// and most of them won't catch exceptions (e.g. dispatcher)
|
||||
try {
|
||||
@@ -186,40 +171,10 @@ luavalue_cast(int index, std::function<Ret(Args...)>& o) {
|
||||
};
|
||||
return true;
|
||||
} else if(g_lua.isNil(index)) {
|
||||
o = std::function<Ret(Args...)>();
|
||||
func = std::function<Ret(Args...)>();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// additional casts
|
||||
|
||||
|
||||
inline void push_luavalue(const Color& v) {
|
||||
g_lua.newTable();
|
||||
g_lua.pushInteger(v.r());
|
||||
g_lua.setField("r");
|
||||
g_lua.pushInteger(v.g());
|
||||
g_lua.setField("g");
|
||||
g_lua.pushInteger(v.b());
|
||||
g_lua.setField("b");
|
||||
g_lua.pushInteger(v.a());
|
||||
g_lua.setField("a");
|
||||
}
|
||||
|
||||
inline bool luavalue_cast(int index, Color& o) {
|
||||
if(!g_lua.isTable(index))
|
||||
return false;
|
||||
|
||||
g_lua.getField("r", index);
|
||||
o.setRed(g_lua.popInteger());
|
||||
g_lua.getField("g", index);
|
||||
o.setGreen(g_lua.popInteger());
|
||||
g_lua.getField("b", index);
|
||||
o.setBlue(g_lua.popInteger());
|
||||
g_lua.getField("a", index);
|
||||
o.setAlpha(g_lua.popInteger());
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user