From 8d8c4ff1664625e7428d0d31cd798d9321680cb2 Mon Sep 17 00:00:00 2001 From: chai Date: Thu, 14 Mar 2019 09:08:07 +0800 Subject: *luax --- Source/3rdParty/Luax/lua.hpp | 11 - Source/3rdParty/Luax/luax.h | 49 +---- Source/3rdParty/Luax/luax_class.cpp | 68 +------ Source/3rdParty/Luax/luax_class.h | 145 ------------- Source/3rdParty/Luax/luax_class.hpp | 150 ++++++++++++++ Source/3rdParty/Luax/luax_class.inl | 292 +++++++++++++++++++++------ Source/3rdParty/Luax/luax_config.h | 7 +- Source/3rdParty/Luax/luax_memberref.h | 2 +- Source/3rdParty/Luax/luax_module.cpp | 8 - Source/3rdParty/Luax/luax_module.h | 12 -- Source/3rdParty/Luax/luax_namespace.cpp | 8 + Source/3rdParty/Luax/luax_namespace.h | 11 + Source/3rdParty/Luax/luax_ref.cpp | 69 +++++++ Source/3rdParty/Luax/luax_ref.h | 24 ++- Source/3rdParty/Luax/luax_runtime.h | 5 +- Source/3rdParty/Luax/luax_state.h | 8 +- Source/3rdParty/Luax/luax_state.inl | 182 ++++++++++------- Source/Asura.Engine/Graphics/Port/Shader.cpp | 2 +- Source/Asura.Engine/Scripting/Object.h | 23 +++ Source/Asura.Engine/Scripting/Portable.h | 8 +- Source/Samples/LuaxTest/main.cpp | 69 +++++-- 21 files changed, 703 insertions(+), 450 deletions(-) delete mode 100644 Source/3rdParty/Luax/lua.hpp delete mode 100644 Source/3rdParty/Luax/luax_class.h create mode 100644 Source/3rdParty/Luax/luax_class.hpp delete mode 100644 Source/3rdParty/Luax/luax_module.cpp delete mode 100644 Source/3rdParty/Luax/luax_module.h create mode 100644 Source/3rdParty/Luax/luax_namespace.cpp create mode 100644 Source/3rdParty/Luax/luax_namespace.h create mode 100644 Source/Asura.Engine/Scripting/Object.h (limited to 'Source') diff --git a/Source/3rdParty/Luax/lua.hpp b/Source/3rdParty/Luax/lua.hpp deleted file mode 100644 index ab14a19..0000000 --- a/Source/3rdParty/Luax/lua.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __LUAX_LUA_HPP__ -#define __LUAX_LUA_HPP__ - -// Include lua first - -extern "C" { -#include "lua51/lua.h" -#include "lua51/lualib.h" -#include "lua51/lauxlib.h" -} -#endif \ No newline at end of file diff --git a/Source/3rdParty/Luax/luax.h b/Source/3rdParty/Luax/luax.h index f43fb26..58ea2c8 100644 --- a/Source/3rdParty/Luax/luax.h +++ b/Source/3rdParty/Luax/luax.h @@ -1,52 +1,13 @@ #ifndef __LUAX_H__ #define __LUAX_H__ -// 从moai-core中抽离出来 - -// include lua.hpp before this #include "luax_state.h" -#include "luax_ref.h" -#include "luax_class.h" -#include "luax_module.h" #include "luax_runtime.h" +#include "luax_namespace.h" +#include "luax_ref.h" #include "luax_reftable.h" +#include "luax_class.hpp" +#include "luax_class.inl" +#include "luax_state.inl" -// luax 扩展的lua主要概念有 -// * modules -// * class -// * -/* - -GetClassName -GetClass -New -Extend -GetInterfaceTable - - - -__index -__newIndex -__gc -__mode -__tostring - - - -数据成员不需要允许访问(赋值和得到值),通过函数实现,即__index设置为元表 - -名称空间通过表实现 - -通过upvalue实现调用者的访问,而不需要通过传入self,比如通过BaseClass.Extend("SubClass")访问BaseClass,区分不同的base class, -把BaseClass设为Extend的upvalue,在cfunction通过lua_upvalueindex宏里访问upvalue。 - -之所以能通过.调用函数是因为元表,元表可以给userdata和table作为元表,所以userdata可以调用,但实际上不需要这样。 - -interface table -> member table -member table -> ref table -ref table -> userdata 保存了对每个其他类型的引用和引用计数(用hLuaUserdata作为key),计数是为了debug - -class table 是类型的本体(工厂),有New、Extend、GetClassName方法 - -*/ #endif \ No newline at end of file diff --git a/Source/3rdParty/Luax/luax_class.cpp b/Source/3rdParty/Luax/luax_class.cpp index 52cf6b7..3cb1f8a 100644 --- a/Source/3rdParty/Luax/luax_class.cpp +++ b/Source/3rdParty/Luax/luax_class.cpp @@ -1,72 +1,6 @@ -#include "luax_state.h" -#include "luax_class.h" -#include "luax_runtime.h" + namespace Luax { - LuaxClass::LuaxClass() - : mRC(1) // 构造时默认有一个引用 - , mSafer(false) - { - } - - LuaxClass::~LuaxClass() - { - assert(mSafer); - } - - void LuaxClass::Retain() - { - ++mRC; - } - - void LuaxClass::Release() - { - if (--mRC <= 0) - { - mSafer = true; // 打开析构safer - delete this; - } - } - - bool LuaxClass::PushLuaUserdata(LuaxState& state) - { - return true; - } - - void LuaxClass::BindFactoryToLua(LuaxState& state) - { - //assert(!mUserdata); - - // - state.PushPtrUserData(this); - - lua_newtable(state); // ref table - lua_newtable(state); // member table - - } - - void LuaxClass::BindSingletonToLua(LuaxState& state) - { - - } - - //-------------------------------------------------------------------------------------------------------------- - - /// - /// 释放工厂创建的实例 - /// - int LuaxClass::l_GC(lua_State* L) - { - LUAX_SETUP(L, "U"); - - return 0; - } - - int LuaxClass::l_ToString(lua_State* L) - { - return 0; - } - } \ No newline at end of file diff --git a/Source/3rdParty/Luax/luax_class.h b/Source/3rdParty/Luax/luax_class.h deleted file mode 100644 index bde9990..0000000 --- a/Source/3rdParty/Luax/luax_class.h +++ /dev/null @@ -1,145 +0,0 @@ -#ifndef __LUAX_CLASS_H__ -#define __LUAX_CLASS_H__ - -#include - -#include "lua.hpp" -#include "luax_config.h" -#include "luax_state.h" -#include "luax_runtime.h" - -namespace Luax -{ - -#define LUAX_DECL_METHOD(mtd) static int mtd(lua_State*) - - /// - /// RegisterLuaxClass 注册类的方法和成员,比如枚举、常量等到class table - /// LuaxRegisterInterface 注册接口方法到interface table - /// LuaxGetFactoryName 获得工厂的类名,同时用来避免注册时错误注册为了singleton,通过编译时报错避免 - /// -#define LUAX_DECL_FACTORY(type) \ - static void RegisterLuaxClass(LuaxState&);\ - static void RegisterLuaxInterface(LuaxState&);\ - static const char* GetLuaxFactoryName() { return #type; };\ - static const char* GetLuaxClassName() { return #type; };\ - static bool IsLuaxClassSingleton() { return false; }; - - - /// - /// RegisterLuaxClass 注册类的方法和成员,比如枚举、常量等到class table - /// LuaxGetSingletonName 获得单例的类名 - /// -#define LUAX_DECL_SINGLETON(type) \ - static void RegisterLuaxClass(LuaxState&); \ - static const char* GetLuaxSingletonName() { return #type; }; \ - static const char* GetLuaxClassName() { return #type; }; \ - static bool IsLuaxClassSingleton() { return true; }; - - - /// - /// 需要暴露给lua的class需要继承此类。通过lua管理的实例要确保引用计数的正确性,在多个线程中需要确定不会误释放。 - /// - class LuaxClass - { - public: - - void Retain(); - void Release(); - - protected: - - LuaxClass(); - virtual ~LuaxClass(); - - /// - /// 将userdata push到栈顶,如果没有初始化mUserdata,初始化设置好元表并把初始化好的userdata留在栈顶。 - /// - bool PushLuaUserdata(LuaxState& state); - - //------------------------------------------------------------------------------------------------------------ - - /// - /// 对类的reftable的管理 - /// - void Ref(); - - private: - - friend class LuaxState; - - template static void RegisterLuaxClass(LuaxState& state); - template static void RegisterLuaxFactoryClass(LuaxState& state); - template static void RegisterLuaxInterface(LuaxState& state); - template static void RegisterLuaxSingletonClass(LuaxState& state); - - /// - /// 屏蔽取地址运算符,如果需要地址,只能通过在堆上创建实例得到。在栈上和静态区的变量不能取地址。保证引用计数的准确。如 - /// 果需要穿引用,使用引用传递而不是传递地址。 - /// - void* operator &(); - - /// - /// 绑定到state,如果本类是工厂 - /// - void BindFactoryToLua(LuaxState& state); - - /// - /// 绑定到state,如果本类是单例 - /// - void BindSingletonToLua(LuaxState& state); - - //------------------------------------------------------------------------------------------------------------ - - LuaxStrongRef mInterfaceTable; // interface table - LuaxStrongRef mClassTable; // class table - - /// - /// 引用计数,用来处理线程间共享 - /// - int mRC; - - /// - /// 确保析构函数只能通过Release调用的safer,这样只要继承了LuaxClass的类,如果使用delete直接析构,就会报错 - /// - bool mSafer; - - public: - - //------------------------------------------------------------------------------------------------------------ - // 公共内容 - - template LUAX_DECL_METHOD(l_GetClassName); - template LUAX_DECL_METHOD(l_GetClassName2); - - LUAX_DECL_METHOD(l_ToString); // __tostring - - //------------------------------------------------------------------------------------------------------------ - // 工厂类相关 - - LUAX_DECL_METHOD(l_GC); // __gc - - //------------------------------------------------------------------------------------------------------------ - // 单例类相关 - - }; - - /// - /// 在成员方法里创建LuaxState并对参数进行检查。 - /// -#define LUAX_SETUP(L, params) \ - LuaxRuntime& runtime = LuaxRuntime::Get(); \ - LuaxState& state = runtime[L].state; \ - if(!state.CheckParams(1, params)) return 0 - -#define LUAX_STATE(L) \ - LuaxState& state = LuaxRuntime::Get().GetLuaxState(L) - -#define LUAX_RUNTIME() \ - LuaxRuntime& runtime = LuaxRuntime::Get() - -#include "luax_class.inl" - -} - -#endif \ No newline at end of file diff --git a/Source/3rdParty/Luax/luax_class.hpp b/Source/3rdParty/Luax/luax_class.hpp new file mode 100644 index 0000000..6ce8d19 --- /dev/null +++ b/Source/3rdParty/Luax/luax_class.hpp @@ -0,0 +1,150 @@ +#ifndef __LUAX_CLASS_H__ +#define __LUAX_CLASS_H__ + +#include + +#include "luax_config.h" +#include "luax_ref.h" + +namespace Luax +{ + +#define LUAX_DECL_METHOD(mtd) static int mtd(lua_State* L) + + /// + /// RegisterLuaxClass 注册类的方法和成员,比如枚举、常量等到class table + /// LuaxRegisterInterface 注册接口方法到interface table + /// LuaxGetFactoryName 获得工厂的类名,同时用来避免注册时错误注册为了singleton,通过编译时报错避免 + /// +#define LUAX_DECL_FACTORY(type) \ + static void RegisterLuaxClass(LuaxState&);\ + static void RegisterLuaxInterface(LuaxState&);\ + static const char* GetLuaxFactoryName() { return #type; };\ + static const char* GetLuaxClassName() { return #type; };\ + static bool IsLuaxClassSingleton() { return false; }; + + /// + /// RegisterLuaxClass 注册类的方法和成员,比如枚举、常量等到class table + /// LuaxGetSingletonName 获得单例的类名 + /// +#define LUAX_DECL_SINGLETON(type) \ + static void RegisterLuaxClass(LuaxState&); \ + static const char* GetLuaxSingletonName() { return #type; }; \ + static const char* GetLuaxClassName() { return #type; }; \ + static bool IsLuaxClassSingleton() { return true; }; + + /// + /// 需要暴露给lua的class需要继承此类。通过lua管理的实例要确保引用计数的正确性,在多个线程中需要确定不会误释放。 + /// + template + class LuaxClass + { + public: + + void Retain(); + void Release(); + + protected: + + LuaxClass(); + virtual ~LuaxClass(); + + /// + /// 将userdata push到栈顶,如果没有初始化mUserdata,初始化设置好元表并把初始化好的userdata留在栈顶。并添加一个引用。 + /// + bool PushLuaUserdata(LuaxState& state); + + //------------------------------------------------------------------------------------------------------------ + + /// + /// 对类的reftable的管理 + /// + void Ref(); + + private: + + friend class LuaxState; + + static void RegisterLuaxClass(LuaxState& state); + static void RegisterLuaxFactoryClass(LuaxState& state); + static void RegisterLuaxSingletonClass(LuaxState& state); + static void RegisterLuaxInterface(LuaxState& state); + + static void SetInterfaceTableRef(LuaxState& state, int idx); + static void SetClassTableRef(LuaxState& state, int idx); + + static void PushInterfaceTable(LuaxState& state); + static void PushClassTable(LuaxState& state); + static void PushRefTable(LuaxState& state); + + /// + /// 屏蔽取地址运算符,如果需要地址,只能通过在堆上创建实例得到。在栈上和静态区的变量不能取地址。保证引用计数的准确。如 + /// 果需要穿引用,使用引用传递而不是传递地址。 + /// + void* operator &(); + + /// + /// 创建userdata,绑定实例到state,如果本类是工厂 + /// + void BindToLua(LuaxState& state); + + //------------------------------------------------------------------------------------------------------------ + + /// + /// 所有LuaxClass类型的实例共享的内容 + /// + static LuaxStrongRef mInterfaceTable; // interface table + static LuaxStrongRef mClassTable; // class table + static LuaxStrongRef mRefTable; // 单例 + + /// + /// 通过userdata可以拿到ref table\member table\interface table + /// + LuaxWeakRef mUserdata; + + /// + /// 引用计数,用来处理线程间共享 + /// + int mRC; + + /// + /// 确保析构函数只能通过Release调用的safer,这样只要继承了LuaxClass的类,如果使用delete直接析构,就会报错 + /// + bool mSafer; + + public: + + //------------------------------------------------------------------------------------------------------------ + // 公共内容 + + LUAX_DECL_METHOD( l_GetClassName ); + LUAX_DECL_METHOD( l_GetInterfaceTable ); + LUAX_DECL_METHOD(l_ToString); + + //------------------------------------------------------------------------------------------------------------ + // 工厂类相关 + + LUAX_DECL_METHOD( l_ExtendFactory ); + LUAX_DECL_METHOD( l_GC ); + + //------------------------------------------------------------------------------------------------------------ + // 单例类相关 + + LUAX_DECL_METHOD( l_ExtendSingleton ); + + }; + + /// + /// 在成员方法里创建LuaxState并对参数进行检查。 + /// +#define LUAX_SETUP(L, params) \ + LuaxRuntime& runtime = LuaxRuntime::Get(); \ + LuaxState& state = runtime[L].state; \ + if(!state.CheckParams(1, params)) return 0 + +#define LUAX_STATE(L) \ + LuaxState& state = LuaxRuntime::Get().GetLuaxState(L) + +} + +#endif \ No newline at end of file diff --git a/Source/3rdParty/Luax/luax_class.inl b/Source/3rdParty/Luax/luax_class.inl index fd5c1d9..895152e 100644 --- a/Source/3rdParty/Luax/luax_class.inl +++ b/Source/3rdParty/Luax/luax_class.inl @@ -1,75 +1,249 @@ +namespace Luax +{ -//---------------------------------------------------------------------------------------------------------------- -// 接口 + //---------------------------------------------------------------------------------------------------------------- + // 接口 -/// -/// 对不同类型,通过调用GetLuaClassName获得类型名 -/// -template -int LuaxClass::l_GetClassName(lua_State* L) -{ - LUAX_SETUP(L, "*"); + /// + /// 对不同类型,通过调用GetLuaClassName获得类型名 + /// + template + int LuaxClass::l_GetClassName(lua_State* L) + { + LUAX_SETUP(L, "*"); - cc8* type = T::GetLuaxClassName(); - state.Push(type); - return 1; -} + cc8* type = T::GetLuaxClassName(); + state.Push(type); + return 1; + } -//---------------------------------------------------------------------------------------------------------------- + //---------------------------------------------------------------------------------------------------------------- -/// -/// 注册工厂和单例共有的类成员 -/// -template -void LuaxClass::RegisterLuaxClass(LuaxState& state) -{ - luaL_Reg regTable[] = { - { "GetClassName", l_GetClassName }, - { NULL, NULL } - }; + /// + /// 注册工厂和单例共有的类成员 + /// + template + void LuaxClass::RegisterLuaxClass(LuaxState& state) + { + luaL_Reg regTable[] = { + { "GetClassName", l_GetClassName }, + { NULL, NULL } + }; - state.Register(regTable); -} + state.Register(regTable); + } -/// -/// 工厂类的成员,注册在class table -/// -template -void LuaxClass::RegisterLuaxFactoryClass(LuaxState& state) -{ - luaL_Reg regTable[] = { - { NULL, NULL } - }; + /// + /// 工厂类的成员,注册在class table + /// + template + void LuaxClass::RegisterLuaxFactoryClass(LuaxState& state) + { + luaL_Reg regTable[] = { + { "GetInterfaceTable", l_GetInterfaceTable }, + { NULL, NULL } + }; - state.Register(regTable); -} + state.Register(regTable); + } -/// -/// 工厂实例的成员,注册在interface table -/// -template -void LuaxClass::RegisterLuaxInterface(LuaxState& state) -{ - luaL_Reg regTable[] = { - { "__gc", l_GC }, - { NULL, NULL } - }; + /// + /// 工厂实例的成员,注册在interface table + /// + template + void LuaxClass::RegisterLuaxInterface(LuaxState& state) + { + luaL_Reg regTable[] = { + { "__gc", l_GC }, + { NULL, NULL } + }; - state.Register(regTable); -} + state.Register(regTable); + } -/// -/// 单例类的成员,注册在class table -/// -template -void LuaxClass::RegisterLuaxSingletonClass(LuaxState& state) -{ - luaL_Reg regTable[] = { - {NULL, NULL} - }; + /// + /// 单例类的成员,注册在class table + /// + template + void LuaxClass::RegisterLuaxSingletonClass(LuaxState& state) + { + luaL_Reg regTable[] = { + { NULL, NULL } + }; + + state.Register(regTable); + } + + template + void LuaxClass::PushInterfaceTable(LuaxState& state) + { + assert(mInterfaceTable); + + mInterfaceTable.PushRef(state); + } + + template + void LuaxClass::PushClassTable(LuaxState& state) + { + assert(mClassTable); + + mClassTable.PushRef(state); + } + + template + void LuaxClass::PushRefTable(LuaxState& state) + { + assert(mRefTable); + + mRefTable.Push(state); + } + + template + void LuaxClass::SetInterfaceTableRef(LuaxState& state, int idx) + { + mInterfaceTable.SetRef(state, idx); + } + + template + void LuaxClass::SetClassTableRef(LuaxState& state, int idx) + { + mClassTable.SetRef(state, idx); + } + + template + LuaxClass::LuaxClass() + : mRC(1) // 构造时默认有一个引用 + , mSafer(false) + { + } + + template + LuaxClass::~LuaxClass() + { + assert(mSafer); + } + + template + void LuaxClass::Retain() + { + ++mRC; + } + + template + void LuaxClass::Release() + { + if (--mRC <= 0) + { + mSafer = true; // 打开析构safer + delete this; + } + } + + template + bool LuaxClass::PushLuaUserdata(LuaxState& state) + { + if (!mUserdata) + { + BindToLua(state); + return true; + } + return mUserdata.PushRef(state); + } + + template + void LuaxClass::BindToLua(LuaxState& state) + { + assert(!mUserdata); + + // 创建userdata并留在栈顶 + state.PushPtrUserData(this); + + // 工厂 + if (!T::IsLuaxClassSingleton()) + { + lua_newtable(state); // ref table + lua_newtable(state); // member table + LuaxClass::PushInterfaceTable(state); // interface table + + // stack: + // -1: interface table + // -2: member table + // -3: ref table + // -4: userdata + + int top = state.GetTop(); + int memberTable = top - 1; + int refTable = top - 2; + + // ref table 注册 __gc和__tostring + lua_pushcfunction(state, LuaxClass::l_GC); + lua_setfield(state, refTable, "__gc"); + + lua_pushcfunction(state, LuaxClass::l_ToString); + lua_setfield(state, refTable, "__tostring"); + + // member table 设为 ref table 的 __index 和 __newindex + lua_pushvalue(state, memberTable); + lua_setfield(state, refTable, "__index"); + + lua_pushvalue(state, memberTable); + lua_setfield(state, refTable, "__newindex"); + + // 设置元表 + lua_setmetatable(state, -2); // interface is meta of member + lua_setmetatable(state, -2); // member is meta of ref + lua_setmetatable(state, -2); // ref is meta of userdata + } + + // 设置一个userdata的弱引用,方便通过native指针返回lua对象 + mUserdata.SetRef(state, -1); + assert(mUserdata); + + if (T::IsLuaxClassSingleton()) + { + + } + } + + //-------------------------------------------------------------------------------------------------------------- + + /// + /// 释放工厂创建的实例 + /// + template + int LuaxClass::l_GC(lua_State* L) + { + LUAX_SETUP(L, "U"); + + return 0; + } + + template + int LuaxClass::l_ToString(lua_State* L) + { + return 0; + } + + template + int LuaxClass::l_ExtendFactory(lua_State* L) + { + return 0; + } + + template + int LuaxClass::l_GetInterfaceTable(lua_State* L) + { + LUAX_STATE(L); + assert(mInterfaceTable); + mInterfaceTable.PushRef(state); + return 0; + } + + template LuaxStrongRef LuaxClass::mInterfaceTable; // interface table + template LuaxStrongRef LuaxClass::mClassTable; // class table + template LuaxStrongRef LuaxClass::mRefTable; // 单例 - state.Register(regTable); } \ No newline at end of file diff --git a/Source/3rdParty/Luax/luax_config.h b/Source/3rdParty/Luax/luax_config.h index ea623a9..3401336 100644 --- a/Source/3rdParty/Luax/luax_config.h +++ b/Source/3rdParty/Luax/luax_config.h @@ -2,7 +2,12 @@ #define __LUAX_TYPE_H__ #include -#include "lua.hpp" + +extern "C" { +#include "lua51/lua.h" +#include "lua51/lualib.h" +#include "lua51/lauxlib.h" +} #include diff --git a/Source/3rdParty/Luax/luax_memberref.h b/Source/3rdParty/Luax/luax_memberref.h index 052c53e..baebd06 100644 --- a/Source/3rdParty/Luax/luax_memberref.h +++ b/Source/3rdParty/Luax/luax_memberref.h @@ -5,7 +5,7 @@ namespace Luax { /// - /// LuaxClass的成员引用,保证正确释放,是强引用。 + /// LuaxClass的成员引用,存在interface table里,保证正确释放,是强引用。 /// class LuaxMemberRef { diff --git a/Source/3rdParty/Luax/luax_module.cpp b/Source/3rdParty/Luax/luax_module.cpp deleted file mode 100644 index 94de1a6..0000000 --- a/Source/3rdParty/Luax/luax_module.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "luax_module.h" - -namespace Luax -{ - - - -} \ No newline at end of file diff --git a/Source/3rdParty/Luax/luax_module.h b/Source/3rdParty/Luax/luax_module.h deleted file mode 100644 index 96d954c..0000000 --- a/Source/3rdParty/Luax/luax_module.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __LUAX_MODULE_H__ -#define __LUAX_MODULE_H__ - -namespace Luax -{ - -#define LUAX_BEGIN_MODULE(MDL) -#define LUAX_END_MODULE(MDL) - -} - -#endif \ No newline at end of file diff --git a/Source/3rdParty/Luax/luax_namespace.cpp b/Source/3rdParty/Luax/luax_namespace.cpp new file mode 100644 index 0000000..a27d44a --- /dev/null +++ b/Source/3rdParty/Luax/luax_namespace.cpp @@ -0,0 +1,8 @@ +#include "luax_namespace.h" + +namespace Luax +{ + + + +} \ No newline at end of file diff --git a/Source/3rdParty/Luax/luax_namespace.h b/Source/3rdParty/Luax/luax_namespace.h new file mode 100644 index 0000000..c9b9a23 --- /dev/null +++ b/Source/3rdParty/Luax/luax_namespace.h @@ -0,0 +1,11 @@ +#ifndef __LUAX_NAMESPACE_H__ +#define __LUAX_NAMESPACE_H__ + +namespace Luax +{ + + + +} + +#endif \ No newline at end of file diff --git a/Source/3rdParty/Luax/luax_ref.cpp b/Source/3rdParty/Luax/luax_ref.cpp index e69de29..544861d 100644 --- a/Source/3rdParty/Luax/luax_ref.cpp +++ b/Source/3rdParty/Luax/luax_ref.cpp @@ -0,0 +1,69 @@ +#include "luax_runtime.h" +#include "luax_ref.h" + +namespace Luax +{ + + LuaxRef::LuaxRef(int mode) + : mRefID(LUA_NOREF) + , mMode(mode) + { + } + + LuaxRef::~LuaxRef() + { + } + + LuaxRef::operator bool() + { + return (mRefID != LUA_NOREF); + } + + bool LuaxRef::PushRef(LuaxState& state) + { + assert(mRefID != LUA_NOREF); + + LuaxRuntime& runtime = LuaxRuntime::Get(); + + if (mMode == STRONG_REF) + { + LuaxRefTable& table = runtime[state.GetHandle()].strongRefTable; + table.PushRef(state, mRefID); + } + else if (mMode == WEAK_REF) + { + LuaxRefTable& table = runtime[state.GetHandle()].weakRefTable; + table.PushRef(state, mRefID); + } + else + { + return false; + } + } + + void LuaxRef::SetRef(LuaxState& state, int idx) + { + LuaxRuntime& runtime = LuaxRuntime::Get(); + if (mMode == STRONG_REF) + { + LuaxRefTable& table = runtime[state.GetHandle()].strongRefTable; + mRefID = table.Ref(state, idx); + } + else if (mMode == WEAK_REF) + { + LuaxRefTable& table = runtime[state.GetHandle()].weakRefTable; + mRefID = table.Ref(state, idx); + } + } + + LuaxStrongRef::LuaxStrongRef() + : LuaxRef(STRONG_REF) + { + } + + LuaxWeakRef::LuaxWeakRef() + : LuaxRef(WEAK_REF) + { + } + +} diff --git a/Source/3rdParty/Luax/luax_ref.h b/Source/3rdParty/Luax/luax_ref.h index 759a314..7b484e9 100644 --- a/Source/3rdParty/Luax/luax_ref.h +++ b/Source/3rdParty/Luax/luax_ref.h @@ -1,6 +1,9 @@ #ifndef __LUAX_REF_H__ #define __LUAX_REF_H__ +#include "luax_config.h" +#include "luax_state.h" + namespace Luax { @@ -13,13 +16,24 @@ namespace Luax enum { - STRONG, - WEAK + STRONG_REF, + WEAK_REF }; + + LuaxRef(int mode = STRONG_REF); + virtual ~LuaxRef(); + + operator bool(); + + void SetRef(LuaxState& state, int idx); + bool PushRef(LuaxState& state); + + int GetRefID(); private: - int mRefID; // = luaL_ref + int mRefID; // luaL_ref + int mMode; // strong or weak }; @@ -28,6 +42,8 @@ namespace Luax /// class LuaxStrongRef: public LuaxRef { + public: + LuaxStrongRef(); }; @@ -36,6 +52,8 @@ namespace Luax /// class LuaxWeakRef : public LuaxRef { + public: + LuaxWeakRef(); }; diff --git a/Source/3rdParty/Luax/luax_runtime.h b/Source/3rdParty/Luax/luax_runtime.h index 2414c2e..fe70580 100644 --- a/Source/3rdParty/Luax/luax_runtime.h +++ b/Source/3rdParty/Luax/luax_runtime.h @@ -60,12 +60,15 @@ namespace Luax static LuaxRuntime* mRuntime; /// - /// 从lua_state找到context + /// 从lua_State handle到context的映射 /// std::map mContexts; }; +#define LUAX_RUNTIME() \ + LuaxRuntime& runtime = LuaxRuntime::Get() + } #endif \ No newline at end of file diff --git a/Source/3rdParty/Luax/luax_state.h b/Source/3rdParty/Luax/luax_state.h index 6a688b6..2b143f8 100644 --- a/Source/3rdParty/Luax/luax_state.h +++ b/Source/3rdParty/Luax/luax_state.h @@ -3,15 +3,13 @@ #include -#include "lua.hpp" -#include "luax_reftable.h" #include "luax_config.h" +#include "luax_reftable.h" namespace Luax { class Context; - class LuaxClass; /// /// 对lua_State的代理,除了保存一个lua_State的引用不保存其他内容。一个实例的metatable如下: @@ -109,6 +107,8 @@ namespace Luax void Settop(int idx); + template T* GetLuaUserdata(int idx); + //------------------------------------------------------------------------------------------------------------ // 对引用的管理,包含register[LUAX_STRONG_REFTABLE]和register[LUAX_WEAK_REFTABLE] @@ -157,8 +157,6 @@ namespace Luax }; -#include "luax_state.inl" - //-------------------------------------------------------------------------------------------------------------- // GetValue()模板特化 diff --git a/Source/3rdParty/Luax/luax_state.inl b/Source/3rdParty/Luax/luax_state.inl index 1515123..2c9f7a8 100644 --- a/Source/3rdParty/Luax/luax_state.inl +++ b/Source/3rdParty/Luax/luax_state.inl @@ -1,110 +1,140 @@ +namespace Luax +{ -// 针对普通类和单例类有不同的注册过程,通过LuaxState的两个工厂方法Register_实现 + // 针对普通类和单例类有不同的注册过程,通过LuaxState的两个工厂方法Register_实现 -// 注册工厂,分为注册interface table和class table,以type name为键设置在名称空间上。在注册阶段不会设置元表,等到New方法调用的时候才会。 + // 注册工厂,分为注册interface table和class table,以type name为键设置在名称空间上。在注册阶段不会设置元表,等到New方法调用的时候才会。 -template -void LuaxState::RegisterFactory() -{ - lua_State* L = mState; + template + void LuaxState::RegisterFactory() + { + lua_State* L = mState; + LuaxState& state = *this; - int top = lua_gettop(L); // namespace table + int top = lua_gettop(L); // namespace table - const char* type = T::GetLuaxFactoryName(); + assert(lua_istable(L, top)); - // interface table. - lua_newtable(L); + const char* type = T::GetLuaxFactoryName(); - int idx = AbsIndex(-1); + // interface table + lua_newtable(L); - LuaxClass::RegisterLuaxInterface(*this); - T::RegisterLuaxInterface(*this); + // interface table[__index] = interface table + lua_pushvalue(L, -1); + lua_setfield(L, -2, "__index"); - // 检测T里面是否没有注册必须的方法 -#define assertMethods(I, NAME)\ - GetField(I, NAME);\ - assert(IsType(-1, LUA_TFUNCTION));\ - Pop(); + LuaxClass::RegisterLuaxInterface(state); + T::RegisterLuaxInterface(state); - assertMethods(idx, "New"); + LuaxClass::SetInterfaceTableRef(state, -1); -#undef assertMethods + lua_settop(L, top); - lua_settop(L, top); + // class table + lua_newtable(L); - // class table. - lua_newtable(L); + LuaxClass::RegisterLuaxClass(state); + LuaxClass::RegisterLuaxFactoryClass(state); + T::RegisterLuaxClass(state); - assert(lua_istable(L, -1)); + // 检测T里面是否没有注册必须的方法 +#define _assertmethod(I, NAME) \ + GetField(I, NAME); \ + assert(IsType(-1, LUA_TFUNCTION)); \ + Pop(); - lua_pushvalue(L, -1); + // New方法可以没有,如果没有的话表示这是一个抽象类 + //_assertmethod(-1, "New"); - LuaxClass::RegisterLuaxClass(*this); - LuaxClass::RegisterLuaxFactoryClass(*this); - T::RegisterLuaxClass(*this); +#undef _assertmethod - SetField(top, type); + // .Extend() + lua_pushvalue(state, -1); // class table + LuaxClass::PushInterfaceTable(state); // interface table + lua_pushcclosure(state, LuaxClass::l_ExtendFactory, 2); + lua_setfield(state, -2, "Extend"); - // reset top - lua_settop(L, top); + // .GetInterfaceTable() + LuaxClass::PushInterfaceTable(state); // interface table + lua_pushcclosure(state, LuaxClass::l_GetInterfaceTable, 1); + lua_setfield(state, -2, "GetInterfaceTable"); -} + LuaxClass::SetClassTableRef(state, -1); -// 注册单例 -template -void LuaxState::RegisterSingleton() -{ - lua_State* L = mState; + SetField(top, type); - int top = lua_gettop(L); // namespace table + // reset top + lua_settop(L, top); + } - const char* type = T::GetLuaxSingletonName(); + // 注册单例 + template + void LuaxState::RegisterSingleton() + { + lua_State* L = mState; + LuaxState& state = *this; - // class table. - lua_newtable(L); + int top = lua_gettop(L); // namespace table + assert(lua_istable(L, top)); - assert(lua_istable(L, -1)); + const char* type = T::GetLuaxSingletonName(); - lua_pushvalue(L, -1); + // class table. + lua_newtable(L); - LuaxClass::RegisterLuaxClass(*this); - LuaxClass::RegisterLuaxFactoryClass(*this); - T::RegisterLuaxClass(*this); + LuaxClass::RegisterLuaxClass(state); + LuaxClass::RegisterLuaxFactoryClass(state); + T::RegisterLuaxClass(state); - SetField(top, type); + SetField(top, type); - // reset top - lua_settop(L, top); + // reset top + lua_settop(L, top); + } -} + template + void LuaxState::SetField(int idx, cc8* key, T value) + { + if (IsTableOrUserdata(idx)) + { + idx = AbsIndex(idx); + this->Push(value); + lua_setfield(mState, idx, key); + } + } -template -void LuaxState::SetField(int idx, cc8* key, T value) -{ - if (IsTableOrUserdata(idx)) + template + T LuaxState::GetField(int idx, cc8* key, T value) { - idx = AbsIndex(idx); - this->Push(value); - lua_setfield(mState, idx, key); + GetField(idx, key); + T result = GetValue < T >(-1, value); + this->Pop(); + + return result; } -} -template -T LuaxState::GetField(int idx, cc8* key, T value) -{ - GetField(idx, key); - T result = GetValue < T >(-1, value); - this->Pop(); - - return result; -} - -template -T LuaxState::GetField(int idx, int key, T value) -{ - GetField(idx, key); - T result = GetValue < T >(-1, value); - Pop(); + template + T LuaxState::GetField(int idx, int key, T value) + { + GetField(idx, key); + T result = GetValue < T >(-1, value); + Pop(); + + return result; + } + + template + T* LuaxState::GetLuaUserdata(int idx) + { + void* p = nullptr; + + if (IsType(idx, LUA_TUSERDATA)) + { + p = *(void**)lua_touserdata(mState, idx); + } + + return static_cast(p); + } - return result; -} +} \ No newline at end of file diff --git a/Source/Asura.Engine/Graphics/Port/Shader.cpp b/Source/Asura.Engine/Graphics/Port/Shader.cpp index 35fa86d..ba355f5 100644 --- a/Source/Asura.Engine/Graphics/Port/Shader.cpp +++ b/Source/Asura.Engine/Graphics/Port/Shader.cpp @@ -22,7 +22,7 @@ namespace AsuraEngine int Shader::l_Unuse(lua_State* L) { LUAX_STATE(L); - + } /// diff --git a/Source/Asura.Engine/Scripting/Object.h b/Source/Asura.Engine/Scripting/Object.h new file mode 100644 index 0000000..58b7e1a --- /dev/null +++ b/Source/Asura.Engine/Scripting/Object.h @@ -0,0 +1,23 @@ +#ifndef __ASURA_ENGINE_OBJECT_H__ +#define __ASURA_ENGINE_OBJECT_H__ + +#include "Config.h" +#include "Portable.h" + +namespace AsuraEngine +{ + namespace Scripting + { + + /// + /// AsuraEngine脚本的抽象基类,所有的东西都从这里派生 + /// + class Object : public Portable + { + + }; + + } +} + +#endif \ No newline at end of file diff --git a/Source/Asura.Engine/Scripting/Portable.h b/Source/Asura.Engine/Scripting/Portable.h index c188378..e3c5bef 100644 --- a/Source/Asura.Engine/Scripting/Portable.h +++ b/Source/Asura.Engine/Scripting/Portable.h @@ -10,8 +10,12 @@ namespace AsuraEngine namespace Scripting { - using Portable = Luax::LuaxClass; - + /// + /// 需要导出到lua的继承此类 + /// + template + using Portable = Luax::LuaxClass; + } } diff --git a/Source/Samples/LuaxTest/main.cpp b/Source/Samples/LuaxTest/main.cpp index 8dc7281..fdcf29a 100644 --- a/Source/Samples/LuaxTest/main.cpp +++ b/Source/Samples/LuaxTest/main.cpp @@ -59,25 +59,28 @@ void School::RegisterLuaxClass(LuaxState& state) //---------------------------------------------------------------------------------------------------------------- -class Boy : public LuaxClass +class Boy : public LuaxClass { public: - Boy(int age) : mAge(age) {} + Boy(int age, const char* name) : mAge(age), mName(name){} -private: + int mAge; + + const char* mName; - int mAge; +private: public: LUAX_DECL_FACTORY(SimBoy); // member methods - LUAX_DECL_METHOD(l_New); LUAX_DECL_METHOD(l_GetAge); + LUAX_DECL_METHOD(l_GetName); // class method + LUAX_DECL_METHOD(l_New); LUAX_DECL_METHOD(l_GetGender); }; @@ -87,8 +90,9 @@ int Boy::l_New(lua_State* L) LUAX_STATE(L); int age = state.GetValue(1, 0); + const char* name = state.GetValue(2, ""); - Boy* boy = new Boy(age); + Boy* boy = new Boy(age, name); boy->PushLuaUserdata(state); return 1; @@ -97,6 +101,19 @@ int Boy::l_New(lua_State* L) int Boy::l_GetAge(lua_State* L) { LUAX_SETUP(L, "U"); + + Boy* self = state.GetLuaUserdata(1); + + state.Push(self->mAge); + + return 1; +} + +int Boy::l_GetName(lua_State* L) +{ + LUAX_SETUP(L, "U"); + Boy* self = state.GetLuaUserdata(1); + state.Push(self->mName); return 1; } @@ -113,8 +130,9 @@ void Boy::RegisterLuaxClass(LuaxState& state) state.SetField(-1, "Gender", "Male"); // 101班 luaL_Reg regTable[] = { - {"GetGender", l_GetGender}, - {NULL, NULL} + { "New", l_New }, + { "GetGender", l_GetGender }, + {NULL, NULL} }; state.Register(regTable); @@ -123,8 +141,9 @@ void Boy::RegisterLuaxClass(LuaxState& state) void Boy::RegisterLuaxInterface(LuaxState& state) { luaL_Reg regTable[] = { - {"New", l_New}, - {NULL, NULL} + { "GetAge", l_GetAge }, + { "GetName", l_GetName }, + {NULL, NULL} }; state.Register(regTable); @@ -132,6 +151,11 @@ void Boy::RegisterLuaxInterface(LuaxState& state) //---------------------------------------------------------------------------------------------------------------- +class Girl : public LuaxClass +{ +}; + +//---------------------------------------------------------------------------------------------------------------- string script = R"( function main() local a = 19 @@ -144,7 +168,6 @@ function main() -- print(Asura.SimSchool.GetName()) print(Asura.SimBoy.Class) print(Asura.SimBoy.Gender) - print(Asura.SimBoy.GetGender()) print(Asura.SimBoy.GetClassName()) print(Asura.School.GetName()) print(Asura.School.Region) @@ -160,8 +183,27 @@ function main() end local kid = Kid.New(110, 12) kid:GetHeight() -]] -end + ]] + local kid = Asura.SimBoy.New(23, "Chai") + print(kid:GetAge()) + print(kid:GetName()) + kid.fruit = function() + return "apple" + end + print(kid.fruit()) + print(Asura.SimBoy.GetGender()) + Asura.SimBoy.Havefun = function() + return "Boys have some fun!" + end + print(Asura.SimBoy.Havefun()) + +-- 修改类方法 + Asura.SimBoy.Foo = function() + return "SimBoy.Foo" + end + print(Asura.SimBoy.Foo()) + +end function err(msg) print(msg) end @@ -183,7 +225,6 @@ int main() lua_State* L = runtime.Open(); Luax::LuaxState& state = runtime[L].state; - LuaxRefTable& strong = runtime[L].strongRefTable; state.OpenLibs(); state.PushNamespace("Asura"); state.PushNamespace("author"); -- cgit v1.1-26-g67d0