Skip to content

Latest commit

 

History

History
212 lines (178 loc) · 5.05 KB

ENGLISH-README.md

File metadata and controls

212 lines (178 loc) · 5.05 KB

#nua

Simple C++11 friendly header-only bindings to Lua

A component of PM-Game-Server.
Reference to Selene and fix some features to meet the PM-Game-Server's requirements


##Requirements

  • cmake 2.8+(This is not must if you don't want to compile tests)
  • lua 5.2+
  • a compiler which support c++14(recommend gcc)

##Features and Usage
###Establishing lua context

nua::Context ctx;

If you don't need standard Lua libraries:

nua::Context ctx{false};

When a nua::Context destruct, the lua context is automatically destroyed in addition to all objects associated with it(including C++ objects).

###Loading lua script from file

ctx.load("path/to/your.lua");

###Executing lua code in c++ code

ctx(R"(print("hello, world"))");

###Registering c++ function to lua

ctx["foo"] = []{ std::cout << "hello, nua" << std::endl; };     /**< lambda */
ctx["bar"] = std::function<...>(...);                           /**< stl function */
ctx["barz"] = std::bind(...);                                    
struct T
{
    type operator()(...)
    {
        ...
    }
} callable;

ctx["func"] = callable;                                         /**< callable object */

Then you can call these functions in lua.
###Calling lua function in c++

ctx["foo"]();                                                   /**< no return, no parameter */
ctx["bar"](1, 2, "hello").get<int>();                           /**< get return value with type of int */
int x;
std::string y;
std::tie(x, y) = ctx["barz"](1, 2, 3).get<int, std::string>();  /**< get more than one return value */

###Registering Classes

struct T
{
    int v;
    int func(int y);
};
ctx.setClass<T>("v", &T::v, "func", &T::func);

Then you can use this class in lua:

function bar(t)
    print(t:v())            --get T::v
    t:set_v(123)            --set T::v
    t:func(123)             --call T::func
end

You should not that t should be passed to lua by C++:

T t;
ctx["bar"](t);

###Passing reference Rigistered class can be passed to lua by reference

struct T
{
    T(const T&) = delete;
} t;

ctx.setClass<T>();

ctx["foo"](std::ref(t));
ctx["bar"](std::cref(t));       /**< when you pass const reference, the set_xxx functions will be omited as well as non-const member function */

###Returning reference from c++

ctx["foo"] = [&]() -> const T& { return t; };

###Accepting Lua functions as Arguments

-- test.lua

function add(a, b)
    return a + b 
end

function pass_add(x, y)
    return take_fun_arg(add, x, y)
end
nua::Context ctx;
ctx["take_fun_arg"] = [](nua::function<int(int, int)> func, int a, int b)
{
    return func(a, b); 
};

ctx.load("test.lua");
assert(ctx["pass_add"](3, 5) == 8);

###Making use of c++ polymorphic functions

nua::Context ctx;

struct B
{
    virtual void apply() const
    {
        std::cout << "apply B" << std::endl;
    }
};

struct T : B
{
    void apply() const override
    {
        std::cout << "apply T" << std::endl;
    }
};

ctx.setClass<B>("apply", &B::apply);

T t;
B& rt = t;

ctx(R"(
    function apply(b)
        b:apply()
    end
)");
ctx["apply"](std::cref(rt));

##Note You can not

  • pass reference of primitive type to nua
  • return reference of primitive type in the function you registered to nua
  • use non-const reference of primitive type as args in the function you registered to nua
  • return reference of primitive type from lua to c++

The primitive types include:

  • all number type in c++(bool, char, unsigned char, int, etc).
  • std::string
  • std::nullptr_t
  • nua::function
ctx(R"(
    function foo(x)
    end 
)");
int x = 0;
ctx["foo"](x);             /**< ok */  
ctx["foo"](std::ref(x));   /**< runtime error, x is of primitive type */  
ctx["foo"](std::cref(x));  /**< runtime error, x is of primitive type */  

Note that std::string is also of primitive type:

ctx["foo"] = [](const std::string& s) {...};        /**< ok, receive const reference of primitive type */  
ctx["foo"] = []() -> const std::string& {...};      /**< runtime error, return reference of primitive type */  

An object can be return from lua to c++ as reference, only if it was passed to lua as reference before, and the const-qualifiers must be correct.

struct T
{
};

ctx.setClass<T>();
ctx(R"(
    function forward_ref(x)
        return x
    end
)");

T t;
ctx["forward_ref"](t).get<const T&>();                  /**< runtime error, expect a reference of a non-reference object */
ctx["forward_ref"](t).get<T&>();                        /**< runtime error, expect a reference of a non-reference object */
ctx["forward_ref"](std::ref(t)).get<const T&>();        /**< ok, non-const reference can be translate to its' const version */
ctx["forward_ref"](std::cref(t)).get<const T&>();       /**< ok */
ctx["forward_ref"](std::cref(t)).get<T&>();             /**< runtime error, const reference can't be translate to non-const one */