Giter Site home page Giter Site logo

kaguya's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kaguya's Issues

Throw error on invalid return values

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.

Support default parameters

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

registering function not working

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)

Wrong object lifetime in move operators

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 does newLib work ?

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

Build error on macOS Sierra

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>>();

Is there a way to use optional args with overloads ?

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 ?

Global function as member function.

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.

Detect a runtime error in a UserdataMetatable function call

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?

Performance while function call

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.

how to return a table?

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);
}

UserdataMetatable enable custom gc function.

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>);
    }

function object cannot bind right?

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?

Kaguya in dump api mode? is it possible?

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.

Is it possible setmetatable by class name?

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);

Is it possible add __call meta method?

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?

Support for Template Constructor / Members / Functions

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 ?

CMake usage

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.

'index' was not declared in this scope

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?

Access subtables directly

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);

?

Cannot init UserdataMetatable when class is noncopyable

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

Crash when incorrectly calling member function

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

Enum classes are broken

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));
        }
    };

Wrapper for Lua error throwing

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:

  1. Lua calls a function, but the argument is of the wrong type. I assume (correct me here) this wrapper will directly call the error handler here. So there is no way to catch this with Luas pcall
  2. The argument passed to the function is wrong (after the wrapper calls the C++ function) e.g. an index is out of bounds. For getters it might be reasonable to return 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?

Compile failure for const-member functions

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

Error adding metatable to member std::vector

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));
}

Template specialisation using return-type

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>();

Fail to execute simple Lua code with kaguya

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

A few questions about functions

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 :)

Passing classes by ref to function is broken

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

Write acess to substruct property

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

Kaguya on Linux ?

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 ?

how to bind the function from lua?

tbProject["BindNetStateChangeMsg"] = kaguya::function([](const std::function<void(int)>& func){
	g_NetStateChangeFunc = func;
});

if use this way, it will be error!

Passing a LuaRef from a kaguya::State to another kaguya::State

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)");

Error while passing base class smart pointer to function

    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.

How to handle Lua function in c++

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?

Nil support for smart pointers

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?

how to use in multi so or dll

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

New feature request.

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.

__index and __newindex can not work in kaguya.

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)
        );
}

Document lua_type_traits

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?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.