您的位置:首页 > 移动开发 > Cocos引擎

quick-cocos2dx 组件管理器

2013-12-13 15:55 344 查看
接触过unity3D的都知道,unity里的对象,都是由一个空的gameObject附加上相应的组件构成的。quick-lua里也有这种功能。它是由Registry.lua,GameObject.lua和Component.lua协调完成的。如果想使用这套机制,只需要调一个函数:GameObject.extend(obj),这样obj就能附加组件了。如果相用自定义组件,则要自定义Component的派生类

-- 定义Registry类,此类用于管理所有组件类。相当于一张注册表,所有的组件都要在这张表中注册。(当然
-- 不用去显示地注册,newObject会根据组件的名字,自动加载并注册组件
local Registry = class("Registry")

Registry.classes_ = {}

-- 注册组件,这里的组件实际上就是一个类,且要派生自Component。
function Registry.add(cls, name)
assert(type(cls) == "table" and cls.__cname ~= nil, "Registry.add() - invalid class")
if not name then name = cls.__cname end
assert(Registry.classes_[name] == nil, "Registry.add() - class \"%s\" already exists", tostring(name))
Registry.classes_[name] = cls
end

-- 删除组件
function Registry.remove(name)
assert(Registry.classes_[name] ~= nil, "Registry.remove() - class \"%s\" not found", name)
Registry.classes_[name] = nil
end

-- 实例化指定组件,并返回该实例化对象。若指定组件还未加载,则自动加载它。
function Registry.newObject(name)
local cls = Registry.classes_[name]
if not cls then
-- auto load
pcall(function()
cls = require(name)
Registry.add(cls, name)
end)
end
assert(cls ~= nil, string.format("Registry.newObject() - invalid class \"%s\"", tostring(name)))
return cls.new()
end

return Registry


local Registry = import(".Registry")

-- 负责为target对象拓展功能,使其能够附加各种组件
local GameObject = {}

function GameObject.extend(target)
target.components_ = {}

function target:checkComponent(name)
return self.components_[name] ~= nil
end

function target:addComponent(name)
local component = Registry.newObject(name)
self.components_[name] = component
component:bind_(self)
return component
end

function target:removeComponent(name)
local component = self.components_[name]
if component then component:unbind_() end
self.components_[name] = nil
end

function target:getComponent(name)
return self.components_[name]
end

return target
end

return GameObject


-- 组件基类,所有组件都要派生自它
local Component = class("Component")

-- 构造函数,
-- name为组件名称
-- depends为该组件需要依赖于哪些组件,
-- 当某对象附加该组件时,会自动为且附加所有的depends组件
function Component:ctor(name, depends)
self.name_ = name
self.depends_ = totable(depends)
end

function Component:getName()
return self.name_
end

-- 获取所有的依赖组件(它是一个table)
function Component:getDepends()
return self.depends_
end

-- 获取该组件被附加到哪个组件上
function Component:getTarget()
return self.target_
end

-- 将该组件某些的方法导出到target上
-- methods为字符串数组,字符串名字就是函数名。
-- 有了这套机制,在调用addcomponent后接着调用此函数,
-- 则以后想使用该组件的功能,直接通过target就能调用,无需先获取组件,再调用函数
function Component:exportMethods_(methods)
self.exportedMethods_ = methods
local target = self.target_
local name = self.name_
local com = self
for _, key in ipairs(methods) do
if not target[key] then
target[key] = function(__, ...)
local r = {com[key](self, ...)}
if r[1] == self then r[1] = target end
return unpack(r)
end
end
end
return self
end

-- 将该组件绑到target对象上
function Component:bind_(target)
self.target_ = target
for _, name in ipairs(self.depends_) do
if not target:checkComponent(name) then
target:addComponent(name)
end
end
self:onBind_(target)
end

-- 解绑该组件
function Component:unbind_()
if self.exportedMethods_ then
local target = self.target_
for _, key in ipairs(self.exportedMethods_) do
target[key] = nil
end
end
self:onUnbind_()
end

function Component:onBind_()
end

function Component:onUnbind_()
end

return Component
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: