1 . BaseClass.lua
--[[
-- Lua面向对象设计
--]]
--保存类类型的虚表
local _class = {}
-- 自定义类型
ClassType = {
class = 1,
instance = 2,
}
function BaseClass(classname, super)
assert(type(classname) == "string" and #classname > 0)
-- 生成一个类类型
local class_type = {}
-- 在创建对象的时候自动调用
class_type.__init = false
class_type.__delete = false
class_type.__cname = classname
class_type.__ctype = ClassType.class
class_type.super = super
class_type.New = function(...)
-- 生成一个类对象
local obj = {}
obj._class_type = class_type
obj.__ctype = ClassType.instance
-- 在初始化之前注册基类方法
setmetatable(obj, {
__index = _class[class_type],
})
-- 调用初始化方法
do
local create
create = function(c, ...)
if c.super then
create(c.super, ...)
end
if c.__init then
c.__init(obj, ...)
end
end
create(class_type, ...)
end
-- 注册一个delete方法
obj.Delete = function(self)
local now_super = self._class_type
while now_super ~= nil do
if now_super.__delete then
now_super.__delete(self)
end
now_super = now_super.super
end
end
return obj
end
local vtbl = {}
_class[class_type] = vtbl
setmetatable(class_type, {
__newindex = function(t,k,v)
vtbl[k] = v
end
,
--For call parent method
__index = vtbl,
})
if super then
setmetatable(vtbl, {
__index = function(t,k)
local ret = _class[super][k]
--do not do accept, make hot update work right!
--vtbl[k] = ret
return ret
end
})
end
return class_type
end
2 . ConstClass.lua
--[[
-- 静态类:只读:避免访问错误,访问控制仅在调试模式下生效
-- 注意:
-- 1、调试模式下需要getmetatable再执行遍历
--]]
function ConstClass(classname, const_tb, super)
assert(type(classname) == "string" and #classname > 0)
local cls
if super then
cls = DeepCopy(super)
else
cls = {}
end
if const_tb then
for i,v in pairs(const_tb) do
cls[i] = v
end
end
cls.__cname = classname
cls.__tostring = function(self)
return table.dump(self, true, 2)
end
if Config.Debug then
-- 访问限制
cls.__index = function(tb, key)
local value = cls[key]
if value == nil then
error(tb.__cname.." read err: no key named : "..key.."\n"..table.dump(tb), 2)
end
return value
end
cls.__newindex = function(tb, key, value)
if cls[key] == nil then
error(tb.__cname.." write err: No key named : "..key.."\n"..table.dump(tb), 2)
else
error(tb.__cname.."(const) can not be writed : "..key, 2)
end
end
return setmetatable({}, cls)
else
return cls
end
end
3 . DataClass.lua
--[[
-- 数据结构类:不可写、读不存在的域:避免访问错误,访问控制仅在调试模式下生效
-- 注意:
-- 1、必须初始化,没有默认值的概念(和CS结构体一样)
-- 2、字符串全部初始化为空串:""
-- 3、table全部初始化为空表:{}
-- 4、函数(比如回调)初始化为空函数:function() end
-- 5、初始化一定不要使用nil--为nil的项lua会认为你是要删除这个项,全部设置为false
-- 6、调试模式下需要getmetatable再执行遍历
-- 7、如果提供了__init函数但是实例化时不带参数或者参数不全,将被初始化为false
--]]
-- 访问限制
local DatakIndex = function(mt, key)
local value = nil
if mt[key] ~= nil then
value = mt[key]
end
if value == nil then
error(mt.__cname.." read err: no key named : "..key.."\n"..table.dump(mt), 2)
end
return value
end
local DataNewindex = function(mt, key, value)
if mt[key] == nil then
error(mt.__cname.." write err: No key named : "..key.."\n"..table.dump(mt), 2)
end
if value then
rawset(mt, key, value)
else
rawset(mt, key, false)
end
end
function DataClass(classname, data_tb, super)
assert(type(classname) == "string" and #classname > 0)
local cls
if super then
cls = DeepCopy(super)
else
cls = {}
end
if data_tb then
for i,v in pairs(data_tb) do
cls[i] = v
end
end
cls.super = super
cls.__cname = classname
function cls.New(...)
local data = DeepCopy(cls)
local ret_data
data.New = nil
if Config.Debug then
-- 访问限制
data.__index = function(tb, key)
return DatakIndex(data, key)
end
data.__newindex = function(tb, key, value)
DataNewindex(data, key, value)
end
ret_data = setmetatable({}, data)
else
ret_data = setmetatable(data, data)
end
-- 调用初始化方法
do
local args = {...}
local create
create = function(c, ...)
if c.super then
create(c.super, ...)
end
if c.__init then
c.__init(ret_data, ...)
end
end
if #args > 0 then
create(cls, ...)
end
end
return ret_data
end
return cls
end
4 . Messenger.lua
--[[
-- 消息系统
-- 使用范例:
-- local Messenger = require "Framework.Common.Messenger";
-- local TestEventCenter = Messenger.New() --创建消息中心
-- TestEventCenter:AddListener(Type, callback) --添加监听
-- TestEventCenter:AddListener(Type, callback, ...) --添加监听
-- TestEventCenter:Broadcast(Type, ...) --发送消息
-- TestEventCenter:RemoveListener(Type, callback, ...) --移除监听
-- TestEventCenter:Cleanup() --清理消息中心
-- 注意:
-- 1、模块实例销毁时,要自动移除消息监听,不移除的话不能自动清理监听
-- 2、使用弱引用,即使监听不手动移除,消息系统也不会持有对象引用,所以对象的销毁是不受消息系统影响的
-- 3、换句话说:广播发出,回调一定会被调用,但回调参数中的实例对象,可能已经被销毁,所以回调函数一定要注意判空
--]]
local Messenger = BaseClass("Messenger");
local function __init(self)
self.events = {}
end
local function __delete(self)
self.events = nil
self.error_handle = nil
end
local function AddListener(self, e_type, e_listener, ...)
local event = self.events[e_type]
if event == nil then
event = setmetatable({}, {__mode = "k"})
end
for k, v in pairs(event) do
if k == e_listener then
error("Aready cotains listener : "..tostring(e_listener))
return
end
end
event[e_listener] = setmetatable(SafePack(...), {__mode = "kv"})
self.events[e_type] = event;
end
local function Broadcast(self, e_type, ...)
local event = self.events[e_type]
if event == nil then
return
end
for k, v in pairs(event) do
assert(k ~= nil)
local args = ConcatSafePack(v, SafePack(...))
k(SafeUnpack(args))
end
end
local function RemoveListener(self, e_type, e_listener)
local event = self.events[e_type]
if event == nil then
return
end
event[e_listener] = nil
end
local function RemoveListenerByType(self, e_type)
self.events[e_type] = nil
end
local function Cleanup(self)
self.events = {};
end
Messenger.__init = __init
Messenger.__delete = __delete
Messenger.AddListener = AddListener
Messenger.Broadcast = Broadcast
Messenger.RemoveListener = RemoveListener
Messenger.RemoveListenerByType = RemoveListenerByType
Messenger.Cleanup = Cleanup
return Messenger;
--[[
-- 单例类
--]]
local Singleton = BaseClass("Singleton");
local function __init(self)
assert(rawget(self._class_type, "Instance") == nil, self._class_type.__cname.." to create singleton twice!")
rawset(self._class_type, "Instance", self)
end
local function __delete(self)
rawset(self._class_type, "Instance", nil)
end
-- 只是用于启动模块
local function Startup(self)
end
-- 不要重写
local function GetInstance(self)
if rawget(self, "Instance") == nil then
rawset(self, "Instance", self.New())
end
assert(self.Instance ~= nil)
return self.Instance
end
-- 不要重写
local function Delete(self)
self.Instance = nil
end
Singleton.__init = __init
Singleton.__delete = __delete
Singleton.Startup = Startup
Singleton.GetInstance = GetInstance
Singleton.Destory = Destory
return Singleton;
--[[
-- 可更新脚本,等效于带有Unity侧Update、LateUpdate、FixedUpdate函数
-- 注意:
-- 1、虽然支持Update、LateUpdate、FixedUpdate更新,但能不用就不用---不要定义这些函数即可,用太多可能对性能有影响
-- 2、使用Time获取时间相关信息,如:Time.deltaTime,Time.fixedDeltaTime,Time.frameCount等
--]]
local Updatable = BaseClass("Updatable")
-- 添加更新函数
local function AddUpdate(self)
if self.Update ~= nil then
self.__update_handle = BindCallback(self, self.Update)
UpdateManager:GetInstance():AddUpdate(self.__update_handle)
end
if self.LateUpdate ~= nil then
self.__lateupdate_handle = BindCallback(self, self.LateUpdate)
UpdateManager:GetInstance():AddLateUpdate(self.__lateupdate_handle)
end
if self.FixedUpdate ~= nil then
self.__fixedupdate_handle = BindCallback(self, self.FixedUpdate)
UpdateManager:GetInstance():AddFixedUpdate(self.__fixedupdate_handle)
end
end
-- 注销更新函数
local function RemoveUpdate(self)
if self.__update_handle ~= nil then
UpdateManager:GetInstance():RemoveUpdate(self.__update_handle)
self.__update_handle = nil
end
if self.__lateupdate_handle ~= nil then
UpdateManager:GetInstance():RemoveLateUpdate(self.__lateupdate_handle)
self.__lateupdate_handle = nil
end
if self.__fixedupdate_handle ~= nil then
UpdateManager:GetInstance():RemoveFixedUpdate(self.__fixedupdate_handle)
self.__fixedupdate_handle = nil
end
end
-- 构造函数
local function __init(self)
self:EnableUpdate(true)
end
-- 析构函数
local function __delete(self)
self:EnableUpdate(false)
end
-- 是否启用更新
local function EnableUpdate(self, enable)
RemoveUpdate(self)
if enable then
AddUpdate(self)
end
end
Updatable.__init = __init
Updatable.__delete = __delete
Updatable.EnableUpdate = EnableUpdate
return Updatable
--[[
-- 可更新单例脚本,等效于MonoSignleton
--]]
local UpdatableSingleton = BaseClass("UpdatableSingleton", Updatable)
local function __init(self)
assert(rawget(self._class_type, "Instance") == nil, self._class_type.__cname.." to create UpdatableSingleton twice!")
rawset(self._class_type, "Instance", self)
end
local function __delete(self)
rawset(self._class_type, "Instance", nil)
end
-- 只是用于启动模块
local function Startup(self)
end
-- 不要重写
local function GetInstance(self)
if rawget(self, "Instance") == nil then
rawset(self, "Instance", self.New())
end
assert(self.Instance ~= nil)
return self.Instance
end
-- 不要重写
local function Delete(self)
self.Instance = nil
end
UpdatableSingleton.__init = __init
UpdatableSingleton.__delete = __delete
UpdatableSingleton.Startup = Startup
UpdatableSingleton.GetInstance = GetInstance
UpdatableSingleton.Destory = Destory
return UpdatableSingleton