This will register a C++ class with Lua, and then call a Lua function
passing C++ objects to this function.
*/
#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
# define _CRT_SECURE_NO_DEPRECATE
#endif
#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE)
# define _SCL_SECURE_NO_DEPRECATE
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
#if LUA_VERSION_NUM > 501
#define lua_open luaL_newstate
#endif
swig -lua -externalruntime swigluarun.h
It contains useful function used by SWIG in its wrapper
SWIG_TypeQuery() SWIG_NewPointerObj()
*/
#include "swigluarun.h"
extern "C" int luaopen_example(lua_State*L);
#include "example.h"
bool push_pointer(lua_State*L, void* ptr, const char* type_name, int owned = 0) {
swig_type_info * pTypeInfo = SWIG_TypeQuery(L, type_name);
if (pTypeInfo == 0)
return false;
SWIG_NewPointerObj(L, ptr, pTypeInfo, owned);
return true;
}
void onEvent(Event e)
it's very tedious, but gives you an idea of the issues involved.
*/
int call_onEvent(lua_State *L, Event e) {
int top;
push a, push b, call 'add' check & return res
*/
top = lua_gettop(L);
lua_getglobal(L, "onEvent");
if (!lua_isfunction(L, -1)) {
printf("[C++] error: cannot find function 'OnEvent'\n");
lua_settop(L, top);
return 0;
}
push_pointer(L, &e, "Event *", 0);
if (lua_pcall(L, 1, 0, 0) != 0)
{
printf("[C++] error running function `OnEvent': %s\n", lua_tostring(L, -1));
lua_settop(L, top);
return 0;
}
lua_settop(L, top);
return 1;
}
int main(int argc, char* argv[]) {
printf("[C++] Welcome to the simple embedded Lua example v3\n");
printf("[C++] We are in C++\n");
printf("[C++] opening a Lua state & loading the libraries\n");
lua_State *L = lua_open();
luaopen_base(L);
luaopen_string(L);
luaopen_math(L);
printf("[C++] now loading the SWIG wrappered library\n");
luaopen_example(L);
printf("[C++] all looks ok\n");
printf("\n");
printf("[C++] let's create an Engine and pass a pointer to Lua\n");
Engine engine;
this is a little tedious, to do, but let's do it
we need to pass the pointer (obviously), the type name
and a flag which states if Lua should delete the pointer once it's finished with it
The type name is a class name string which is registered with SWIG
(normally, just look in the wrapper file to get this)
in this case we don't want Lua to delete the pointer so the ownership flag is 0
*/
push_pointer(L,&engine,"Engine *",0);
lua_setglobal(L, "pEngine");
if (argc != 2 || argv[1] == NULL || strlen(argv[1]) == 0) {
printf("[C++] ERROR: no lua file given on command line\n");
exit(3);
}
printf("[C++] now let's load the file '%s'\n", argv[1]);
printf("[C++] any lua code in this file will be executed\n");
if (luaL_loadfile(L, argv[1]) || lua_pcall(L, 0, 0, 0)) {
printf("[C++] ERROR: cannot run lua file: %s",lua_tostring(L, -1));
exit(3);
}
printf("[C++] We are now back in C++, all looks ok\n");
printf("\n");
printf("[C++] Let's call the Lua function onEvent(e)\n");
printf("[C++] We will give it different events, as we wish\n");
printf("[C++] Starting with STARTUP\n");
Event ev;
ev.mType = Event::STARTUP;
call_onEvent(L, ev);
printf("[C++] ok\n");
printf("[C++] now we will try MOUSEPRESS,KEYPRESS,MOUSEPRESS\n");
ev.mType = Event::MOUSEPRESS;
call_onEvent(L, ev);
ev.mType = Event::KEYPRESS;
call_onEvent(L, ev);
ev.mType = Event::MOUSEPRESS;
call_onEvent(L, ev);
printf("[C++] ok\n");
printf("[C++] Finally we will SHUTDOWN\n");
ev.mType = Event::SHUTDOWN;
call_onEvent(L, ev);
printf("[C++] ok\n");
printf("\n");
printf("[C++] all finished, closing the lua state\n");
lua_close(L);
return 0;
}