summaryrefslogtreecommitdiff
path: root/Examples/lua/embed3
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2009-08-18 20:56:02 +0000
committerLorry <lorry@roadtrain.codethink.co.uk>2012-09-25 16:59:08 +0000
commit9f8a09ed743cedd9547bf0661d518647966ab114 (patch)
tree9c7803d3b27a8ec22e91792ac7f7932efa128b20 /Examples/lua/embed3
downloadswig-tarball-master.tar.gz
Imported from /srv/lorry/lorry-area/swig-tarball/swig-1.3.40.tar.gz.HEADswig-1.3.40master
Diffstat (limited to 'Examples/lua/embed3')
-rw-r--r--Examples/lua/embed3/Makefile20
-rw-r--r--Examples/lua/embed3/embed3.cpp146
-rw-r--r--Examples/lua/embed3/example.cpp25
-rw-r--r--Examples/lua/embed3/example.h24
-rw-r--r--Examples/lua/embed3/example.i8
-rw-r--r--Examples/lua/embed3/runme.lua35
6 files changed, 258 insertions, 0 deletions
diff --git a/Examples/lua/embed3/Makefile b/Examples/lua/embed3/Makefile
new file mode 100644
index 0000000..def3528
--- /dev/null
+++ b/Examples/lua/embed3/Makefile
@@ -0,0 +1,20 @@
+TOP = ../..
+SWIG = $(TOP)/../preinst-swig
+TARGET = embed3
+SRCS = example.cpp
+INTERFACE = example.i
+LUA_INTERP = embed3.cpp
+
+# this is a little different to normal as we have our own special interpreter
+# which we want to static link
+# we also need the external runtime, so we can get access to certain internals of SWIG
+all::
+ $(SWIG) -c++ -lua $(SWIGOPT) -external-runtime swigluarun.h
+ $(MAKE) -f $(TOP)/Makefile $(SWIGLIB) SRCS='$(SRCS)' SWIG='$(SWIG)' \
+ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='example.i' LUA_INTERP='$(LUA_INTERP)' lua_static_cpp
+
+clean::
+ $(MAKE) -f $(TOP)/Makefile lua_clean
+
+check: all
+
diff --git a/Examples/lua/embed3/embed3.cpp b/Examples/lua/embed3/embed3.cpp
new file mode 100644
index 0000000..e5e0e0a
--- /dev/null
+++ b/Examples/lua/embed3/embed3.cpp
@@ -0,0 +1,146 @@
+/* embed3.cpp A C++ embeded interpreter
+
+This will register a C++ class with Lua, and then call a Lua function
+passing C++ objects to this function.
+
+*/
+
+/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
+#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
+# define _CRT_SECURE_NO_DEPRECATE
+#endif
+
+/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */
+#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>
+}
+
+/* The SWIG external runtime is generated by using.
+swig -lua -externalruntime swigluarun.h
+It contains useful function used by SWIG in its wrappering
+SWIG_TypeQuery() SWIG_NewPointerObj()
+*/
+#include "swigluarun.h" // the SWIG external runtime
+
+/* the SWIG wrappered library */
+extern "C" int luaopen_example(lua_State*L);
+
+// the code itself
+#include "example.h"
+
+// this code pushes a C++ pointer as well as the SWIG type onto the Lua stack
+bool push_pointer(lua_State*L, void* ptr, const char* type_name, int owned = 0) {
+ // task 1: get the object 'type' which is registered with SWIG
+ // you need to call SWIG_TypeQuery() with the class name
+ // (normally, just look in the wrapper file to get this)
+ swig_type_info * pTypeInfo = SWIG_TypeQuery(L, type_name);
+ if (pTypeInfo == 0)
+ return false; // error
+ // task 2: push the pointer to the Lua stack
+ // this requires a pointer & the type
+ // the last param specifies if Lua is responsible for deleting the object
+ SWIG_NewPointerObj(L, ptr, pTypeInfo, owned);
+ return true;
+}
+
+/* This is an example of how to call the Lua function
+ void onEvent(Event e)
+ its very tedious, but gives you an idea of the issues involed.
+*/
+int call_onEvent(lua_State *L, Event e) {
+ int top;
+ /* ok, here we go:
+ push a, push b, call 'add' check & return res
+ */
+ top = lua_gettop(L); /* for later */
+ lua_pushstring(L, "onEvent"); /* function name */
+ lua_gettable(L, LUA_GLOBALSINDEX); /* function to be called */
+ if (!lua_isfunction(L, -1)) {
+ printf("[C++] error: cannot find function 'OnEvent'\n");
+ lua_settop(L, top); // reset
+ return 0;
+ }
+ // push the event object
+ push_pointer(L, &e, "Event *", 0);
+ if (lua_pcall(L, 1, 0, 0) != 0) /* call function with 1 arguments and no result */
+ {
+ printf("[C++] error running function `OnEvent': %s\n", lua_tostring(L, -1));
+ lua_settop(L, top); // reset
+ return 0;
+ }
+ lua_settop(L, top); /* reset stack */
+ return 1; // ok
+}
+
+
+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++] lets create an Engine and pass a pointer to Lua\n");
+ Engine engine;
+ /* this code will pass a pointer into lua, but C++ still owns the object
+ this is a little tedious, to do, but lets do it
+ we need to pass the pointer (obviously), the type name
+ and a flag which states if Lua should delete the pointer once its 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"); // set as global variable
+
+ printf("[C++] now lets load the file 'runme.lua'\n");
+ printf("[C++] any lua code in this file will be executed\n");
+ if (luaL_loadfile(L, "runme.lua") || 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++] Lets 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;
+}
diff --git a/Examples/lua/embed3/example.cpp b/Examples/lua/embed3/example.cpp
new file mode 100644
index 0000000..a8264f3
--- /dev/null
+++ b/Examples/lua/embed3/example.cpp
@@ -0,0 +1,25 @@
+/* File : example.cpp */
+
+#include <stdio.h>
+#include "example.h"
+
+void Engine::start()
+{
+ printf("[C++] Engine::start()\n");
+}
+
+void Engine::stop()
+{
+ printf("[C++] Engine::stop()\n");
+}
+
+void Engine::accelerate(float f)
+{
+ printf("[C++] Engine::accelerate(%f)\n",f);
+}
+
+void Engine::decelerate(float f)
+{
+ printf("[C++] Engine::decelerate(%f)\n",f);
+}
+
diff --git a/Examples/lua/embed3/example.h b/Examples/lua/embed3/example.h
new file mode 100644
index 0000000..41c13e9
--- /dev/null
+++ b/Examples/lua/embed3/example.h
@@ -0,0 +1,24 @@
+/* File : example.h */
+
+/* This is some kind of engine of some kind
+we will give it some dummy methods for Lua to call*/
+
+class Engine
+{
+public:
+ void start();
+ void stop();
+ void accelerate(float f);
+ void decelerate(float f);
+};
+
+
+/* We also want to pass some events to Lua, so lets have a few classes
+to do this.
+*/
+class Event
+{
+public:
+ enum {STARTUP,KEYPRESS,MOUSEPRESS,SHUTDOWN} mType;
+ // etc
+};
diff --git a/Examples/lua/embed3/example.i b/Examples/lua/embed3/example.i
new file mode 100644
index 0000000..032805c
--- /dev/null
+++ b/Examples/lua/embed3/example.i
@@ -0,0 +1,8 @@
+/* File : example.i */
+%module example
+
+%{
+#include "example.h"
+%}
+
+%include "example.h"
diff --git a/Examples/lua/embed3/runme.lua b/Examples/lua/embed3/runme.lua
new file mode 100644
index 0000000..3a44bd2
--- /dev/null
+++ b/Examples/lua/embed3/runme.lua
@@ -0,0 +1,35 @@
+print "[lua] This is runme.lua"
+-- test program for embeded lua
+-- we do not need to load the library, as it was already in the intrepreter
+-- but lets check anyway
+
+assert(type(example)=='table',"Don't appear to have loaded the example module. Do not run this file directly, run the embed3 executable")
+
+print "[lua] looking to see if we have a pointer to the engine"
+if type(pEngine)=="userdata" then
+ print "[lua] looks good"
+else
+ print "[lua] nope, no signs of it"
+end
+
+
+-- the embed program expects a function void onEvent(Event)
+-- this is it
+
+function onEvent(e)
+ print("[Lua] onEvent with event",e.mType)
+ -- lets do something with the Engine
+ -- nothing clever, but ...
+ if e.mType==example.Event_STARTUP then
+ pEngine:start()
+ elseif e.mType==example.Event_KEYPRESS then
+ pEngine:accelerate(0.4)
+ elseif e.mType==example.Event_MOUSEPRESS then
+ pEngine:decelerate(0.4)
+ elseif e.mType==example.Event_SHUTDOWN then
+ pEngine:stop()
+ else
+ error("unknown event type")
+ end
+ print("[Lua] ending onEvent")
+end \ No newline at end of file