summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Noble <pixel@nobis-crew.org>2013-07-30 19:10:20 -0700
committerNicolas Noble <pixel@nobis-crew.org>2013-07-30 19:30:09 -0700
commite7db8576b8a4988dfdd206500199e59c3b57bf55 (patch)
treede40c83fd7eef3d0c443a7e0d9d670b8b6aace64
parentbabb39375916dc114d3413aa52c9a2c543cad2af (diff)
Changing things a bit in the Lua binding system. Now pushing a class template means pushing a table by its name, and the constructor is implicit in it.
-rw-r--r--includes/BLua.h37
-rw-r--r--src/BLua.cc2
-rw-r--r--tests/test-Lua.cc29
3 files changed, 61 insertions, 7 deletions
diff --git a/includes/BLua.h b/includes/BLua.h
index e11c3fb..a6dd2bc 100644
--- a/includes/BLua.h
+++ b/includes/BLua.h
@@ -223,6 +223,16 @@ struct lua_functypes_t {
true); \
}
+#define DECLARE_CONSTRUCTOR(classname, enumvar) static int constructor(lua_State * L) { \
+ return LuaHelpers<classname>::method_multiplex( \
+ enumvar, \
+ L, \
+ NULL, \
+ sLua_##classname::classname##_proceed_statics, \
+ classname##_functions, \
+ false); \
+ }
+
#define DECLARE_FUNCTION(classname, enumvar) static int function_##enumvar(lua_State * L) { \
return LuaHelpers<classname>::method_multiplex( \
enumvar, \
@@ -233,6 +243,16 @@ struct lua_functypes_t {
false); \
}
+#define DECLARE_STATIC(classname, enumvar) static int static_##enumvar(lua_State * L) { \
+ return LuaHelpers<classname>::method_multiplex( \
+ enumvar, \
+ L, \
+ NULL, \
+ sLua_##classname::classname##_proceed_statics, \
+ classname##_functions, \
+ false); \
+ }
+
#define PUSH_METHOD(classname, enumvar) pushIt( \
L, \
classname##_methods[enumvar].name, \
@@ -243,6 +263,21 @@ struct lua_functypes_t {
String("__") + classname##_methods[enumvar].name, \
sLua_##classname::method_##enumvar)
+#define PUSH_CONSTRUCTOR(classname, enumvar) \
+ bool constructorPushed = true; \
+ L.newtable(); \
+ L.push(#classname); \
+ L.copy(-2); \
+ L.setvar(); \
+ L.declareFunc("new", sLua_##classname::constructor, -1)
+
+#define PUSH_STATIC(classname, enumvar) \
+ AAssert(constructorPushed, "Please call PUSH_CONSTRUCTOR first"); \
+ L.declareFunc( \
+ classname##_functions[enumvar].name, \
+ sLua_##classname::static_##enumvar, \
+ -1)
+
#define PUSH_FUNCTION(classname, enumvar) L.declareFunc( \
classname##_functions[enumvar].name, \
sLua_##classname::function_##enumvar)
@@ -252,6 +287,8 @@ struct lua_functypes_t {
sLua_##classname::function_##enumvar, \
array)
+#define PUSH_CLASS_DONE() L.pop()
+
#define CHECK_METHODS(classname) { \
int i = 0; \
while (classname##_methods[i].number != -1) { \
diff --git a/src/BLua.cc b/src/BLua.cc
index 62e4010..cb0e645 100644
--- a/src/BLua.cc
+++ b/src/BLua.cc
@@ -382,6 +382,8 @@ void Balau::Lua::declareFunc(const char * name, lua_CFunction f, int i) {
checkstack(2);
lua_pushstring(L, name);
lua_pushcfunction(L, f);
+ if ((i < 0) && (i > LUA_REGISTRYINDEX))
+ i += 2;
lua_settable(L, i);
}
diff --git a/tests/test-Lua.cc b/tests/test-Lua.cc
index 724369f..1925033 100644
--- a/tests/test-Lua.cc
+++ b/tests/test-Lua.cc
@@ -15,6 +15,7 @@ class ObjectTest {
void someMethod1() { Printer::log(M_DEBUG, "ObjectTest::someMethod1() called on %p.", this); callCount++; }
int someMethod2(int p) { Printer::log(M_DEBUG, "ObjectTest::someMethod2() called on %p.", this); callCount++; return p * 2; }
static void someFunction() { Printer::log(M_DEBUG, "ObjectTest::someFunction() called."); callCount++; }
+ static void someStatic() { Printer::log(M_DEBUG, "ObjectTest::someStatic() called."); callCount++; }
};
enum ObjectTest_methods_t {
@@ -23,8 +24,9 @@ enum ObjectTest_methods_t {
};
enum ObjectTest_functions_t {
- OBJECTTEST_CREATEOBJECTTEST,
+ OBJECTTEST_CONSTRUCTOR,
OBJECTTEST_SOMEFUNCTION,
+ OBJECTTEST_SOMESTATIC,
OBJECTTEST_YIELDTEST,
};
@@ -35,8 +37,9 @@ struct lua_functypes_t ObjectTest_methods[] = {
};
struct lua_functypes_t ObjectTest_functions[] = {
- { OBJECTTEST_CREATEOBJECTTEST, "createObjectTest", 0, 0, { } },
+ { OBJECTTEST_CONSTRUCTOR, NULL, 0, 0, { } },
{ OBJECTTEST_SOMEFUNCTION, "ObjectTestFunction", 0, 0, { } },
+ { OBJECTTEST_SOMESTATIC, "SomeStatic", 0, 0, { } },
{ OBJECTTEST_YIELDTEST, "yieldTest", 1, 1, { BLUA_NUMBER } },
{ -1, 0, 0, 0, 0 },
};
@@ -46,7 +49,8 @@ class sLua_ObjectTest {
DECLARE_METHOD(ObjectTest, OBJECTTEST_SOMEMETHOD1);
DECLARE_METHOD(ObjectTest, OBJECTTEST_SOMEMETHOD2);
- DECLARE_FUNCTION(ObjectTest, OBJECTTEST_CREATEOBJECTTEST);
+ DECLARE_CONSTRUCTOR(ObjectTest, OBJECTTEST_CONSTRUCTOR);
+ DECLARE_STATIC(ObjectTest, OBJECTTEST_SOMESTATIC);
DECLARE_FUNCTION(ObjectTest, OBJECTTEST_SOMEFUNCTION);
DECLARE_FUNCTION(ObjectTest, OBJECTTEST_YIELDTEST);
private:
@@ -61,9 +65,11 @@ class LuaObjectTestFactory : public LuaObjectFactory {
CHECK_METHODS(ObjectTest);
CHECK_FUNCTIONS(ObjectTest);
- PUSH_FUNCTION(ObjectTest, OBJECTTEST_CREATEOBJECTTEST);
+ PUSH_CONSTRUCTOR(ObjectTest, OBJECTTEST_CONSTRUCTOR);
+ PUSH_STATIC(ObjectTest, OBJECTTEST_SOMESTATIC);
PUSH_FUNCTION(ObjectTest, OBJECTTEST_SOMEFUNCTION);
PUSH_FUNCTION(ObjectTest, OBJECTTEST_YIELDTEST);
+ PUSH_CLASS_DONE();
}
private:
void pushObjectAndMembers(Lua & L) {
@@ -96,7 +102,7 @@ int sLua_ObjectTest::ObjectTest_proceed_statics(Lua & L, int n, int caller) thro
int y;
switch (caller) {
- case OBJECTTEST_CREATEOBJECTTEST:
+ case OBJECTTEST_CONSTRUCTOR:
{
ObjectTest * ot = new ObjectTest;
LuaObjectTestFactory factory(ot);
@@ -105,6 +111,10 @@ int sLua_ObjectTest::ObjectTest_proceed_statics(Lua & L, int n, int caller) thro
return 1;
break;
+ case OBJECTTEST_SOMESTATIC:
+ ObjectTest::someStatic();
+ break;
+
case OBJECTTEST_SOMEFUNCTION:
ObjectTest::someFunction();
break;
@@ -187,6 +197,11 @@ void MainTask::Do() {
TAssert(callCount == 3);
+ L.load("ObjectTest.SomeStatic()");
+ TAssert(L.gettop() == 0);
+
+ TAssert(callCount == 4);
+
L.load("yieldTest(0)");
while (L.yielded()) {
waitFor(LuaHelpersBase::getEvent(L));
@@ -201,9 +216,9 @@ void MainTask::Do() {
TAssert(L.gettop() == 0);
TAssert(objGotDestroyed == 0);
- L.load("obj2 = createObjectTest() obj2:destroy()");
+ L.load("obj2 = ObjectTest.new() obj2:destroy()");
TAssert(objGotDestroyed == 1);
- L.load("createObjectTest() collectgarbage('collect')");
+ L.load("ObjectTest.new() collectgarbage('collect')");
TAssert(objGotDestroyed == 2);
L.close();
TAssert(objGotDestroyed == 3);