satoren / kaguya Goto Github PK
View Code? Open in Web Editor NEWC++ binding to Lua
License: Boost Software License 1.0
C++ binding to Lua
License: Boost Software License 1.0
Can I do an "addMember" of an overloaded method in kaguya ?
If not, is it possible to add this feature ?
For exemple if we have :
class Vector2
{
...
};
class A
{
public:
void move(int x, int y, bool moveNow = true);
void move(Vector2 pos, moveNow = true);
};
When binding, how should I use KAGUYA_MEMBER_FUNCTION_OVERLOADS ?
Please add documentation to lua_type_traits
. I'm not really sure what the members mean, especially weakTypeTest
and typeTest
(their difference). Probably rename them (I guess weakTypeTest
means: isConvertible
and typeTest
means isType
)
Especially confusing is the implementation of template<> struct lua_type_traits<void>
of which I assume is taken when a void*
is pushed or retrieved. Is it actually possible to do state["value"] = (void*) 0xDEAD;
and retrieve it? If so, can you outline what happens/which traits are used?
for example:
class Vector3
{
public:
Vector3(float x, float y, float z);
};
It can call
local vec = Vector3.new(1, 2, 3)
to create a vector3 object. but sometimes I want to create the user data with
local vec = Vector3(1, 2, 3)
```,
Is possible add ```__call``` method for class?
lua_rawget_rtype is not define in lua5.1
Hi,
Kaguya don't work on macOS
/include/kaguya/object.hpp:86:11: error: no viable conversion from returned value of type '__bit_iterator<std::__1::vector<bool, std::__1::allocator<bool> >, true>' to function return type 'const void *' return &object_; ^~~~~~~~ /Users/arthapz/Downloads/ObEngine-master/extlibs/include/kaguya/object.hpp:63:3: note: in instantiation of member function 'kaguya::ObjectWrapper<std::__1::__bit_const_reference<std::__1::vector<bool, std::__1::allocator<bool> > > >::cget' requested here ObjectWrapper(Args&&... args) : object_(std::forward<Args>(args)...) {} ^ /Users/arthapz/Downloads/ObEngine-master/extlibs/include/kaguya/object.hpp:732:17: note: in instantiation of function template specialization 'kaguya::ObjectWrapper<std::__1::__bit_const_reference<std::__1::vector<bool, std::__1::allocator<bool> > > >::ObjectWrapper<std::__1::__bit_const_reference<std::__1::vector<bool, std::__1::allocator<bool> > > >' requested here new(storage) wrapper_type(std::forward<T>(v)); ^ /Users/arthapz/Downloads/ObEngine-master/extlibs/include/kaguya/type.hpp:66:16: note: in instantiation of function template specialization 'kaguya::util::object_push<std::__1::__bit_const_reference<std::__1::vector<bool, std::__1::allocator<bool> > > >' requested here return util::object_push(l,std::forward<NCRT>(v)); ^ /Users/arthapz/Downloads/ObEngine-master/extlibs/include/kaguya/utility.hpp:200:64: note: in instantiation of member function 'kaguya::lua_type_traits<std::__1::__bit_const_reference<std::__1::vector<bool, std::__1::allocator<bool> > >, void>::push' requested here int c = lua_type_traits<typename traits::decay<Arg>::type>::push(l, std::forward<Arg>(arg)); ^ /Users/arthapz/Downloads/ObEngine-master/extlibs/include/kaguya/utility.hpp:233:22: note: in instantiation of function template specialization 'kaguya::util::push_args<std::__1::__bit_const_reference<std::__1::vector<bool, std::__1::allocator<bool> > >>' requested here int count = util::push_args(state, std::forward<T>(v)); ^ /Users/arthapz/Downloads/ObEngine-master/extlibs/include/kaguya/lua_ref_table.hpp:497:11: note: (skipping 1 context in backtrace; use -ftemplate-backtrace-limit=0 to see all) util::one_push(l, *it); ^ /Users/arthapz/Downloads/ObEngine-master/extlibs/include/kaguya/utility.hpp:200:64: note: in instantiation of member function 'kaguya::lua_type_traits<std::__1::vector<bool, std::__1::allocator<bool> >, void>::push' requested here int c = lua_type_traits<typename traits::decay<Arg>::type>::push(l, std::forward<Arg>(arg)); ^ /Users/arthapz/Downloads/ObEngine-master/extlibs/include/kaguya/utility.hpp:233:22: note: in instantiation of function template specialization 'kaguya::util::push_args<std::__1::vector<bool, std::__1::allocator<bool> > &>' requested here int count = util::push_args(state, std::forward<T>(v)); ^ /Users/arthapz/Downloads/ObEngine-master/extlibs/include/kaguya/detail/lua_table_def.hpp:37:11: note: in instantiation of function template specialization 'kaguya::util::one_push<std::__1::vector<bool, std::__1::allocator<bool> > &>' requested here util::one_push(state, std::forward<V>(value)); ^ /Users/arthapz/Downloads/ObEngine-master/extlibs/include/kaguya/lua_ref_table.hpp:58:25: note: in instantiation of function template specialization 'kaguya::detail::table_proxy::set<std::__1::vector<bool, std::__1::allocator<bool> > &, std::__1::basic_string<char> &>' requested here detail::table_proxy::set(state_, table_index_, key_, std::forward<T>(src)); ^ /Users/arthapz/Downloads/ObEngine-master/src/GameObject.cpp:296:51: note: in instantiation of function template specialization 'kaguya::TableKeyReferenceProxy<std::__1::basic_string<char> >::operator=<std::__1::vector<bool, std::__1::allocator<bool> > &>' requested here (*m_objectScript)["cpp_param"][it->first] = allParam->at(it->first).second.as<std::vector<bool>>();
Hi.
Version 1.3.1 tar.gz source tarball contains some strange unicode characters instead of second "1":
https://github.com/satoren/kaguya/archive/v1.3.%EF%BC%91.tar.gz
Could you please fix file name?
Hey :)
I can't call the C++ function in Lua I just registered :(
void print_text(const char* msg)
{
//printf("%s", msg.c_str());
std::cout << "kaguya rocks ! " << msg << std::endl;
}
kaguya::State state;
kaguya::LoadLibs();
state.dofile("test.lua");
state["print_text"] = &print_text;
I always get "test.lua:7: attempt to call a nil value (global 'print_text')"
but calling state["print_text"]("meep");
works :P
In my lua script it's just print_text("hello world\n)
Do you plan to add support for templates when adding constructor, members or functions to a ClassMetatable ?
It works when you specify the type but could it be possible to leave the type empty and let Lua use any type ?
When a global function with first argument is Object& or Object*, Can I treat is as a member function for usertype. e.g.
float Length(Vector2& vec)
{
return sqrtf(vec.x * vec.x + vec.y * vec.y);
}
In Lua:
local vec = Vector2:new(10, 10)
local length = vec:Length()
Now I can register it as a static function for usertype.
I would like to detect runtime errors when I call a lua function. I tried this, (similar to https://github.com/satoren/kaguya/blob/master/test/test_06_state.cpp ) but no exception is thrown.
luaState.setErrorHandler(kaguya::ErrorHandler::throwDefaultError);
kaguya::LuaFunction way_function = luaState["way_function"];
kaguya::LuaRef ret = way_function(&sharedData.osmObject);
I have a deliberate error in the lua code which I would expect to say variable not defined:
function way_function(way)
local highway = way:Find("highway")
local waterway = way:Find("waterway")
if highway~="" then
way:Layer("transportation", false)
way:Attribute("class", highway)
end
if waterway~="" then
way:Layer("waterway", false)
way:Attribute("class", waterway)
end
if building~="" then
way:Layer("building", true)
end
end
Any ideas?
I created the following class in C++ :
class BaseAttribute
{
private:
std::string data;
public:
BaseAttribute(std::string data);
template <typename T> T get();
template <> inline int get() {
return std::stoi(data);
}
template <> inline double get() {
return std::stod(data);
}
template <> inline bool get() {
return (data == "True") ? true : false;
}
template <> inline std::string get() {
return data;
}
}
I used the following code to bind this class in Lua :
(*lua)["BaseAttribute"].setClass(kaguya::ClassMetatable<Data::BaseAttribute>()
.addConstructor<std::string, std::string, std::string>()
.addMember("get", static_cast<int(Data::BaseAttribute::*)()>(&Data::BaseAttribute::get))
.addMember("get", static_cast<double(Data::BaseAttribute::*)()>(&Data::BaseAttribute::get))
.addMember("get", static_cast<bool(Data::BaseAttribute::*)()>(&Data::BaseAttribute::get))
.addMember("get", static_cast<std::string(Data::BaseAttribute::*)()>(&Data::BaseAttribute::get))
);
"lua" variable is a kaguya::State*
Now when I use this in Lua :
local myattr = BaseAttribute.new("54.6");
print(myattr.get());
It'll only use the version. Is there a way to specify the template implementation I want to use in Lua?
Like with a myattr.get<double>();
With the current version, it seems that you can only set one base class. Is it possible to add multiple base class ?
Is there another way to access a subtable ?
I know you can do :
luavm["a"]["b"]["c"] = 10;
But is it possible to do something like :
std::string path = "a.b.c";
luavm.access(path);
?
Example test code:
using TestVect = vector<int>;
int getItem(TestVect &v, int i) { return v.at(i); }
struct TestStrcutWithVect {
TestVect vect;
};
TEST(Add_metatable_to_member_vector) {
kaguya::State s;
s["Vect"].setClass(kaguya::ClassMetatable<TestVect>().addStaticMember("getItem", getItem));
s["TestStrcutWithVect"].setClass(kaguya::ClassMetatable<TestStrcutWithVect>().addProperty(
"vect", &TestStrcutWithVect::vect));
TestStrcutWithVect test;
test.vect.push_back(123);
s["test"] = &test;
s("i = test.vect:getItem(0)");
EXPECT_THAT(s["i"], Eq(123));
}
Gives: [string "i = test.vect:getItem(0)"]:1: attempt to call method 'getItem' (a nil value) unknown file: error: C++ exception with description "nilis not __int64" thrown in the test body.
Following test also fails:
TEST(Pass_member_vector_to_free_function) {
kaguya::State s;
s["Vect"].setClass(kaguya::ClassMetatable<TestVect>());
s["TestStrcutWithVect"].setClass(kaguya::ClassMetatable<TestStrcutWithVect>().addProperty(
"vect", &TestStrcutWithVect::vect));
s["getItem"] = getItem;
TestStrcutWithVect test;
test.vect.push_back(123);
s["test"] = &test;
s("i = getItem(test.vect, 0)");
EXPECT_THAT(s["i"], Eq(123));
}
With message argument not matching:table,number candidated class std::vector<int,class std::allocator<int> >,int unknown file: error: C++ exception with description "nilis not __int64" thrown in the test body.
Same story with using TestVect = string;
. But if I replace using TestVect = vector<int>;
to struct TestVect : vector<int>{};
or using TestVect = array<int, 10>;
all tests pass.
If vector isn't a member then metatable is added and followig test passes:
using TestVect = vector<int>;
TEST(Add_metatable_to_vector) {
kaguya::State s;
s["Vect"].setClass(kaguya::ClassMetatable<TestVect>().addStaticMember("getItem", getItem));
TestVect vect;
vect.push_back(123);
s["vect"] = &vect;
s("i = vect:getItem(0)");
EXPECT_THAT(s["i"], Eq(123));
}
Maybe add nil support to smart pointers? To be able write something like:
boost::shared_ptr<Test> pp;
s["foo"] = kaguya::function([&](boost::shared_ptr<Test> p) { pp=p;});
s("foo(nil)");
ASSERT(pp == nullptr);
I changed behavior for boost::shared_ptr using trait like this:
namespace kaguya {
template <typename T>
struct lua_type_traits<boost::shared_ptr<T>> {
typedef const boost::shared_ptr<T> &push_type;
typedef boost::shared_ptr<T> get_type;
static bool checkType(lua_State *l, int index) {
return object_wrapper(l, index, metatableName<get_type>()) != nullptr ||
lua_type(l, index) == LUA_TNIL;
}
static bool strictCheckType(lua_State *l, int index) {
return object_wrapper(l, index, metatableName<get_type>()) != nullptr;
}
static get_type get(lua_State *l, int index) {
if (lua_type(l, index) == LUA_TNIL) {
return nullptr;
}
const get_type *pointer = get_const_pointer(l, index, types::typetag<get_type>());
if (!pointer) {
throw LuaTypeMismatch("type mismatch!!");
}
return *pointer;
}
static int push(lua_State *l, push_type v) {
typedef ObjectSmartPointerWrapper<boost::shared_ptr<T>> wrapper_type;
void *storage = lua_newuserdata(l, sizeof(wrapper_type));
new (storage) wrapper_type(v);
class_userdata::setmetatable<T>(l);
return 1;
}
};
}
Is it correct implementation?
Hi,
I've tried to compile and run some simple code using kaguya.
I compiled the same code twice, first with my system binary and
libraries (64 bits archlinux up to date) and then with a toolchain
for 32 bits x86.
In both cases the compilation is successful, my problem is when I run
the version compiled with the toolchain I get an error : "attempt to index a nil value"
(which I don't get with the version compiled directly with my system).
I tried to replicate the code logic using only the lua C api and then compiled
it again with my system binary and libraries then with the toolchain. In this
case both binaries works as expected.
My system uses g++ 6.2.1 while the toolchain is using g++ 4.9.2 (both meeting kaguya
requirements). I'm compiling with the std=c++11 option.
My system uses lua 5.3.3 while the toolchain uses 5.2.2
Here is the code which get me the "attempt to index a nil value" error :
#include "kaguya.hpp"
kaguya::State luaState;
auto scriptAdding2CppVariables = R"(
return valA + valB
)";
// Loading script in Lua context.
kaguya::LuaFunction luaFunc = luaState.loadstring(scriptAdding2CppVariables);
auto a = 1;
auto b = 2;
// Exporting variables to Lua context (under the same they're used in the previous script).
luaState["valA"] = a;
luaState["valB"] = b;
if (luaFunc() == a + b)
{
std::cout << "SUCCESS" << std::endl;
}
else
{
std::cout << "FAILED" << std::endl;
}
And here is the equivalent with the C api which does not trigger any error.
#ifdef __cplusplus
#include <lua.hpp>
#else
# include <lua.h>
# include <lualib.h>
# include <lauxlib.h>
#endif
lua_State* state;
auto scriptAdding2CppVariables = R"(
function add (varA, varB)
return varA + varB
end
)";
/* initialize Lua */
state = luaL_newstate();
luaL_dostring(state, scriptAdding2CppVariables);
lua_getglobal(state, "add");
auto varA = 1;
lua_pushnumber(state, varA);
auto varB = 2;
lua_pushnumber(state, varB);
lua_call(state, 2, 1);
/* call the add function */
auto sum = (int)lua_tointeger(state, -1);
lua_pop(state, 1);
if(sum == varA + varB)
{
std::cout << "SUCCESS" << std::endl;
}
else
{
std::cout << "FAILED" << std::endl;
}
/* cleanup Lua */
lua_close(state);
I've tried modifying scriptAdding2CppVariables (in the code version using kaguaya) to
"return 1 + 2" and removed the statements to export the variables a and b into the lua
context but I still get the same error. It leaves us with only 3 statements using lua.
Commenting the call to luaFunc() does stop the error from occurring.
If anyone could tell me why I got this behavior I'd be grateful.
Thanks
In genrated code like
template<typename T1>
inline FunEvaluator LuaRef::operator()(T1 t1)
{
value_type typ = type();
if(typ != TYPE_FUNCTION && typ != TYPE_THREAD){except::typeMismatchError(state_, "is not function");return FunEvaluator(state_);}
int argstart = lua_gettop(state_);
lua_type_traits<T1>::push(state_,standard::forward<T1>(t1));
int argnum = lua_gettop(state_) - argstart;
std::vector<LuaRef> args;
args.reserve(argnum);
for (int i = 0; i < argnum; ++i)
args.push_back(LuaRef(state_, StackTop()));
std::reverse(args.begin(), args.end());
return FunEvaluator(state_,*this,args);
}
change last line to return FunEvaluator(state_,*this, std::move(args));
. It prevents vector copying and gives non-negligible perf increase while func calling. May be there are other places where such optimization can be made.
tbProject["BindNetStateChangeMsg"] = kaguya::function([](const std::function<void(int)>& func){
g_NetStateChangeFunc = func;
});
if use this way, it will be error!
Hey,
I'm currently trying to understand "newLib". I want to register a lua script from inside my C++ code for my main lua script I load with dofile. :)
An example would be great :)
Thank you :D
Is it somehow possible, to support default parameters without writing extra functions?
Like:
class Foo{
void func(int param = 42){ std::cout << param; }
};
Currently those functions can be registered, but if the param is notpassed by Lua , it will be 0
instead of 42
e.g.
static const Variant& VariantMapGetVariant(const VariantMap& variantMap, const String& key)
{
VariantMap::ConstIterator i = variantMap.Find(StringHash(key));
if (i == variantMap.End())
return Variant::EMPTY;
return i->second_;
}
static void VariantMapSetVariant(VariantMap& variantMap, const String& key, const Variant& value)
{
variantMap[StringHash(key)] = value;
}
static void RegisterVariantMap(kaguya::State& lua)
{
using namespace kaguya;
lua["KVariantMap"].setClass(UserdataMetatable<VariantMap>()
.setConstructors<VariantMap()>()
// Can not work in kaguya
// .addStaticFunction("__index", &VariantMapGetVariant)
// .addStaticFunction("__newindex", &VariantMapSetVariant)
.addStaticFunction("Get", &VariantMapGetVariant)
.addStaticFunction("Set", &VariantMapSetVariant)
);
}
I'm having trouble to build a solution for MSVC using your CMakeLists.txt.
I'm not used to CMake, is there a way I can specify where to find the Lua includes (and lib if necessary), for example using LuaJIT ? It seems your script assumes that the user has a standard Lua installation.
Sometimes user want to custom __gc function for some userdata, for example:
I have a RefCounted object, when GC, it may call following function.
void RefCountedGC(RefCounted* obj)
{
obj->ref --;
if (obj->ref == 0)
delete obj;
}
So it is better add a argument to UserdataMetatable enable user custom the gc funciton.
UserdataMetatable(bool registerGC= true)
{
if (registerGC)
{
addStaticFunction("__gc", &class_userdata::destructor<ObjectWrapperBase>);
}
I found a crash that can easily occur by a typo in the lua code:
std::map<unsigned, unsigned> myMap;
class FooClass{
public:
void mapCallback(const std::map<unsigned, unsigned>& map)
{
myMap = map;
}
};
void testMap(kaguya::State& state)
{
state["testMap"].setClass(kaguya::ClassMetatable<FooClass>().addMemberFunction("testMap", &FooClass::mapCallback));
state["foo"] = FooClass();
// Wrong -> Crash
state("myMap = {[1]=2, [3]=4, [5]=6}\n foo.testMap(myMap)");
//Correct
state("myMap = {[1]=2, [3]=4, [5]=6}\n foo:testMap(myMap)");
TEST_EQUAL(myMap[1], 2);
TEST_EQUAL(myMap[3], 4);
TEST_EQUAL(myMap[5], 6);
}
The reason is that the .
instead of :
skips the this
pointer and kaguya does not detect the invalid argument count and happily tries to get a map from index 2 at the stack which is not there. Such errors should be detected
I have a loop like this:
struct Foo{ int bar; Foo(int bar):bar(bar){}};
for(int i=0; i<5; i++){
Foo foo = Foo(i);
state["Foo" + std::to_string(i)] = foo;
}
If I then access the state["Foo2"] I get wrong results because kaguya stores a pointer to the local foo
instance.
I traced it a bit (VS) and found, that it goes through the move assignment operator which finally stores a pointer to the value, instead of the value.
Changing the line to state["Foo" + std::to_string(i)] = static_cast<Foo const&>(foo);
fixes this. However the examples suggest, that both should be the same.
Do I misunderstand this or is this a bug?
How to pass a value from one state to another ? Using kaguya::LuaRef doesn't work, is there another way ?
kaguya::State luaP;
kaguya::State luaQ;
luaP("test = \"hello\"");
kaguya::LuaRef retainValue = luaP["test"];
luaQ["test"] = test;
luaQ("print(test)");
Doing it like that works but I want to store a kaguya::LuaRef or something like that
kaguya::State luaP;
kaguya::State luaQ;
luaP("test = \"hello\"");
luaQ["test"] = luaP["test"];
luaQ("print(test)");
lua_type_traits for enum should be like this, I think:
template<typename T> struct lua_type_traits<T
, typename traits::enable_if<traits::is_enum<T>::value>::type>
{
typedef typename traits::remove_const_reference<T>::type get_type;
typedef typename traits::remove_const_reference<T>::type push_type;
static bool strictCheckType(lua_State* l, int index)
{
return lua_type_traits<int>::strictCheckType(l, index);
}
static bool checkType(lua_State* l, int index)
{
return lua_type_traits<int>::checkType(l, index);
}
static get_type get(lua_State* l, int index)
{
return static_cast<get_type>(static_cast<int>(lua_type_traits<int>::get(l, index)));
}
static int push(lua_State* l, push_type s)
{
return lua_type_traits<int>::push(l, static_cast<int>(s));
}
};
As it is possible to call C++ functions from Lua and it is possible that this goes wrong, there should be a method to throw lua errors.
2 cases:
pcall
nil
but if e.g. this is a valid return value too or it is an execution function that you don't want to just 'do nothing' it is better to throw an error, that lua can catch and that will be passed to the error handler otherwise.However I did not find a function for calling lua_error in the wrapper (besides of course executing state("error('Foo bar!!!')")
)
Is there something for this? If not could it be added? What about the io.openFile
like behaviour that it returns the file or nil and an error message? Can this be done easily with kaguya?
Hi, satoren:
When all of the c++ functions and classes register to Lua, is it possible run in dump mode, in this mode, it will output a API documentation. for example:
void TestFunction(int, int);
lua["Test"] = function(TestFunction);
in dump mode, it will output a line:
void Test(int, int);
as documentation.
Hi, Satoren, your kaguya is greater, now the Urho3D Lua API with kaguya is finished. thanks.
These is a class call StringHash
in Urho3D, I have bind it to Lua as a user data. When I call some functions with StringHash arguments, I can do like this:
// C++
void SomeFunction(StringHash hash);
// Lua
SomeFunction(StringHash('This is a string'))
But sometimes I want to call like this:
// Lua
SomeFunction('This is a string')
Now I can not write a lua_type_traits<StringHash>
specialization class, because kaguya forbid it.
struct TestStructSub {
float f_{};
};
struct TestStruct {
TestStructSub s_;
};
...
add class kaguya::ClassMetatable<TestStructSub>()
.addProperty("f_", &TestStructSub::f_);
add class kaguya::ClassMetatable<TestStruct>()
.addProperty("s_", &TestStruct::s_);
...
TestStruct ts;
s["ts"] = &ts;
s("ts.s_.f_ = 1");
ASSERT(ts.s_.f_ == 1); // fails, ts.s_.f_ == 0
Call member function is slow than property.
with sprite:GetPosition, sprite:SetPosition
get fps 54
with sprite.position
get fps 125
Hey I wanted to ask a few questions ...
When I try to call a lua function from my test lua script the application crashes, but the examples works
without any issue, same for getting a variable from my script.
int ret = state["math"]["abs"](-32);
works
but
function getvalue(x)
return x
end
int ret = state["getvalue"](5);
doesn't :(
well ...
state("multresfun =function() return 1,2,4 end");//registering multiple results function
int a, b, c;
kaguya::tie(a, b, c) = state["multresfun"]();
works, but he same called from lua file doesn't :(
So, do I do something wrong or forgot something ?!
My next question is how can I register a function in C++ and call it like
function mycppfunction
bla bla bla
end
That's it so far.
Your lua binding is awesome :) I love it ! :D
Shiny and clean :D 👍
Thanks :)
s["TestBase"].setClass(kaguya::ClassMetatable<TestBase>());
s["TestDer"].setClass(kaguya::ClassMetatable<TestDer, TestBase>());
s["func1"] = kaguya::function([&](std::shared_ptr<TestBase> b) { ... });
s["d"] = std::make_shared<TestDer>();
s("func1(d)");
Shows error argument not matching
.
Has your lib been tested on Linux :) ?
It works perfectly on Windows but I want to pass a string as parameter on Linux is says :
maybe...Argument mismatch:GameObject,string,string,string candidate is: GameObject,std::__cxx11::basic_string<char, std::char_traits<char> std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>n std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>n std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>n std::allocator<char> >,
But basically, a std::__cxx11::basic_string<char, std::char_traits<char> std::allocator<char> >
IS a string.
Is it cause of Lua or Kaguya ?
The compilation (with an older apple-crosscompiler) fails when instantiating int kaguya::nativefunction::FunctorType::FunInvoker<F>::invoke(lua_State*) [with F = Nation (LuaPlayerBase::*)()const]
as this results in instantiation of kaguya::traits::is_object<Nation ()()const>
which ultimately fails with 'const' qualifiers added to function type 'Team ()()const' [...] In instantiation of 'kaguya::traits::remove_const<Nation ()()const>'
I tried to change the traits to:
using standard::remove_const;
using standard::remove_volatile;
using standard::remove_cv;
using standard::is_pointer;
But that fails too: pointer to function type 'int () const' cannot have 'const' qualifier
for is_pointer
from kaguya::traits::is_object<int () const>
from 'call' [with MemType = int () const, T = kaguya_test_util::TestClass]
You probably can replace all this by is_member_object_pointer
http://www.boost.org/doc/libs/1_58_0/libs/type_traits/doc/html/boost_typetraits/reference/is_member_object_pointer.html
how can i return a table?
i do not want to create map in c/c++(it use frequency)
now code:(how to change to kaguya)
int nRows = dataTable.NumOfRows();
int nField = dataTable.NumOfFields();
lua_newtable(tolua_S);
int array_index = lua_gettop(tolua_S);
for (int i = 0; i < nRows; i++)
{
lua_newtable(tolua_S);
int result_index = lua_gettop(tolua_S);
for (int j = 0; j < nField; j++)
{
dataTable.SetRow(i);
lua_pushstring(tolua_S, dataTable.NameOfField(j));
lua_pushstring(tolua_S, dataTable.ValueOfField(j));
lua_settable(tolua_S, result_index);
}
lua_settop(tolua_S, result_index);
lua_rawseti(tolua_S, array_index, i + 1);
}
Like
s["to"] = kaguya::function([&](MyStruct & p) { });
'initializing': cannot convert from 'const 'anonymous-namespace'::MyStruct ' to ''anonymous-namespace'::MyStruct &' Tests C:\cpplibs\lua\inst\include\kaguya\gen\native_function.inl 478
Current these is only a function to set metatable for class.
class_userdata::setmetatable<ClassType>(lua_state* state);
Is it possible add another function so can set metatable by class name?
class_userdata::setmetatable(lua_state* state, const char* class_name);
shared code is push string to lua.
why we can not do like pushlightuserdata? sign the unuse address.
code is more simple and quick.
is other reason?
struct NcTest {
NcTest(NcTest const &) = delete;
auto foo() -> NcTest & { return *this; }
};
auto const ncTestMt = kaguya::UserdataMetatable<NcTest>().addFunction("foo", &NcTest::foo);
Error C2280 'anonymous-namespace'::NcTest::NcTest(const anonymous-namespace'::NcTest &)': attempting to reference a deleted function
In visual studio 2015 upd 3
I'm getting the following compiler error when trying to use the header-only lib:
kaguya/detail/lua_table_def.hpp: In member function 'typename kaguya::lua_type_traits<T>::get_type kaguya::LuaTableOrUserDataImpl<Derived>::getField(const KEY&) const':
kaguya/detail/lua_table_def.hpp:111:39: error: 'index' was not declared in this scope
lua_type_traits<KEY>::push_(state, index);
^
And indeed when I look at the reported line, there is a variable index
of which I can't find a declaration or definition. Should this be key
instead?
I have code like this:
std::vector<unsigned> GetValues()
{
kaguya::LuaRef getValues= lua["getValues"];
if(getValues.type() == LUA_TFUNCTION)
return getValues();
return std::vector<unsigned>();
}
And I want this code to throw an error or something so I can detect when the lua function returns invalid types. E.g. in this case the lua function returned a table of strings instead of numbers.
Problem is: I just get the empty vector and have no way to tell if the vector was actually empty or just had some wrong elements.
Visua Studio 2015, Update 3, latest Kaguya
struct func_obj {
int x;
int operator()( int i ) { x = i; return i; }
};
int main (int argc, char*[] argv ) {
kaguya::State state;
// Fails Line 408, native_function.hpp
// is_callable KAGUYA_STATIC_ASSERT assertion
//state["f"] = kaguya::function( func_obj() );
// works fine
state["f"] = kaguya::function( [](int i){ func_obj o; return o(i); } );
// also fine
func_obj fo;
state["f"] = kaguya::function( [&](int i){ return fo(i); } );
}
Is something wrong with is_callable trait?
Thanks for the great Lua binding !!
But I meet a problem:
class prototype
class Node : public Ref
{
public:
void scheduleOnce(const std::function<void(float)>& callback, float delay, const std::string &key);
}
register code:
cc["Node"].setClass(kaguya::ClassMetatable<Node, Ref>()
.addMemberFunction("scheduleOnce", static_cast<void(Node::*)(const std::function<void(float)>& callback, float delay, const std::string &key)>(&Node::scheduleOnce))
);
Lua test code:
node:scheduleOnce(function(dt) print ("scheduleOnce") end, 1.0, "test")
error:
__luadraw__ error: maybe...Argument mismatch:PN7cocos2d6SpriteE,function,number,string candidate is:
PN7cocos2d4NodeE,NSt3__18functionIFvfEEE,f,NSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE,
Am I missing something?
a.so export class A
lua require b.so have interface param 1 is A
how to get a point if use kaguya::get_pointer(L, nIndex, kaguya::types::typetag());
the metatable_name_key is not same so it will fail
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.