aboutsummaryrefslogtreecommitdiff
path: root/src/libjin-lua/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/libjin-lua/common')
-rw-r--r--src/libjin-lua/common/je_lua.h83
-rw-r--r--src/libjin-lua/common/je_lua_callback.cpp43
-rw-r--r--src/libjin-lua/common/je_lua_callback.h66
-rw-r--r--src/libjin-lua/common/je_lua_common.h9
-rw-r--r--src/libjin-lua/common/je_lua_constant.h14
-rw-r--r--src/libjin-lua/common/je_lua_error.h30
-rw-r--r--src/libjin-lua/common/je_lua_function.cpp0
-rw-r--r--src/libjin-lua/common/je_lua_function.h6
-rw-r--r--src/libjin-lua/common/je_lua_object.cpp112
-rw-r--r--src/libjin-lua/common/je_lua_object.h69
-rw-r--r--src/libjin-lua/common/je_lua_port.h8
-rw-r--r--src/libjin-lua/common/je_lua_reference.cpp42
-rw-r--r--src/libjin-lua/common/je_lua_reference.h54
-rw-r--r--src/libjin-lua/common/je_lua_runtime.cpp215
-rw-r--r--src/libjin-lua/common/je_lua_shared.cpp11
-rw-r--r--src/libjin-lua/common/je_lua_shared.hpp84
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ֻһLuaObject󶨣new
+ /// 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