Skip to main content
added 377 characters in body
Source Link
Alex Ames
  • 392
  • 2
  • 9

I'm fairly sure Lua can do everything you need relatively simply. I use Lua and C++ in my game. I looked at various wrappers like LuaBind, or using a generator like Swig, but I decided I didn't want any of that stuff and I wrote my own wrapper which I ended up making open source in case other people found it useful.

Using my little library you can do stuff like this in C++:

// Wrap a C++ function
static int Widget_AddChild(lua_State* L)
{
    // Typesafe way to extract userdata from Lua
    Widget* parent = luaW_check<Widget>(L, 1);
    Widget* child = luaW_check<Widget>(L, 2);
    lua_pushboolean(L, parent->AddChild(child));
}

static luaL_reg Widget_Metatable[] =
{
    // Register the function you wrote above
    { "AddChild", Widget_AddChild },
    
    // Widgets also have some getter and setter functions, 
    // Using these templates you can automatically generate 
    // wrapper functions for them
    { "GetStyle", luaU_get<Widget, Style, &Widget::GetStyle> },
    { "SetStyle", luaU_set<Widget, Style, &Widget::SetStyle> },
    { "Style", luaU_getset<Widget, Style, &Widget::GetStyle, &Widget::SetStyle> },

    { NULL, NULL }
};

int luaopen_Widget(lua_State* L)
{
    luaW_register<Widget>(L, "Widget", NULL, Widget_Metatable);
    return 1;
}

In lua you could now do something like this:

local w = Widget.new()
w.foo = 10 -- Foo is stored on w, it's not accessible to other instances
-- You can also add values accessible to all Widgets
function Widget.metatable:newfunction() 
    print(self:GetWidth()) 
end
w:newfunction()

With all that, you can fairly easily call C++ function from Lua (and vice versa, but I didn't illustrate that here). Once you know how to interact with the Lua API, writing a function to 'safely' call (i.e. call a function only if it exists) a Lua function should be easy as well.

Edit:

If you want to check for the existence of a function before calling it, like I said, just check that the value is a function before calling it.

lua_getglobal(L, "myFunc"); // You can get your function from anywhere, this is just for example
if (lua_isfunction(L, -1)) // Check the top of the stack, make sure it's a function
{
    lua_call(L, 0, 0);
}

I'm fairly sure Lua can do everything you need relatively simply. I use Lua and C++ in my game. I looked at various wrappers like LuaBind, or using a generator like Swig, but I decided I didn't want any of that stuff and I wrote my own wrapper which I ended up making open source in case other people found it useful.

Using my little library you can do stuff like this in C++:

// Wrap a C++ function
static int Widget_AddChild(lua_State* L)
{
    // Typesafe way to extract userdata from Lua
    Widget* parent = luaW_check<Widget>(L, 1);
    Widget* child = luaW_check<Widget>(L, 2);
    lua_pushboolean(L, parent->AddChild(child));
}

static luaL_reg Widget_Metatable[] =
{
    // Register the function you wrote above
    { "AddChild", Widget_AddChild },
    
    // Widgets also have some getter and setter functions, 
    // Using these templates you can automatically generate 
    // wrapper functions for them
    { "GetStyle", luaU_get<Widget, Style, &Widget::GetStyle> },
    { "SetStyle", luaU_set<Widget, Style, &Widget::SetStyle> },
    { "Style", luaU_getset<Widget, Style, &Widget::GetStyle, &Widget::SetStyle> },

    { NULL, NULL }
};

int luaopen_Widget(lua_State* L)
{
    luaW_register<Widget>(L, "Widget", NULL, Widget_Metatable);
    return 1;
}

In lua you could now do something like this:

local w = Widget.new()
w.foo = 10 -- Foo is stored on w, it's not accessible to other instances
-- You can also add values accessible to all Widgets
function Widget.metatable:newfunction() 
    print(self:GetWidth()) 
end
w:newfunction()

With all that, you can fairly easily call C++ function from Lua (and vice versa, but I didn't illustrate that here). Once you know how to interact with the Lua API, writing a function to 'safely' call (i.e. call a function only if it exists) a Lua function should be easy as well.

I'm fairly sure Lua can do everything you need relatively simply. I use Lua and C++ in my game. I looked at various wrappers like LuaBind, or using a generator like Swig, but I decided I didn't want any of that stuff and I wrote my own wrapper which I ended up making open source in case other people found it useful.

Using my little library you can do stuff like this in C++:

// Wrap a C++ function
static int Widget_AddChild(lua_State* L)
{
    // Typesafe way to extract userdata from Lua
    Widget* parent = luaW_check<Widget>(L, 1);
    Widget* child = luaW_check<Widget>(L, 2);
    lua_pushboolean(L, parent->AddChild(child));
}

static luaL_reg Widget_Metatable[] =
{
    // Register the function you wrote above
    { "AddChild", Widget_AddChild },
    
    // Widgets also have some getter and setter functions, 
    // Using these templates you can automatically generate 
    // wrapper functions for them
    { "GetStyle", luaU_get<Widget, Style, &Widget::GetStyle> },
    { "SetStyle", luaU_set<Widget, Style, &Widget::SetStyle> },
    { "Style", luaU_getset<Widget, Style, &Widget::GetStyle, &Widget::SetStyle> },

    { NULL, NULL }
};

int luaopen_Widget(lua_State* L)
{
    luaW_register<Widget>(L, "Widget", NULL, Widget_Metatable);
    return 1;
}

In lua you could now do something like this:

local w = Widget.new()
w.foo = 10 -- Foo is stored on w, it's not accessible to other instances
-- You can also add values accessible to all Widgets
function Widget.metatable:newfunction() 
    print(self:GetWidth()) 
end
w:newfunction()

With all that, you can fairly easily call C++ function from Lua (and vice versa, but I didn't illustrate that here). Once you know how to interact with the Lua API, writing a function to 'safely' call (i.e. call a function only if it exists) a Lua function should be easy as well.

Edit:

If you want to check for the existence of a function before calling it, like I said, just check that the value is a function before calling it.

lua_getglobal(L, "myFunc"); // You can get your function from anywhere, this is just for example
if (lua_isfunction(L, -1)) // Check the top of the stack, make sure it's a function
{
    lua_call(L, 0, 0);
}
Source Link
Alex Ames
  • 392
  • 2
  • 9

I'm fairly sure Lua can do everything you need relatively simply. I use Lua and C++ in my game. I looked at various wrappers like LuaBind, or using a generator like Swig, but I decided I didn't want any of that stuff and I wrote my own wrapper which I ended up making open source in case other people found it useful.

Using my little library you can do stuff like this in C++:

// Wrap a C++ function
static int Widget_AddChild(lua_State* L)
{
    // Typesafe way to extract userdata from Lua
    Widget* parent = luaW_check<Widget>(L, 1);
    Widget* child = luaW_check<Widget>(L, 2);
    lua_pushboolean(L, parent->AddChild(child));
}

static luaL_reg Widget_Metatable[] =
{
    // Register the function you wrote above
    { "AddChild", Widget_AddChild },
    
    // Widgets also have some getter and setter functions, 
    // Using these templates you can automatically generate 
    // wrapper functions for them
    { "GetStyle", luaU_get<Widget, Style, &Widget::GetStyle> },
    { "SetStyle", luaU_set<Widget, Style, &Widget::SetStyle> },
    { "Style", luaU_getset<Widget, Style, &Widget::GetStyle, &Widget::SetStyle> },

    { NULL, NULL }
};

int luaopen_Widget(lua_State* L)
{
    luaW_register<Widget>(L, "Widget", NULL, Widget_Metatable);
    return 1;
}

In lua you could now do something like this:

local w = Widget.new()
w.foo = 10 -- Foo is stored on w, it's not accessible to other instances
-- You can also add values accessible to all Widgets
function Widget.metatable:newfunction() 
    print(self:GetWidth()) 
end
w:newfunction()

With all that, you can fairly easily call C++ function from Lua (and vice versa, but I didn't illustrate that here). Once you know how to interact with the Lua API, writing a function to 'safely' call (i.e. call a function only if it exists) a Lua function should be easy as well.