2011-08-14 04:09:11 +02:00
|
|
|
#ifndef LUAVALUECASTS_H
|
|
|
|
#define LUAVALUECASTS_H
|
|
|
|
|
|
|
|
// this file is and must be included only from luainterface.h
|
|
|
|
|
2011-08-19 20:53:23 +02:00
|
|
|
#include "declarations.h"
|
|
|
|
#include <framework/otml/declarations.h>
|
2011-08-14 04:09:11 +02:00
|
|
|
|
2011-08-19 20:53:23 +02:00
|
|
|
// bool
|
|
|
|
void push_luavalue(bool b);
|
|
|
|
bool luavalue_cast(int index, bool& b);
|
2011-08-14 04:09:11 +02:00
|
|
|
|
2011-08-19 20:53:23 +02:00
|
|
|
// int
|
|
|
|
void push_luavalue(int i);
|
|
|
|
bool luavalue_cast(int index, int& i);
|
2011-08-14 04:09:11 +02:00
|
|
|
|
2011-08-19 20:53:23 +02:00
|
|
|
// double
|
|
|
|
void push_luavalue(double d);
|
|
|
|
bool luavalue_cast(int index, double& d);
|
2011-08-14 04:09:11 +02:00
|
|
|
|
2011-08-20 22:30:41 +02:00
|
|
|
// size_t
|
|
|
|
void push_luavalue(std::size_t s);
|
|
|
|
bool luavalue_cast(int index, std::size_t& s);
|
|
|
|
|
2011-08-19 20:53:23 +02:00
|
|
|
// string
|
|
|
|
void push_luavalue(const char* cstr);
|
|
|
|
void push_luavalue(const std::string& str);
|
|
|
|
bool luavalue_cast(int index, std::string& str);
|
2011-08-14 04:09:11 +02:00
|
|
|
|
2011-08-19 20:53:23 +02:00
|
|
|
// lua cpp function
|
|
|
|
void push_luavalue(const LuaCppFunction& func);
|
|
|
|
|
|
|
|
// color
|
|
|
|
void push_luavalue(const Color& color);
|
|
|
|
bool luavalue_cast(int index, Color& color);
|
2011-08-14 04:09:11 +02:00
|
|
|
|
2011-08-19 20:53:23 +02:00
|
|
|
// 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
|
2011-08-14 04:09:11 +02:00
|
|
|
template<class T>
|
|
|
|
typename std::enable_if<std::is_base_of<LuaObject, typename T::element_type>::value, void>::type
|
2011-08-19 20:53:23 +02:00
|
|
|
push_luavalue(const T& obj);
|
2011-08-14 04:09:11 +02:00
|
|
|
|
2011-08-19 20:53:23 +02:00
|
|
|
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
|
2011-08-14 04:09:11 +02:00
|
|
|
template<typename Ret, typename... Args>
|
2011-08-19 20:53:23 +02:00
|
|
|
void push_luavalue(const std::function<Ret(Args...)>& func);
|
2011-08-14 04:09:11 +02:00
|
|
|
|
2011-08-19 20:53:23 +02:00
|
|
|
template<typename... Args>
|
|
|
|
bool luavalue_cast(int index, std::function<void(Args...)>& func);
|
2011-08-14 04:09:11 +02:00
|
|
|
|
2011-08-19 20:53:23 +02:00
|
|
|
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);
|
2011-08-14 04:09:11 +02:00
|
|
|
|
|
|
|
|
2011-08-19 20:53:23 +02:00
|
|
|
// start definitions
|
2011-08-14 04:09:11 +02:00
|
|
|
|
2011-08-19 20:53:23 +02:00
|
|
|
#include "luaexception.h"
|
|
|
|
#include "luainterface.h"
|
2011-08-14 04:09:11 +02:00
|
|
|
|
|
|
|
template<class T>
|
|
|
|
typename std::enable_if<std::is_enum<T>::value, bool>::type
|
2011-08-19 20:53:23 +02:00
|
|
|
luavalue_cast(int index, T& myenum) {
|
|
|
|
return luavalue_cast(index, (int&)myenum);
|
2011-08-14 04:09:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class T>
|
2011-08-19 20:53:23 +02:00
|
|
|
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();
|
2011-08-14 04:09:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class T>
|
2011-08-19 20:53:23 +02:00
|
|
|
typename std::enable_if<std::is_base_of<LuaObject, T>::value, bool>::type
|
|
|
|
luavalue_cast(int index, std::shared_ptr<T>& ptr) {
|
2011-08-14 04:09:11 +02:00
|
|
|
LuaObjectPtr obj;
|
|
|
|
if(!luavalue_cast(index, obj))
|
|
|
|
return false;
|
2011-08-19 20:53:23 +02:00
|
|
|
ptr = std::dynamic_pointer_cast<T>(obj);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename Ret, typename... Args>
|
|
|
|
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();
|
2011-08-14 04:09:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
template<typename... Args>
|
2011-08-19 20:53:23 +02:00
|
|
|
bool luavalue_cast(int index, std::function<void(Args...)>& func) {
|
2011-08-14 04:09:11 +02:00
|
|
|
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();
|
2011-08-19 20:53:23 +02:00
|
|
|
func = [=](Args... args...) {
|
2011-08-14 04:09:11 +02:00
|
|
|
// 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);
|
|
|
|
try {
|
|
|
|
if(g_lua.isFunction()) {
|
|
|
|
g_lua.polymorphicPush(args...);
|
|
|
|
assert(g_lua.safeCall(sizeof...(Args)) == 0);
|
|
|
|
} else {
|
|
|
|
throw LuaException("attempt to call an expired lua function from C++,"
|
|
|
|
"did you forget to hold a reference for that function?", 0);
|
|
|
|
}
|
|
|
|
} catch(std::exception& e) {
|
2011-08-20 22:30:41 +02:00
|
|
|
logError("lua function callback failed: ", e.what());
|
2011-08-14 04:09:11 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
return true;
|
|
|
|
} else if(g_lua.isNil(index)) {
|
2011-08-19 20:53:23 +02:00
|
|
|
func = std::function<void(Args...)>();
|
2011-08-14 04:09:11 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename Ret, typename... Args>
|
|
|
|
typename std::enable_if<!std::is_void<Ret>::value, bool>::type
|
2011-08-19 20:53:23 +02:00
|
|
|
luavalue_cast(int index, std::function<Ret(Args...)>& func) {
|
2011-08-14 04:09:11 +02:00
|
|
|
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();
|
2011-08-19 20:53:23 +02:00
|
|
|
func = [=](Args... args...) -> Ret {
|
2011-08-14 04:09:11 +02:00
|
|
|
// 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 {
|
|
|
|
g_lua.getWeakRef(funcWeakRef);
|
|
|
|
if(g_lua.isFunction()) {
|
|
|
|
g_lua.polymorphicPush(args...);
|
|
|
|
if(g_lua.safeCall(sizeof...(Args)) != 1)
|
|
|
|
throw LuaException("a function from lua didn't retrieve the expected number of results", 0);
|
|
|
|
return g_lua.polymorphicPop<Ret>();
|
|
|
|
} else {
|
|
|
|
throw LuaException("attempt to call an expired lua function from C++,"
|
|
|
|
"did you forget to hold a reference for that function?", 0);
|
|
|
|
}
|
|
|
|
} catch(std::exception& e) {
|
2011-08-20 22:30:41 +02:00
|
|
|
logError("lua function callback failed: ", e.what());
|
2011-08-14 04:09:11 +02:00
|
|
|
}
|
|
|
|
return Ret();
|
|
|
|
};
|
|
|
|
return true;
|
|
|
|
} else if(g_lua.isNil(index)) {
|
2011-08-19 20:53:23 +02:00
|
|
|
func = std::function<Ret(Args...)>();
|
2011-08-14 04:09:11 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|