接触过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 endassert(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 loadpcall(function()cls = require(name)Registry.add(cls, name)end)endassert(cls ~= nil, string.format("Registry.newObject() - invalid class \"%s\"", tostring(name)))return cls.new()
endreturn Registry
local Registry = import(".Registry")-- 负责为target对象拓展功能,使其能够附加各种组件
local GameObject = {}function GameObject.extend(target)target.components_ = {}function target:checkComponent(name)return self.components_[name] ~= nilendfunction target:addComponent(name)local component = Registry.newObject(name)self.components_[name] = componentcomponent:bind_(self)return componentendfunction target:removeComponent(name)local component = self.components_[name]if component then component:unbind_() endself.components_[name] = nilendfunction target:getComponent(name)return self.components_[name]endreturn target
endreturn GameObject
-- 组件基类,所有组件都要派生自它
local Component = class("Component")-- 构造函数,
-- name为组件名称
-- depends为该组件需要依赖于哪些组件,
-- 当某对象附加该组件时,会自动为且附加所有的depends组件
function Component:ctor(name, depends)self.name_ = nameself.depends_ = totable(depends)
endfunction 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_ = methodslocal target = self.target_local name = self.name_local com = selffor _, key in ipairs(methods) doif not target[key] thentarget[key] = function(__, ...)local r = {com[key](self, ...)}if r[1] == self then r[1] = target endreturn unpack(r)endendendreturn self
end-- 将该组件绑到target对象上
function Component:bind_(target)self.target_ = targetfor _, name in ipairs(self.depends_) doif not target:checkComponent(name) thentarget:addComponent(name)endendself:onBind_(target)
end-- 解绑该组件
function Component:unbind_()if self.exportedMethods_ thenlocal target = self.target_for _, key in ipairs(self.exportedMethods_) dotarget[key] = nilendendself:onUnbind_()
endfunction Component:onBind_()
endfunction Component:onUnbind_()
endreturn Component

quick-cocos2dx 组件管理器相关推荐

  1. 如何为火狐浏览器添加附加组件?火狐浏览器附加组件管理器使用教程

    作为一款开放源码的浏览器产品,火狐在国内也不乏粉丝.当然,这其中也有火狐浏览器上的插件功能的部分功劳,毕竟其要优于许多同类产品!那么,该如何为火狐浏览器添加附加组件呢?不清楚操作方法的朋友,还不赶紧来 ...

  2. linux 附加组件管理器在哪,使用Mozilla Firefox 64中的新附加组件管理器进行实际操作...

    Mozilla Firefox 64现在可以下载了,其中一个最大的变化是引入了一个更新后的附加组件管理器,允许您配置.禁用和删除扩展.主题.插件和语言. 这显然不是Firefox浏览器的新特性,但在6 ...

  3. 我的世界服务器组件管理器,我的世界ESS插件 Essentials | 我的世界 | MC世界侠

    ESS插件,是我的世界服务端最基础的OP组件,它功能强大,能让腐竹更好的管理自己的服务器. Essentials基础系列插件包括以下七个文件: 1.Essentials.jar 总体设置--支持各种作 ...

  4. Delta3D———通过游戏管理器组件和消息的扩展创建自定义行为 《转》

    游戏管理器组件给我们提供了在不修改游戏管理器的情况下灵活扩展我们的自定义行为的能力.游戏管理器组件是基于消息来工作的,定义自定义行为的基本 流程就是创建自定义类型的消息,在合适的时候发送消息,创建自定 ...

  5. 推荐一个简单、轻量、功能非常强大的C#/ASP.NET定时任务执行管理器组件–FluentScheduler...

    在C#WINFORM或者是ASP.NET的WEB应用程序中,根据各种定时任务的需求,比如:每天的数据统计,每小时刷新系统缓存等等,这个时候我们得应用到定时器这个东东. .NET Framework有自 ...

  6. 【详细】Android入门到放弃篇-YES OR NO-》各种UI组件,布局管理器,单元Activity

    问:达叔,你放弃了吗? 答:不,放弃是不可能的,丢了Android,你会心疼吗?如果别人把你丢掉,你是痛苦呢?还是痛苦呢?~ 引导语 有人说,爱上一个人是痛苦的,有人说,喜欢一个人是幸福的. 人与人之 ...

  7. 已禁用对分布式事务管理器(MSDTC)的网络访问。请使用组件服务管理工具启用 DTC 以便在 MSDTC 安全配置中进行网络访问。...

    [记得server 跟 client 机器都要这样配置] 已禁用对分布式事务管理器(MSDTC)的网络访问.请使用组件服务管理工具启用 DTC 以便在 MSDTC 安全配置中进行网络访问. 已禁用对分 ...

  8. Java-GUI编程实战之管理系统 Day2【Swing(组件介绍、布局管理器、事件类及监听器类)、基础组件按钮和输入框的用法】

    视频.课件.源码[链接:https://pan.baidu.com/s/13ffqGDzH-DZib6-MFViW3Q 提取码:zjxs] Java-GUI编程实战之管理系统 Day1[项目开发流程. ...

  9. 窗口管理器 实现_「42」Python布局管理器(三):place实现组件的精确与灵活布局...

    已经学习了两类布局管理器: Pack布局管理器:按照垂直或者水平的方向自然排布: Grid布局管理器:采用表格结构组织组件,组件位置受限表格形式. 两类管理器都属于那种很古板的布局方式,不能适应需要相 ...

  10. .NET定时任务执行管理器开源组件–FluentScheduler

    在日常项目里通常会遇到定时执行任务的需求,也就是定时器..NET Framework里关于定时器的类有3个,分别是System.Windows.Forms.Timer.System.Timers.Ti ...

最新文章

  1. 常见的冒泡排序、顺序查找和对半查找
  2. FPGA时序案例分析【Vivado版】
  3. kmeans聚类选择最优K值python实现
  4. python3基础教程廖雪峰云-廖雪峰Python3教程---实战day1-day13总结
  5. ADSL宽带为什么下载和上传速度差别如此之大?
  6. CCNA题库关于Frame-relay看图答题的解答
  7. springboot日志自定义路径无效及出现org.springframework.boot.context.properties.bind.BindException错误
  8. Python 语法细节(Python 2.x 与 Python 3.x 语法差异)
  9. 计算机网络之网络层:10、IP组播、IGMP协议、组播路由选择协议
  10. 【实战项目】采用jeecg3.2框架,一个人写的购物系统
  11. 如何用Pygame写游戏(十六)
  12. css 获取第一个a标签,CSS-伪类获取除第一个之外的其他子元素
  13. 远程源已存在于“ git push”到新存储库中
  14. 用MACD决策树模型预测股票趋势
  15. Mac右键使用VS Code打开项目
  16. 4刀最多切割一个正方体为多少部分
  17. 项目环境搭建,数据库,以及Swagger2介绍(二)
  18. ubuntu平台下编译vlc-android视频播放器实践
  19. vue在列表和下拉框中显示icon图标
  20. 单目相机内参标定注意事项

热门文章

  1. WPF 使用 Font Awesome(OTF / TTF)
  2. 使用pyinstaller打包python源代码生成exe程序
  3. mysql教材课后题答案_MySql练习题参考答案
  4. Scratch妙笔生花
  5. 微信小程序的下载安装
  6. mysql学习书籍推荐
  7. OMAPL138 DSP程序固化
  8. java中同步代码块具体步骤,Java同步块
  9. JAVA常见异常之NullPointerException 空指针异常
  10. 使用JFlash往Nordic nRF系列芯片烧写程序