From e228ec00409dfd61db80e4db48bcd38434729a19 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Mon, 25 Jun 2018 23:55:44 +0200 Subject: [PATCH] [DEV] Continue integration --- luaWrapper/luaWrapper.hpp | 390 ++++++++++++++++------------- sample/sample_1/BankAccount.cpp | 10 + sample/sample_1/BankAccount.hpp | 1 + sample/sample_1/LuaBankAccount.cpp | 40 +-- sample/sample_1/LuaBankAccount.hpp | 7 +- sample/sample_1/example1.lua | 3 + 6 files changed, 249 insertions(+), 202 deletions(-) diff --git a/luaWrapper/luaWrapper.hpp b/luaWrapper/luaWrapper.hpp index 36d7468..b6e221a 100644 --- a/luaWrapper/luaWrapper.hpp +++ b/luaWrapper/luaWrapper.hpp @@ -14,15 +14,15 @@ * can be created in either Lua or C++, and passed back and forth. * * The main functions of interest are the following: - * luaW_is - * luaW_to - * luaW_check - * luaW_push - * luaW_register - * luaW_setfuncs - * luaW_extend - * luaW_hold - * luaW_release + * luaW_is + * luaW_to + * luaW_check + * luaW_push + * luaW_register + * luaW_setfuncs + * luaW_extend + * luaW_hold + * luaW_release * * These functions allow you to manipulate arbitrary classes just like you * would the primitive types (e.g. numbers or strings). If you are familiar @@ -37,6 +37,7 @@ #include #include #include +#include #define LUAW_POSTCTOR_KEY "__postctor" #define LUAW_EXTENDS_KEY "__extends" @@ -59,8 +60,9 @@ inline int luaW_correctindex(lua_State* _luaState, int _index, int _correction) * alternative option, you may select a different function when registering * your class. */ -template ememory::SharedPtr luaW_defaultallocator(lua_State* _luaState) { - return ememory::makeShared(); +template +ememory::SharedPtr luaW_defaultallocator(lua_State* _luaState) { + return ememory::makeShared(); } /** @@ -70,7 +72,8 @@ template ememory::SharedPtr luaW_defaultallocator(lua_State* _lu * are using shared_ptr you would need to push the address of the object the * shared_ptr represents, rather than the address of the shared_ptr itself. */ -template void luaW_defaultidentifier(lua_State* _luaState, ememory::SharedPtr _obj) { +template +void luaW_defaultidentifier(lua_State* _luaState, ememory::SharedPtr _obj) { lua_pushlightuserdata(_luaState, _obj.get()); } @@ -83,66 +86,62 @@ template void luaW_defaultidentifier(lua_State* _luaState, ememory: * when and object is the type I want. This is only used internally. */ struct luaW_Userdata { - luaW_Userdata(ememory::SharedPtr vptr = NULL, luaW_Userdata (*udcast)(const luaW_Userdata&) = NULL) : - data(etk::move(vptr)), - cast(udcast) { + luaW_Userdata(ememory::SharedPtr _vptr = null, size_t _typeId = 0) : + m_data(etk::move(_vptr)), + m_typeId(_typeId) { // nothing to do ... } luaW_Userdata(luaW_Userdata&& _obj) { - etk::swap(data, _obj.data); + etk::swap(m_data, _obj.m_data); + etk::swap(m_typeId, _obj.m_typeId); } luaW_Userdata(const luaW_Userdata& _obj) { - data = _obj.data; + m_data = _obj.m_data; + m_typeId = _obj.m_typeId; } luaW_Userdata& operator= (luaW_Userdata&& _obj) { - etk::swap(data, _obj.data); + etk::swap(m_data, _obj.m_data); + etk::swap(m_typeId, _obj.m_typeId); return *this; } luaW_Userdata& operator= (const luaW_Userdata& _obj) { - data = _obj.data; + m_data = _obj.m_data; + m_typeId = _obj.m_typeId; return *this; } - ememory::SharedPtr data; - luaW_Userdata (*cast)(const luaW_Userdata&); + ememory::SharedPtr m_data; + size_t m_typeId; }; /** * This class cannot actually to be instantiated. It is used only hold the * table name and other information. */ -template class LuaWrapper { +template +class LuaWrapper { public: static const char* classname; - static void (*identifier)(lua_State*, ememory::SharedPtr); - static ememory::SharedPtr (*allocator)(lua_State*); - static luaW_Userdata (*cast)(const luaW_Userdata&); + static void (*identifier)(lua_State*, ememory::SharedPtr); + static ememory::SharedPtr (*allocator)(lua_State*); static void (*postconstructorrecurse)(lua_State* _luaState, int numargs); private: LuaWrapper(); }; -template const char* LuaWrapper::classname; -template void (*LuaWrapper::identifier)(lua_State*, ememory::SharedPtr); -template ememory::SharedPtr (*LuaWrapper::allocator)(lua_State*); -template luaW_Userdata (*LuaWrapper::cast)(const luaW_Userdata&); -template void (*LuaWrapper::postconstructorrecurse)(lua_State* _luaState, int _numargs); +template const char* LuaWrapper::classname; +template void (*LuaWrapper::identifier)(lua_State*, ememory::SharedPtr); +template ememory::SharedPtr (*LuaWrapper::allocator)(lua_State*); +template void (*LuaWrapper::postconstructorrecurse)(lua_State* _luaState, int _numargs); -/** - * Cast from an object of type T to an object of type U. This template - * function is instantiated by calling luaW_extend(L). This is only used - * internally. - */ -template luaW_Userdata luaW_cast(const luaW_Userdata& _obj) { - return luaW_Userdata(static_cast(ememory::staticPointerCast(_obj.data)), LuaWrapper::cast); +template +void luaW_identify(lua_State* _luaState, LUAW_TYPE* _obj) { + LuaWrapper::identifier(_luaState, static_cast(_obj)); } -template void luaW_identify(lua_State* _luaState, T* _obj) { - LuaWrapper::identifier(_luaState, static_cast(_obj)); -} - -template inline void luaW_wrapperfield(lua_State* _luaState, const char* _field) { +template +inline void luaW_wrapperfield(lua_State* _luaState, const char* _field) { lua_getfield(_luaState, LUA_REGISTRYINDEX, LUAW_WRAPPER_KEY); // ... LuaWrapper lua_getfield(_luaState, -1, _field); // ... LuaWrapper LuaWrapper.field - lua_getfield(_luaState, -1, LuaWrapper::classname); // ... LuaWrapper LuaWrapper.field LuaWrapper.field.class + lua_getfield(_luaState, -1, LuaWrapper::classname); // ... LuaWrapper LuaWrapper.field LuaWrapper.field.class lua_replace(_luaState, -3); // ... LuaWrapper.field.class LuaWrapper.field lua_pop(_luaState, 1); // ... LuaWrapper.field.class } @@ -153,11 +152,14 @@ template inline void luaW_wrapperfield(lua_State* _luaState, const * Returns 1 if the value at the given acceptable index is of type T (or if * strict is false, convertable to type T) and 0 otherwise. */ -template bool luaW_is(lua_State *_luaState, int _index, bool _strict = false) { +template +bool luaW_is(lua_State *_luaState, int _index, bool _strict = false) { bool equal = false;// lua_isnil(_luaState, index); - if (!equal && lua_isuserdata(_luaState, _index) && lua_getmetatable(_luaState, _index)) { + if ( equal == false + && lua_isuserdata(_luaState, _index) + && lua_getmetatable(_luaState, _index)) { // ... ud ... udmt - luaL_getmetatable(_luaState, LuaWrapper::classname); // ... ud ... udmt Tmt + luaL_getmetatable(_luaState, LuaWrapper::classname); // ... ud ... udmt Tmt equal = lua_rawequal(_luaState, -1, -2) != 0; if (!equal && !_strict) { lua_getfield(_luaState, -2, LUAW_EXTENDS_KEY); // ... ud ... udmt Tmt udmt.extends @@ -182,16 +184,11 @@ template bool luaW_is(lua_State *_luaState, int _index, bool _stric * Converts the given acceptable index to a T*. That value must be of (or * convertable to) type T; otherwise, returns NULL. */ -template ememory::SharedPtr luaW_to(lua_State* _luaState, int _index, bool _strict = false) { - if (luaW_is(_luaState, _index, _strict)) { +template +ememory::SharedPtr luaW_to(lua_State* _luaState, int _index, bool _strict = false) { + if (luaW_is(_luaState, _index, _strict)) { luaW_Userdata* pud = static_cast(lua_touserdata(_luaState, _index)); - luaW_Userdata ud; - while ( !_strict - && LuaWrapper::cast != pud->cast) { - ud = pud->cast(*pud); - pud = &ud; - } - return ememory::staticPointerCast(pud->data); + return ememory::staticPointerCast(pud->m_data); } return null; } @@ -199,31 +196,33 @@ template ememory::SharedPtr luaW_to(lua_State* _luaState, int _i /** * Analogous to luaL_check(boolean|string|*) * - * Converts the given acceptable index to a T*. That value must be of (or + * Converts the given acceptable index to a LUAW_TYPE*. That value must be of (or * convertable to) type T; otherwise, an error is raised. */ -inline template ememory::SharedPtr luaW_check(lua_State* _luaState, int _index, bool _strict = false) { - ememory::SharedPtr obj; - if (luaW_is(_luaState, _index, _strict)) { +template +ememory::SharedPtr luaW_check(lua_State* _luaState, + int _index, + bool _strict = false) { + ememory::SharedPtr obj; + if (luaW_is(_luaState, _index, _strict)) { luaW_Userdata* pud = static_cast(lua_touserdata(_luaState, _index)); - luaW_Userdata ud; - while (!_strict && LuaWrapper::cast != pud->cast) { - ud = pud->cast(*pud); - pud = &ud; - } - obj = ememory::staticPointerCast(pud->data); + obj = ememory::staticPointerCast(pud->m_data); } else { - const char *msg = lua_pushfstring(_luaState, "%s expected, got %s", LuaWrapper::classname, luaL_typename(_luaState, _index)); + const char *msg = lua_pushfstring(_luaState, "%s expected, got %s", LuaWrapper::classname, luaL_typename(_luaState, _index)); luaL_argerror(_luaState, _index, msg); } return obj; } -inline template ememory::SharedPtr luaW_opt(lua_State* _luaState, int _index, ememory::SharedPtr _fallback = NULL, bool _strict = false) { - if (lua_isnil(_luaState, _index)) { +template +ememory::SharedPtr luaW_opt(lua_State* _luaState, + int _index, + ememory::SharedPtr _fallback = null, + bool _strict = false) { + if (lua_isnil(_luaState, _index) == true) { return _fallback; } else { - return luaW_check(_luaState, _index, _strict); + return luaW_check(_luaState, _index, _strict); } } @@ -234,23 +233,24 @@ inline template ememory::SharedPtr luaW_opt(lua_State* _luaState * the Lua environment, it will assign the existing storage table to it. * Otherwise, a new storage table will be created for it. */ -inline template void luaW_push(lua_State* _luaState, ememory::SharedPtr _obj) { +template +void luaW_push(lua_State* _luaState, + ememory::SharedPtr _obj) { if (_obj != null) { - LuaWrapper::identifier(_luaState, _obj); // ... id - luaW_wrapperfield(_luaState, LUAW_CACHE_KEY); // ... id cache + LuaWrapper::identifier(_luaState, _obj); // ... id + luaW_wrapperfield(_luaState, LUAW_CACHE_KEY); // ... id cache lua_pushvalue(_luaState, -2); // ... id cache id lua_gettable(_luaState, -2); // ... id cache obj if (lua_isnil(_luaState, -1)) { // Create the new luaW_userdata and place it in the cache lua_pop(_luaState, 1); // ... id cache lua_insert(_luaState, -2); // ... cache id - luaW_Userdata* ud = static_cast(lua_newuserdata(_luaState, sizeof(luaW_Userdata))); // ... cache id obj - ud->data = _obj; - ud->cast = LuaWrapper::cast; + // placement new creation (need to initilaize the sructure: + luaW_Userdata* ud = new (lua_newuserdata(_luaState, sizeof(luaW_Userdata))) luaW_Userdata(_obj, ETK_GET_TYPE_ID(LUAW_TYPE)); // ... cache id obj lua_pushvalue(_luaState, -1); // ... cache id obj obj lua_insert(_luaState, -4); // ... obj cache id obj lua_settable(_luaState, -3); // ... obj cache - luaL_getmetatable(_luaState, LuaWrapper::classname); // ... obj cache mt + luaL_getmetatable(_luaState, LuaWrapper::classname); // ... obj cache mt lua_setmetatable(_luaState, -3); // ... obj cache lua_pop(_luaState, 1); // ... obj } else { @@ -270,9 +270,11 @@ inline template void luaW_push(lua_State* _luaState, ememory::Share * Returns true if luaW_hold took hold of the object, and false if it was * already held */ -inline template bool luaW_hold(lua_State* _luaState, ememory::SharedPtr _obj) { - luaW_wrapperfield(_luaState, LUAW_HOLDS_KEY); // ... holds - LuaWrapper::identifier(_luaState, _obj); // ... holds id +template +bool luaW_hold(lua_State* _luaState, + ememory::SharedPtr _obj) { + luaW_wrapperfield(_luaState, LUAW_HOLDS_KEY); // ... holds + LuaWrapper::identifier(_luaState, _obj); // ... holds id lua_pushvalue(_luaState, -1); // ... holds id id lua_gettable(_luaState, -3); // ... holds id hold // If it's not held, hold it @@ -298,26 +300,32 @@ inline template bool luaW_hold(lua_State* _luaState, ememory::Share * has already been deallocated. A wrapper is provided for when it is more * convenient to pass in the object directly. */ -template void luaW_release(lua_State* _luaState, int _index) { - luaW_wrapperfield(_luaState, LUAW_HOLDS_KEY); // ... id ... holds +template +void luaW_release(lua_State* _luaState, + int _index) { + luaW_wrapperfield(_luaState, LUAW_HOLDS_KEY); // ... id ... holds lua_pushvalue(_luaState, luaW_correctindex(_luaState, _index, 1)); // ... id ... holds id lua_pushnil(_luaState); // ... id ... holds id nil lua_settable(_luaState, -3); // ... id ... holds lua_pop(_luaState, 1); // ... id ... } -template void luaW_release(lua_State* _luaState, T* _obj) { - LuaWrapper::identifier(_luaState, _obj); // ... id - luaW_release(_luaState, -1); // ... id +template +void luaW_release(lua_State* _luaState, + LUAW_TYPE* _obj) { + LuaWrapper::identifier(_luaState, _obj); // ... id + luaW_release(_luaState, -1); // ... id lua_pop(_luaState, 1); // ... } -template void luaW_postconstructorinternal(lua_State* _luaState, int _numargs) { +template +void luaW_postconstructorinternal(lua_State* _luaState, + int _numargs) { // ... ud args... - if (LuaWrapper::postconstructorrecurse) { - LuaWrapper::postconstructorrecurse(_luaState, _numargs); + if (LuaWrapper::postconstructorrecurse) { + LuaWrapper::postconstructorrecurse(_luaState, _numargs); } - luaL_getmetatable(_luaState, LuaWrapper::classname); // ... ud args... mt + luaL_getmetatable(_luaState, LuaWrapper::classname); // ... ud args... mt lua_getfield(_luaState, -1, LUAW_POSTCTOR_KEY); // ... ud args... mt postctor if (lua_type(_luaState, -1) == LUA_TFUNCTION) { for (int i = 0; i < _numargs + 1; i++) { @@ -340,9 +348,11 @@ template void luaW_postconstructorinternal(lua_State* _luaState, in * arguments This exists to allow types to adjust values in thier storage table, * which can not be created until after the constructor is called. */ -template void luaW_postconstructor(lua_State* _luaState, int _numargs) { +template +void luaW_postconstructor(lua_State* _luaState, + int _numargs) { // ... ud args... - luaW_postconstructorinternal(_luaState, _numargs); // ... ud args... + luaW_postconstructorinternal(_luaState, _numargs); // ... ud args... lua_pop(_luaState, _numargs); // ... ud } @@ -352,18 +362,21 @@ template void luaW_postconstructor(lua_State* _luaState, int _numar * Creates an object of type T using the constructor and subsequently calls the * post-constructor on it. */ -template inline int luaW_new(lua_State* _luaState, int _numargs) { +template +inline int luaW_new(lua_State* _luaState, + int _numargs) { // ... args... - ememory::SharedPtr obj = LuaWrapper::allocator(_luaState); - luaW_push(_luaState, obj); // ... args... ud - luaW_hold(_luaState, obj); + ememory::SharedPtr obj = LuaWrapper::allocator(_luaState); + luaW_push(_luaState, obj); // ... args... ud + luaW_hold(_luaState, obj); lua_insert(_luaState, -1 - _numargs); // ... ud args... - luaW_postconstructor(_luaState, _numargs); // ... ud + luaW_postconstructor(_luaState, _numargs); // ... ud return 1; } -template int luaW_new(lua_State* _luaState) { - return luaW_new(_luaState, lua_gettop(_luaState)); +template +int luaW_new(lua_State* _luaState) { + return luaW_new(_luaState, lua_gettop(_luaState)); } /** @@ -375,11 +388,12 @@ template int luaW_new(lua_State* _luaState) { * individual userdata can be treated as a table, and can hold thier own * values. */ -template int luaW_index(lua_State* _luaState) { +template +int luaW_index(lua_State* _luaState) { // obj key - ememory::SharedPtr obj = luaW_to(_luaState, 1); - luaW_wrapperfield(_luaState, LUAW_STORAGE_KEY); // obj key storage - LuaWrapper::identifier(_luaState, obj); // obj key storage id + ememory::SharedPtr obj = luaW_to(_luaState, 1); + luaW_wrapperfield(_luaState, LUAW_STORAGE_KEY); // obj key storage + LuaWrapper::identifier(_luaState, obj); // obj key storage id lua_gettable(_luaState, -2); // obj key storage store // Check if storage table exists if (!lua_isnil(_luaState, -1)) { @@ -406,11 +420,12 @@ template int luaW_index(lua_State* _luaState) { * individual userdata can be treated as a table, and can hold thier own * values. */ -template int luaW_newindex(lua_State* _luaState) { +template +int luaW_newindex(lua_State* _luaState) { // obj key value - ememory::SharedPtr obj = luaW_check(_luaState, 1); - luaW_wrapperfield(_luaState, LUAW_STORAGE_KEY); // obj key value storage - LuaWrapper::identifier(_luaState, obj); // obj key value storage id + ememory::SharedPtr obj = luaW_check(_luaState, 1); + luaW_wrapperfield(_luaState, LUAW_STORAGE_KEY); // obj key value storage + LuaWrapper::identifier(_luaState, obj); // obj key value storage id lua_pushvalue(_luaState, -1); // obj key value storage id id lua_gettable(_luaState, -3); // obj key value storage id store // Add the storage table if there isn't one already @@ -434,24 +449,36 @@ template int luaW_newindex(lua_State* _luaState) { * count is decremented and if this is the final reference to the userdata its * environment table is nil'd and pointer deleted with the destructor callback. */ -template int luaW_gc(lua_State* _luaState) { +template +int luaW_gc(lua_State* _luaState) { // obj - ememory::SharedPtr obj = luaW_to(_luaState, 1); - LuaWrapper::identifier(_luaState, obj); // obj key value storage id - luaW_wrapperfield(_luaState, LUAW_HOLDS_KEY); // obj id counts count holds + /* + ememory::SharedPtr obj = luaW_to(_luaState, 1); + LuaWrapper::identifier(_luaState, obj); // obj key value storage id + luaW_wrapperfield(_luaState, LUAW_HOLDS_KEY); // obj id counts count holds lua_pushvalue(_luaState, 2); // obj id counts count holds id lua_gettable(_luaState, -2); // obj id counts count holds hold if (lua_toboolean(_luaState, -1)) { obj.reset(); } - luaW_wrapperfield(_luaState, LUAW_STORAGE_KEY); // obj id counts count holds hold storage + luaW_wrapperfield(_luaState, LUAW_STORAGE_KEY); // obj id counts count holds hold storage lua_pushvalue(_luaState, 2); // obj id counts count holds hold storage id lua_pushnil(_luaState); // obj id counts count holds hold storage id nil lua_settable(_luaState, -3); // obj id counts count holds hold storage - luaW_release(_luaState, 2); + luaW_release(_luaState, 2); + */ + luaW_Userdata *object = static_cast( lua_touserdata( _luaState, 1 ) ); + object->~luaW_Userdata(); + lua_pop( _luaState, 1 ); return 0; } - +/* + static int gc( lua_State* const L ) + { + + return 0; + } +*/ /** * Thakes two tables and registers them with Lua to the table on the top of the * stack. @@ -535,41 +562,42 @@ inline void luaW_initialize(lua_State* _luaState) { * table globally. As with luaL_register and luaL_setfuncs, both funcstions * leave the new table on the top of the stack. */ -template void luaW_setfuncs(lua_State* _luaState, - const char* _classname, - const luaL_Reg* _table, - const luaL_Reg* _metatable, - ememory::SharedPtr (*_allocator)(lua_State*), - void (*_identifier)(lua_State*, ememory::SharedPtr)) { +template +void luaW_setfuncs(lua_State* _luaState, + const char* _classname, + const luaL_Reg* _table, + const luaL_Reg* _metatable, + ememory::SharedPtr (*_allocator)(lua_State*), + void (*_identifier)(lua_State*, ememory::SharedPtr)) { luaW_initialize(_luaState); - LuaWrapper::classname = _classname; - LuaWrapper::identifier = _identifier; - LuaWrapper::allocator = _allocator; + LuaWrapper::classname = _classname; + LuaWrapper::identifier = _identifier; + LuaWrapper::allocator = _allocator; const luaL_Reg defaulttable[] = { - { "new", luaW_new }, + { "new", luaW_new }, { NULL, NULL } }; const luaL_Reg defaultmetatable[] = { - { "__index", luaW_index }, - { "__newindex", luaW_newindex }, - { "__gc", luaW_gc }, + { "__index", luaW_index }, + { "__newindex", luaW_newindex }, + { "__gc", luaW_gc }, { NULL, NULL } }; // Set up per-type tables lua_getfield(_luaState, LUA_REGISTRYINDEX, LUAW_WRAPPER_KEY); // ... LuaWrapper lua_getfield(_luaState, -1, LUAW_STORAGE_KEY); // ... LuaWrapper LuaWrapper.storage lua_newtable(_luaState); // ... LuaWrapper LuaWrapper.storage {} - lua_setfield(_luaState, -2, LuaWrapper::classname); // ... LuaWrapper LuaWrapper.storage + lua_setfield(_luaState, -2, LuaWrapper::classname); // ... LuaWrapper LuaWrapper.storage lua_pop(_luaState, 1); // ... LuaWrapper lua_getfield(_luaState, -1, LUAW_HOLDS_KEY); // ... LuaWrapper LuaWrapper.holds lua_newtable(_luaState); // ... LuaWrapper LuaWrapper.holds {} - lua_setfield(_luaState, -2, LuaWrapper::classname); // ... LuaWrapper LuaWrapper.holds + lua_setfield(_luaState, -2, LuaWrapper::classname); // ... LuaWrapper LuaWrapper.holds lua_pop(_luaState, 1); // ... LuaWrapper lua_getfield(_luaState, -1, LUAW_CACHE_KEY); // ... LuaWrapper LuaWrapper.cache lua_newtable(_luaState); // ... LuaWrapper LuaWrapper.cache {} - luaW_wrapperfield(_luaState, LUAW_CACHE_METATABLE_KEY); // ... LuaWrapper LuaWrapper.cache {} cmt + luaW_wrapperfield(_luaState, LUAW_CACHE_METATABLE_KEY); // ... LuaWrapper LuaWrapper.cache {} cmt lua_setmetatable(_luaState, -2); // ... LuaWrapper LuaWrapper.cache {} - lua_setfield(_luaState, -2, LuaWrapper::classname); // ... LuaWrapper LuaWrapper.cache + lua_setfield(_luaState, -2, LuaWrapper::classname); // ... LuaWrapper LuaWrapper.cache lua_pop(_luaState, 2); // ... // Open table lua_newtable(_luaState); // ... T @@ -581,46 +609,51 @@ template void luaW_setfuncs(lua_State* _luaState, luaW_registerfuncs(_luaState, defaultmetatable, _metatable); // ... T mt lua_setfield(_luaState, -2, "metatable"); // ... T } -template void luaW_setfuncs(lua_State* _luaState, - const char* _classname, - const luaL_Reg* _table, - const luaL_Reg* _metatable, - ememory::SharedPtr (*_allocator)(lua_State*)) { - luaW_setfuncs(_luaState, _classname, _table, _metatable, _allocator, luaW_defaultidentifier); +template +void luaW_setfuncs(lua_State* _luaState, + const char* _classname, + const luaL_Reg* _table, + const luaL_Reg* _metatable, + ememory::SharedPtr (*_allocator)(lua_State*)) { + luaW_setfuncs(_luaState, _classname, _table, _metatable, _allocator, luaW_defaultidentifier); } -template void luaW_setfuncs(lua_State* _luaState, - const char* _classname, - const luaL_Reg* _table, - const luaL_Reg* _metatable) { - luaW_setfuncs(_luaState, _classname, _table, _metatable, luaW_defaultallocator, luaW_defaultidentifier); +template +void luaW_setfuncs(lua_State* _luaState, + const char* _classname, + const luaL_Reg* _table, + const luaL_Reg* _metatable) { + luaW_setfuncs(_luaState, _classname, _table, _metatable, luaW_defaultallocator, luaW_defaultidentifier); } -template void luaW_register(lua_State* _luaState, - const char* _classname, - const luaL_Reg* _table, - const luaL_Reg* _metatable, - ememory::SharedPtr (*_allocator)(lua_State*), - void (*_identifier)(lua_State*, ememory::SharedPtr)) { +template +void luaW_register(lua_State* _luaState, + const char* _classname, + const luaL_Reg* _table, + const luaL_Reg* _metatable, + ememory::SharedPtr (*_allocator)(lua_State*), + void (*_identifier)(lua_State*, ememory::SharedPtr)) { luaW_setfuncs(_luaState, _classname, _table, _metatable, _allocator, _identifier); // ... T - lua_pushvalue(_luaState, -1); // ... T T - lua_setglobal(_luaState, _classname); // ... T + lua_pushvalue(_luaState, -1); // ... LUAW_TYPE LUAW_TYPE + lua_setglobal(_luaState, _classname); // ... LUAW_TYPE } -template void luaW_register(lua_State* _luaState, - const char* _classname, - const luaL_Reg* _table, - const luaL_Reg* _metatable, - ememory::SharedPtr (*_allocator)(lua_State*)) { - luaW_setfuncs(_luaState, _classname, _table, _metatable, _allocator, luaW_defaultidentifier); - lua_pushvalue(_luaState, -1); // ... T T - lua_setglobal(_luaState, _classname); // ... T +template +void luaW_register(lua_State* _luaState, + const char* _classname, + const luaL_Reg* _table, + const luaL_Reg* _metatable, + ememory::SharedPtr (*_allocator)(lua_State*)) { + luaW_setfuncs(_luaState, _classname, _table, _metatable, _allocator, luaW_defaultidentifier); + lua_pushvalue(_luaState, -1); // ... LUAW_TYPE LUAW_TYPE + lua_setglobal(_luaState, _classname); // ... LUAW_TYPE } -template void luaW_register(lua_State* _luaState, - const char* _classname, - const luaL_Reg* _table, - const luaL_Reg* _metatable) { - luaW_setfuncs(_luaState, _classname, _table, _metatable, luaW_defaultallocator, luaW_defaultidentifier); // ... T +template +void luaW_register(lua_State* _luaState, + const char* _classname, + const luaL_Reg* _table, + const luaL_Reg* _metatable) { + luaW_setfuncs(_luaState, _classname, _table, _metatable, luaW_defaultallocator, luaW_defaultidentifier); // ... T lua_pushvalue(_luaState, -1); // ... T T lua_setglobal(_luaState, _classname); // ... T } @@ -629,21 +662,22 @@ template void luaW_register(lua_State* _luaState, * luaW_extend is used to declare that class T inherits from class U. All * functions in the base class will be available to the derived class (except * when they share a function name, in which case the derived class's function - * wins). This also allows luaW_to to cast your object apropriately, as + * wins). This also allows luaW_to to cast your object apropriately, as * casts straight through a void pointer do not work. */ -template void luaW_extend(lua_State* _luaState) { - if(!LuaWrapper::classname) { +template +void luaW_extend(lua_State* _luaState) { + if(!LuaWrapper::classname) { luaL_error(_luaState, "attempting to call extend on a type that has not been registered"); } - if(!LuaWrapper::classname) { - luaL_error(_luaState, "attempting to extend %s by a type that has not been registered", LuaWrapper::classname); + if(!LuaWrapper::classname) { + luaL_error(_luaState, "attempting to extend %s by a type that has not been registered", LuaWrapper::classname); } - LuaWrapper::cast = luaW_cast; - LuaWrapper::identifier = luaW_identify; - LuaWrapper::postconstructorrecurse = luaW_postconstructorinternal; - luaL_getmetatable(_luaState, LuaWrapper::classname); // mt - luaL_getmetatable(_luaState, LuaWrapper::classname); // mt emt + //LuaWrapper::cast = luaW_cast; + LuaWrapper::identifier = luaW_identify; + LuaWrapper::postconstructorrecurse = luaW_postconstructorinternal; + luaL_getmetatable(_luaState, LuaWrapper::classname); // mt + luaL_getmetatable(_luaState, LuaWrapper::classname); // mt emt // Point T's metatable __index at U's metatable for inheritance lua_newtable(_luaState); // mt emt {} lua_pushvalue(_luaState, -2); // mt emt {} emt @@ -652,21 +686,21 @@ template void luaW_extend(lua_State* _luaState) { // Set up per-type tables to point at parent type lua_getfield(_luaState, LUA_REGISTRYINDEX, LUAW_WRAPPER_KEY); // ... LuaWrapper lua_getfield(_luaState, -1, LUAW_STORAGE_KEY); // ... LuaWrapper LuaWrapper.storage - lua_getfield(_luaState, -1, LuaWrapper::classname); // ... LuaWrapper LuaWrapper.storage U - lua_setfield(_luaState, -2, LuaWrapper::classname); // ... LuaWrapper LuaWrapper.storage + lua_getfield(_luaState, -1, LuaWrapper::classname); // ... LuaWrapper LuaWrapper.storage U + lua_setfield(_luaState, -2, LuaWrapper::classname); // ... LuaWrapper LuaWrapper.storage lua_pop(_luaState, 1); // ... LuaWrapper lua_getfield(_luaState, -1, LUAW_HOLDS_KEY); // ... LuaWrapper LuaWrapper.holds - lua_getfield(_luaState, -1, LuaWrapper::classname); // ... LuaWrapper LuaWrapper.holds U - lua_setfield(_luaState, -2, LuaWrapper::classname); // ... LuaWrapper LuaWrapper.holds + lua_getfield(_luaState, -1, LuaWrapper::classname); // ... LuaWrapper LuaWrapper.holds U + lua_setfield(_luaState, -2, LuaWrapper::classname); // ... LuaWrapper LuaWrapper.holds lua_pop(_luaState, 1); // ... LuaWrapper lua_getfield(_luaState, -1, LUAW_CACHE_KEY); // ... LuaWrapper LuaWrapper.cache - lua_getfield(_luaState, -1, LuaWrapper::classname); // ... LuaWrapper LuaWrapper.cache U - lua_setfield(_luaState, -2, LuaWrapper::classname); // ... LuaWrapper LuaWrapper.cache + lua_getfield(_luaState, -1, LuaWrapper::classname); // ... LuaWrapper LuaWrapper.cache U + lua_setfield(_luaState, -2, LuaWrapper::classname); // ... LuaWrapper LuaWrapper.cache lua_pop(_luaState, 2); // ... // Make a list of all types that inherit from U, for type checking lua_getfield(_luaState, -2, LUAW_EXTENDS_KEY); // mt emt mt.extends lua_pushvalue(_luaState, -2); // mt emt mt.extends emt - lua_setfield(_luaState, -2, LuaWrapper::classname); // mt emt mt.extends + lua_setfield(_luaState, -2, LuaWrapper::classname); // mt emt mt.extends lua_getfield(_luaState, -2, LUAW_EXTENDS_KEY); // mt emt mt.extends emt.extends for (lua_pushnil(_luaState); lua_next(_luaState, -2); lua_pop(_luaState, 1)) { // mt emt mt.extends emt.extends k v diff --git a/sample/sample_1/BankAccount.cpp b/sample/sample_1/BankAccount.cpp index 9c39557..39aa1bd 100644 --- a/sample/sample_1/BankAccount.cpp +++ b/sample/sample_1/BankAccount.cpp @@ -1,11 +1,21 @@ #include "BankAccount.hpp" +#include "test-debug/debug.hpp" float BankAccount::s_totalMoneyInBank = 0; +static int32_t iiii = 0; BankAccount::BankAccount(const char* _owner, float _balance) : m_owner(_owner) , m_balance(_balance) { s_totalMoneyInBank += _balance; + iiii++; + TEST_WARNING( "Create object: " << iiii); +} + +BankAccount::~BankAccount() { + TEST_WARNING( "Remove object: " << iiii); + iiii--; + } const char* BankAccount::getOwnerName() const { diff --git a/sample/sample_1/BankAccount.hpp b/sample/sample_1/BankAccount.hpp index 7178a1e..a5999c3 100644 --- a/sample/sample_1/BankAccount.hpp +++ b/sample/sample_1/BankAccount.hpp @@ -7,6 +7,7 @@ class BankAccount { public: BankAccount(const char* _owner, float _balance); + ~BankAccount(); const char* getOwnerName() const; void deposit(float _amount); void withdraw(float _amount); diff --git a/sample/sample_1/LuaBankAccount.cpp b/sample/sample_1/LuaBankAccount.cpp index 220ad13..ec0958a 100644 --- a/sample/sample_1/LuaBankAccount.cpp +++ b/sample/sample_1/LuaBankAccount.cpp @@ -9,15 +9,17 @@ using namespace std; +ETK_DECLARE_TYPE(BankAccount); + /** * Allocator * * Types that do not have a default contructor require you to write an allocator function. * This function is passed to luaW_register. */ -ememory::SharedPtr BankAccount_new(lua_State *_L) { - const char* owner = luaL_checkstring(_L, 1); - float balance = luaL_checknumber(_L, 2); +ememory::SharedPtr BankAccount_new(lua_State *_luaState) { + const char* owner = luaL_checkstring(_luaState, 1); + float balance = luaL_checknumber(_luaState, 2); return ememory::makeShared(owner, balance); } @@ -27,8 +29,8 @@ ememory::SharedPtr BankAccount_new(lua_State *_L) { * These functions can be called directly from the BankAccount table in lua */ -int BankAccount_checkTotalMoneyInBank(lua_State *_L) { - lua_pushnumber(_L, BankAccount::checkTotalMoneyInBank()); +int BankAccount_checkTotalMoneyInBank(lua_State *_luaState) { + lua_pushnumber(_luaState, BankAccount::checkTotalMoneyInBank()); return 1; } @@ -40,29 +42,29 @@ int BankAccount_checkTotalMoneyInBank(lua_State *_L) { * by the use of special a __index metatmethod that is set up by LuaWrapper. */ -int BankAccount_getOwnerName(lua_State *_L) { - auto account = luaW_check(_L, 1); - lua_pushstring(_L, account->getOwnerName()); +int BankAccount_getOwnerName(lua_State *_luaState) { + auto account = luaW_check(_luaState, 1); + lua_pushstring(_luaState, account->getOwnerName()); return 1; } -int BankAccount_deposit(lua_State* _L) { - auto account = luaW_check(_L, 1); - float amount = luaL_checknumber(_L, 2); +int BankAccount_deposit(lua_State* _luaState) { + auto account = luaW_check(_luaState, 1); + float amount = luaL_checknumber(_luaState, 2); account->deposit(amount); return 0; } -int BankAccount_withdraw(lua_State* _L) { - auto account = luaW_check(_L, 1); - float amount = luaL_checknumber(_L, 2); +int BankAccount_withdraw(lua_State* _luaState) { + auto account = luaW_check(_luaState, 1); + float amount = luaL_checknumber(_luaState, 2); account->withdraw(amount); return 0; } -int BankAccount_checkBalance(lua_State* _L) { - auto account = luaW_check(_L, 1); - lua_pushnumber(_L, account->checkBalance()); +int BankAccount_checkBalance(lua_State* _luaState) { + auto account = luaW_check(_luaState, 1); + lua_pushnumber(_luaState, account->checkBalance()); return 1; } @@ -79,8 +81,8 @@ static luaL_Reg BankAccount_metatable[] = { { NULL, NULL } }; -int luaopen_BankAccount(lua_State* _L) { - luaW_register(_L, +int luaopen_BankAccount(lua_State* _luaState) { + luaW_register(_luaState, "BankAccount", BankAccount_table, BankAccount_metatable, diff --git a/sample/sample_1/LuaBankAccount.hpp b/sample/sample_1/LuaBankAccount.hpp index 098e5e9..b2d4c80 100644 --- a/sample/sample_1/LuaBankAccount.hpp +++ b/sample/sample_1/LuaBankAccount.hpp @@ -1,7 +1,4 @@ -#ifndef LUAEXAMPLE_HPP_ -#define LUAEXAMPLE_HPP_ +#pragma once struct lua_State; -int luaopen_BankAccount(lua_State* _L); - -#endif // LUAEXAMPLE_HPP_ +int luaopen_BankAccount(lua_State* _luaState); diff --git a/sample/sample_1/example1.lua b/sample/sample_1/example1.lua index 4e10078..f22cf56 100644 --- a/sample/sample_1/example1.lua +++ b/sample/sample_1/example1.lua @@ -1,5 +1,8 @@ -- create a bank account and do some account action: alicesaccount = BankAccount.new("Alice", 100) +alicesaccount = BankAccount.new("Alice", 100) +alicesaccount = BankAccount.new("Alice", 100) +alicesaccount = BankAccount.new("Alice", 100) alicesaccount:deposit(20); alicesaccount:deposit(30); alicesaccount:deposit(40);