diff options
Diffstat (limited to 'src/libjin-lua/common')
-rw-r--r-- | src/libjin-lua/common/je_lua.h | 83 | ||||
-rw-r--r-- | src/libjin-lua/common/je_lua_callback.cpp | 43 | ||||
-rw-r--r-- | src/libjin-lua/common/je_lua_callback.h | 66 | ||||
-rw-r--r-- | src/libjin-lua/common/je_lua_common.h | 9 | ||||
-rw-r--r-- | src/libjin-lua/common/je_lua_constant.h | 14 | ||||
-rw-r--r-- | src/libjin-lua/common/je_lua_error.h | 30 | ||||
-rw-r--r-- | src/libjin-lua/common/je_lua_function.cpp | 0 | ||||
-rw-r--r-- | src/libjin-lua/common/je_lua_function.h | 6 | ||||
-rw-r--r-- | src/libjin-lua/common/je_lua_object.cpp | 112 | ||||
-rw-r--r-- | src/libjin-lua/common/je_lua_object.h | 69 | ||||
-rw-r--r-- | src/libjin-lua/common/je_lua_port.h | 8 | ||||
-rw-r--r-- | src/libjin-lua/common/je_lua_reference.cpp | 42 | ||||
-rw-r--r-- | src/libjin-lua/common/je_lua_reference.h | 54 | ||||
-rw-r--r-- | src/libjin-lua/common/je_lua_runtime.cpp | 215 | ||||
-rw-r--r-- | src/libjin-lua/common/je_lua_shared.cpp | 11 | ||||
-rw-r--r-- | src/libjin-lua/common/je_lua_shared.hpp | 84 |
16 files changed, 846 insertions, 0 deletions
diff --git a/src/libjin-lua/common/je_lua.h b/src/libjin-lua/common/je_lua.h new file mode 100644 index 0000000..74f9819 --- /dev/null +++ b/src/libjin-lua/common/je_lua.h @@ -0,0 +1,83 @@ +#ifndef __JE_LUA_H__ +#define __JE_LUA_H__ + +#include <vector> + +#include "LuaJIT/lua.hpp" +#include "luax/luax.h" + +#include "je_lua_shared.hpp" +#include "je_lua_object.h" +#include "je_lua_reference.h" + +namespace JinEngine +{ + namespace Lua + { + + // Extends luax.h library. + + /// + /// + /// + LuaObject* luax_newinstance(lua_State* L, const char* type, Shared* shared); + + /// + /// Copy instance to another lua state. + /// + LuaObject* luax_copyinstance(lua_State* to, LuaObject* src); + + /// + /// + /// + LuaObject* luax_checkobject(lua_State* L, int idx, const char* type); + + /// + /// Access lua object by object pointer. + /// + int luax_getobject(lua_State* L, LuaObject* obj); + + /// + /// Get object's reference table. + /// + void luax_getreference(lua_State* L, LuaObject* obj); + + /// + /// + /// + bool luax_addreference(lua_State* L, LuaObject* obj, LuaObject* dep); + + /// + /// + /// + void luax_removereference(lua_State* L, LuaObject* obj); + + /// + /// + /// + void luax_removereference(lua_State* L, LuaObject* obj, LuaObject* dep); + + /// + /// + /// + void luax_removeobject(lua_State* L, LuaObject* obj); + + /// + /// + /// + int luax_getobjectstable(lua_State* L); + + /// + /// + /// + int luax_getmodulestable(lua_State* L); + + /// + /// + /// + int luax_getreferencestable(lua_State* L); + + } +} + +#endif
\ No newline at end of file diff --git a/src/libjin-lua/common/je_lua_callback.cpp b/src/libjin-lua/common/je_lua_callback.cpp new file mode 100644 index 0000000..392f919 --- /dev/null +++ b/src/libjin-lua/common/je_lua_callback.cpp @@ -0,0 +1,43 @@ +#include "je_lua_callback.h" + +namespace JinEngine +{ + namespace Lua + { + + LuaCallback::LuaCallback(lua_State* L) + : mLuaFunc(nullptr) + , mParams(0) + , mL(L) + { + } + + LuaCallback::~LuaCallback() + { + delete mLuaFunc; + for (auto p : mParams) + delete p; + } + + void LuaCallback::setFunc(int i) + { + if (mLuaFunc != nullptr) + delete mLuaFunc; + mLuaFunc = new LuaRef(mL, i); + } + + void LuaCallback::pushParam(int i) + { + mParams.push_back(new LuaRef(mL, i)); + } + + void LuaCallback::call() + { + mLuaFunc->push(); + for (auto p : mParams) + p->push(); + luax_call(mL, mParams.size(), 0); + } + + } +}
\ No newline at end of file diff --git a/src/libjin-lua/common/je_lua_callback.h b/src/libjin-lua/common/je_lua_callback.h new file mode 100644 index 0000000..0467e45 --- /dev/null +++ b/src/libjin-lua/common/je_lua_callback.h @@ -0,0 +1,66 @@ +#ifndef __JIN_COMMON_FUNCTION_H +#define __JIN_COMMON_FUNCTION_H + +#include <vector> + +#include "libjin/jin.h" +#include "je_lua_reference.h" + +namespace JinEngine +{ + namespace Lua + { + + /// + /// + /// + class LuaCallback + { + public: + /// + /// + /// + LuaCallback(lua_State* L); + + /// + /// + /// + ~LuaCallback(); + + /// + /// + /// + void setFunc(int i); + + /// + /// + /// + void pushParam(int i); + + /// + /// + /// + void call(); + + private: + /// + /// + /// + LuaRef* mLuaFunc; + + /// + /// + /// + std::vector<LuaRef*> mParams; + + /// + /// + /// + lua_State* const mL; + + }; + + } // namespace Lua +} // namespace JinEngine + +#endif // __JIN_COMMON_REFERENCE_H
\ No newline at end of file diff --git a/src/libjin-lua/common/je_lua_common.h b/src/libjin-lua/common/je_lua_common.h new file mode 100644 index 0000000..cdd4f36 --- /dev/null +++ b/src/libjin-lua/common/je_lua_common.h @@ -0,0 +1,9 @@ +#ifndef __JIN_M_TYPES_H +#define __JIN_M_TYPES_H + +#include "je_lua.h" +#include "je_lua_port.h" +#include "je_lua_error.h" +#include "je_lua_reference.h" + +#endif
\ No newline at end of file diff --git a/src/libjin-lua/common/je_lua_constant.h b/src/libjin-lua/common/je_lua_constant.h new file mode 100644 index 0000000..c173b88 --- /dev/null +++ b/src/libjin-lua/common/je_lua_constant.h @@ -0,0 +1,14 @@ +#ifndef __JE_LUA_CONSTANT_H__ +#define __JE_LUA_CONSTANT_H__ + +namespace JinEngine +{ + namespace Lua + { + + + + } +} + +#endif
\ No newline at end of file diff --git a/src/libjin-lua/common/je_lua_error.h b/src/libjin-lua/common/je_lua_error.h new file mode 100644 index 0000000..bd5695d --- /dev/null +++ b/src/libjin-lua/common/je_lua_error.h @@ -0,0 +1,30 @@ +#ifndef __JIN_ERROR_H +#define __JIN_ERROR_H + +#include <string.h> + +#include "common/je_lua.h" + +namespace JinEngine +{ + namespace Lua + { + + static const int FORMAT_MSG_BUFFER_SIZE = 2048; + + inline void error(lua_State* L, const char* fmt, ...) + { + char err[FORMAT_MSG_BUFFER_SIZE + 1] = { 0 }; + va_list args; + va_start(args, fmt); + vsnprintf(err + strlen(err), FORMAT_MSG_BUFFER_SIZE, fmt, args); + va_end(args); + //luax_getglobal(L, "jin"); + //luax_setfieldstring(L, "error", err); + luax_error(L, err); + } + + } // namespace Lua +} // namespace JinEngine + +#endif
\ No newline at end of file diff --git a/src/libjin-lua/common/je_lua_function.cpp b/src/libjin-lua/common/je_lua_function.cpp new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/libjin-lua/common/je_lua_function.cpp diff --git a/src/libjin-lua/common/je_lua_function.h b/src/libjin-lua/common/je_lua_function.h new file mode 100644 index 0000000..49c1b31 --- /dev/null +++ b/src/libjin-lua/common/je_lua_function.h @@ -0,0 +1,6 @@ +#ifndef __JE_LUA_FUNCTION_H__ +#define __JE_LUA_FUNCTION_H__ + + + +#endif
\ No newline at end of file diff --git a/src/libjin-lua/common/je_lua_object.cpp b/src/libjin-lua/common/je_lua_object.cpp new file mode 100644 index 0000000..c35356e --- /dev/null +++ b/src/libjin-lua/common/je_lua_object.cpp @@ -0,0 +1,112 @@ +#include "je_lua_object.h" +#include "je_lua.h" + +namespace JinEngine +{ + namespace Lua + { + + void LuaObject::bind(Shared* obj) + { + if (obj) + { + shared = obj; + shared->retain(); + dependencies = new std::map<uint, LuaObject*>(); + } + } + + void LuaObject::release() + { + // Delete lua shared table reference and references. + if (dependencies) + { + clearDependencies(); + delete dependencies; + dependencies = nullptr; + } + // Try delete engine side shared. + if (shared) + { + shared->release(); + shared = nullptr; + } + } + + const char* LuaObject::getObjectType() + { + return type; + } + + Shared* LuaObject::getShared() + { + return shared; + } + + void LuaObject::setDependency(uint key, LuaObject* dep) + { + removeDependency(key); + dependencies->insert(std::pair<uint, LuaObject*>(key, dep)); + luax_addreference(state, this, dep); + } + + void LuaObject::removeDependency(uint key) + { + if (!isDependOn(key)) + return; + DepsMap::iterator it = dependencies->find(key); + LuaObject* dep = it->second; + luax_removereference(state, this, dep); + dependencies->erase(it); + } + + void LuaObject::removeDependency(LuaObject* dependency) + { + for (DepsMap::iterator it = dependencies->begin(); it != dependencies->end();) + { + LuaObject* dep = it->second; + if (dep == dependency) + { + luax_removereference(state, this, dep); + dependencies->erase(it); + } + else + ++it; + } + } + + bool LuaObject::isDependOn(uint key) + { + return dependencies->find(key) != dependencies->end(); + } + + bool LuaObject::isDependOn(LuaObject* shared) + { + for (std::pair<uint, LuaObject*> dep : (*dependencies)) + { + if (dep.second == shared) + return true; + } + return false; + } + + void LuaObject::clearDependencies() + { + luax_removereference(state, this); + dependencies->clear(); + } + + LuaObject* LuaObject::getDependency(uint key) + { + if (!isDependOn(key)) + return nullptr; + return dependencies->find(key)->second; + } + + int LuaObject::getDependenciesCount() + { + return dependencies->size(); + } + + } +}
\ No newline at end of file diff --git a/src/libjin-lua/common/je_lua_object.h b/src/libjin-lua/common/je_lua_object.h new file mode 100644 index 0000000..6e86508 --- /dev/null +++ b/src/libjin-lua/common/je_lua_object.h @@ -0,0 +1,69 @@ +#ifndef __JIN_COMMON_OBJECT_H__ +#define __JIN_COMMON_OBJECT_H__ + +#include "libjin/jin.h" +#include "je_lua_shared.hpp" + +struct lua_State; + +namespace JinEngine +{ + namespace Lua + { + + class LuaObject + { + public: + /// + /// Set lua_State and object it bind. + /// + void bind(Shared* obj); + + void release(); + + const char* getObjectType(); + + Shared* getShared(); + + template<class T> + T* getObject() + { + return shared->getObject<T>(); + } + + void setDependency(uint key, LuaObject* dep); + + void removeDependency(uint key); + + void removeDependency(LuaObject* dep); + + bool isDependOn(uint key); + + bool isDependOn(LuaObject* shared); + + void clearDependencies(); + + LuaObject* getDependency(uint key); + + int getDependenciesCount(); + + ////////////////////////////////////////////////////////////////////////////////////////////////////// + // Lua state object. + ////////////////////////////////////////////////////////////////////////////////////////////////////// + + using DepsMap = std::map<uint, LuaObject*>; + + lua_State* state; + + Shared* shared; + + const char* type; + + DepsMap* dependencies; + + }; + + } // namespace Lua +} // namespace JinEngine + +#endif // __JIN_COMMON_OBJECT_H__
\ No newline at end of file diff --git a/src/libjin-lua/common/je_lua_port.h b/src/libjin-lua/common/je_lua_port.h new file mode 100644 index 0000000..8e99ca4 --- /dev/null +++ b/src/libjin-lua/common/je_lua_port.h @@ -0,0 +1,8 @@ +#ifndef __JE_LUA_PORT_H +#define __JE_LUA_PORT_H + +#define LUA_PORT extern +#define LUA_IMPLEMENT static +#define LUA_EXPORT + +#endif
\ No newline at end of file diff --git a/src/libjin-lua/common/je_lua_reference.cpp b/src/libjin-lua/common/je_lua_reference.cpp new file mode 100644 index 0000000..72c1c3e --- /dev/null +++ b/src/libjin-lua/common/je_lua_reference.cpp @@ -0,0 +1,42 @@ +#include "common/je_lua.h" + +#include "je_lua_reference.h" + +namespace JinEngine +{ + namespace Lua + { + + LuaRef::LuaRef(lua_State* L, int i) + : mL(L) + { + // Get value. + luax_pushvalue(mL, i); + // Set reference. + luax_getreferencestable(L); + luax_pushvalue(mL, -2); + mIndex = luax_ref(mL, -2); + luax_pop(L, 3); + } + + LuaRef::~LuaRef() + { + unref(); + } + + void LuaRef::unref() + { + luax_getreferencestable(mL); + luax_unref(mL, -1, mIndex); + luax_pop(mL, 1); + } + + void LuaRef::push() + { + luax_getreferencestable(mL); + luax_rawgeti(mL, -1, mIndex); + luax_remove(mL, -2); + } + + } +}
\ No newline at end of file diff --git a/src/libjin-lua/common/je_lua_reference.h b/src/libjin-lua/common/je_lua_reference.h new file mode 100644 index 0000000..1a62dba --- /dev/null +++ b/src/libjin-lua/common/je_lua_reference.h @@ -0,0 +1,54 @@ +#ifndef __JIN_COMMON_REFERENCE_H +#define __JIN_COMMON_REFERENCE_H + +#include "common/je_lua.h" + +namespace JinEngine +{ + namespace Lua + { + + /// + /// This class wraps the reference functionality built into Lua, which allows C++ code to refer to Lua + /// variables. + /// + class LuaRef + { + public: + /// + /// + /// + LuaRef(lua_State* L, int i); + + /// + /// + /// + ~LuaRef(); + + /// + /// + /// + void unref(); + + /// + /// Push value onto the stack. + /// + void push(); + + private: + /// + /// + /// + lua_State* const mL; + + /// + /// + /// + int mIndex; + + }; + + } // namespace Lua +} // namespace JinEngine + +#endif // __JIN_COMMON_REFERENCE_H
\ No newline at end of file diff --git a/src/libjin-lua/common/je_lua_runtime.cpp b/src/libjin-lua/common/je_lua_runtime.cpp new file mode 100644 index 0000000..fb665f1 --- /dev/null +++ b/src/libjin-lua/common/je_lua_runtime.cpp @@ -0,0 +1,215 @@ +#include "libjin/jin.h" + +#include "je_lua.h" +#include "je_lua_object.h" + +using namespace std; +using namespace JinEngine::Math; + +namespace JinEngine +{ + namespace Lua + { + + static const char* Jin_Lua_Objects_Table = "Jin_Objects_Table"; + + static const char* Jin_Lua_Reference_Table = "Jin_Reference_Table"; + + static const char* Jin_Lua_Modules_Table = "Jin_Modules_Table"; + + using DepsMap = LuaObject::DepsMap; + + LuaObject* luax_newinstance(lua_State* L, const char* type, Shared* shared) + { + LuaObject* obj = static_cast<LuaObject*>(luax_newinstance(L, type, sizeof(LuaObject))); + obj->state = L; + obj->type = type; + obj->bind(shared); + // Add to objects_table, objects_table[shared] = luaObj + luax_getobjectstable(L); + luax_pushlightuserdata(L, shared); + luax_pushvalue(L, -3); + luax_settable(L, -3); + luax_pop(L, 1); // Pop objects table. + return obj; + } + + LuaObject* luax_checkobject(lua_State* L, int idx, const char* type) + { + return (LuaObject*)luax_checktype(L, idx, type); + } + + LuaObject* luax_copyinstance(lua_State* to, LuaObject* src) + { + if (to == src->state) + return nullptr; + // Copy dependencies. + DepsMap& srcDeps = *src->dependencies; + for (DepsMap::iterator it = srcDeps.begin(); it != srcDeps.end(); ++it) + { + LuaObject* obj = it->second; + Shared* shr = obj->shared; + // Try get lua object. + luax_getobject(src->state, obj); + LuaObject* luaObj = (LuaObject*)luax_checktype(src->state, -1, obj->getObjectType()); + luax_pop(src->state, 1); // Pop lua object. + luax_copyinstance(to, luaObj); + luax_pop(to, 1); // Pop reference object. + } + Shared* shr = src->getShared(); + LuaObject* obj = luax_newinstance(to, src->getObjectType(), shr); + (*obj->dependencies) = (*src->dependencies); + // Add to objects_table. + luax_getobjectstable(to); + luax_pushlightuserdata(to, shr); + luax_pushvalue(to, -3); + luax_settable(to, -3); + luax_pop(to, 1); // Pop objects table. + // Set dependencies. + DepsMap& deps = *obj->dependencies; + DepsMap::iterator it = deps.begin(); + for (; it != deps.end(); ++it) + { + LuaObject* dep = it->second; + luax_addreference(to, src, dep); + } + return obj; + } + + int luax_getobject(lua_State* L, LuaObject* obj) + { + luax_getobjectstable(L); + luax_pushlightuserdata(L, obj->shared); + luax_gettable(L, -2); + luax_remove(L, -2); // Remove objects table on stack. + return 1; + } + + void luax_removeobject(lua_State* L, LuaObject* obj) + { + luax_getobjectstable(L); + luax_pushlightuserdata(L, obj->shared); + luax_pushnil(L); + luax_settable(L, -3); + luax_pop(L, 1); + } + + int luax_getobjectstable(lua_State* L) + { + luax_getfield(L, LUA_REGISTRYINDEX, Jin_Lua_Objects_Table); + // If no such table, add one. + if (luax_isnil(L, -1) || !luax_istable(L, -1)) + { + luax_pop(L, 1); + luax_newtable(L); + + // metatable + luax_newtable(L); + // weak table + luax_pushliteral(L, "v"); + luax_setfield(L, -2, "__mode"); + // setmetatable(newtable, metatable) + luax_setmetatable(L, -2); + + luax_pushvalue(L, -1); + luax_setfield(L, LUA_REGISTRYINDEX, Jin_Lua_Objects_Table); + } + return 1; + } + + int luax_getmodulestable(lua_State* L) + { + luax_getfield(L, LUA_REGISTRYINDEX, Jin_Lua_Modules_Table); + // If no such table, add one. + if (luax_isnil(L, -1) || !luax_istable(L, -1)) + { + luax_pop(L, 1); + luax_newtable(L); + + // metatable + luax_newtable(L); + // weak table + luax_pushliteral(L, "v"); + luax_setfield(L, -2, "__mode"); + // setmetatable(newtable, metatable) + luax_setmetatable(L, -2); + + luax_pushvalue(L, -1); + luax_setfield(L, LUA_REGISTRYINDEX, Jin_Lua_Modules_Table); + } + return 1; + } + + int luax_getreferencestable(lua_State* L) + { + luax_getfield(L, LUA_REGISTRYINDEX, Jin_Lua_Reference_Table); + // If no such table, add one. + if (luax_isnil(L, -1) || !luax_istable(L, -1)) + { + luax_pop(L, 1); + luax_newtable(L); + luax_pushvalue(L, -1); + luax_setfield(L, LUA_REGISTRYINDEX, Jin_Lua_Reference_Table); + } + return 1; + } + + void luax_getreference(lua_State* L, LuaObject* obj) + { + luax_getreferencestable(L); + luax_pushlightuserdata(L, obj->shared); + luax_gettable(L, -2); + luax_remove(L, -2); + } + + bool luax_addreference(lua_State* L, LuaObject* obj, LuaObject* dep) + { + luax_getreference(L, obj); + // If no dependencies table, add one. + if (luax_isnil(L, -1)) + { + luax_pop(L, 1); + luax_getreferencestable(L); + luax_newtable(L); + luax_pushlightuserdata(L, obj->shared); + luax_pushvalue(L, -2); + luax_settable(L, -4); + luax_remove(L, -2); // Remove references table. + } + luax_pushlightuserdata(L, dep->shared); + luax_getobject(L, dep); + if (luax_isnil(L, -1)) + { + luax_pop(L, 3); // Pop nil, dep, reftbl. + return false; + } + luax_settable(L, -3); + luax_pop(L, 1); + return true; + } + + void luax_removereference(lua_State* L, LuaObject* obj) + { + luax_getreferencestable(L); + luax_pushlightuserdata(L, obj->shared); + luax_pushnil(L); + luax_settable(L, -3); + luax_pop(L, 1); + } + + void luax_removereference(lua_State* L, LuaObject* obj, LuaObject* dep) + { + luax_getreference(L, obj); + if (luax_isnil(L, -1)) + { + luax_pop(L, 1); + return; + } + luax_pushlightuserdata(L, dep->shared); + luax_pushnil(L); + luax_settable(L, -3); + luax_pop(L, 1); + } + + } +}
\ No newline at end of file diff --git a/src/libjin-lua/common/je_lua_shared.cpp b/src/libjin-lua/common/je_lua_shared.cpp new file mode 100644 index 0000000..fce6d81 --- /dev/null +++ b/src/libjin-lua/common/je_lua_shared.cpp @@ -0,0 +1,11 @@ +#include "je_lua.h" +#include "je_lua_shared.hpp" +#include "libjin/jin.h" + +namespace JinEngine +{ + namespace Lua + { + + } +}
\ No newline at end of file diff --git a/src/libjin-lua/common/je_lua_shared.hpp b/src/libjin-lua/common/je_lua_shared.hpp new file mode 100644 index 0000000..6a58ab3 --- /dev/null +++ b/src/libjin-lua/common/je_lua_shared.hpp @@ -0,0 +1,84 @@ +#ifndef __JE_LUA_SHARED_H__ +#define __JE_LUA_SHARED_H__ + +#include <map> +#include <vector> +#include <functional> + +#include "libjin/jin.h" + +namespace JinEngine +{ + namespace Lua + { + + class LuaObject; + + /// + /// Thread shared object wrapper. + /// + class Shared + { + public: + Shared(Object* obj) + : mCount(0) + , mObject(obj) + { + } + + inline Object* operator->() + { + return static_cast<Object*>(mObject); + } + + inline Object* getObject() + { + return static_cast<Object*>(mObject); + } + + template<class T> + inline T* getObject() + { + return static_cast<T*>(mObject); + } + + private: + friend class LuaObject; + + // Disable copy. + Shared(const Shared& shared); + + /// + /// Sharedֻڶ + /// + ~Shared() + { + delete mObject; + } + + /// + /// ͬһ̵߳lua_StateУLuaObjectEngineObjectӦһһӦLuaObject(lua runtime)ü + /// ͻաEngine-sideüΪά̵ͬ߳lua_StateͬһEngineObjectÿLuaObjectһ + /// Sharedʱһüͬһ߳УһEngineObjectֻһLuaObjectnew + /// instanceУômCountͱEngineObjectĹ߳ + /// + inline void Shared::retain() + { + ++mCount; + } + + inline void Shared::release() + { + if (--mCount <= 0) + delete this; + } + + Object* mObject; + int mCount; + + }; + + } // namespace Lua +} // namespace JinEngine + +#endif
\ No newline at end of file |