模块的初始化
组件式的设计中,最难处理的就是模块的初始化次序和退出次序的问题。如果不考虑动态加载卸载问题,则可以简化一些设计。
退出问题解决起来最为容易,安全的退出唯一需要考虑的是对系统资源的释放。这是操作系统的工作,进程被杀掉时,所有占用的资源都会被安全回收,所以我选择的是不作为。
初始化部分要相对复杂一点,我把模块加载和初始化部分分开。加载的过程是静态的,无相互依赖关系的。实际上,做的只有代码和数据段载入内存的过程。(在实现上,要绝对避免隐式的代码运行,例如 C++ 中的全局对象的自动初始化)
初始化过程是惰性的,即:用到再调用初始化入口。每个模块都在自己初始化的时候去调用所依赖模块的初始化(实际上也必须如此,否则拿不到别的模块的句柄,无法使用其它模块内的方法),这样模块之间的初始化次序就自然规整了。只要不人为写出循环初始化的逻辑,是不会出错的。
实际操作中遇到一个问题,某些模块的初始化依赖一些参数。当需要参数传递的时候,初始化流程就变的复杂了。昨天同事提出一个需求:3d 渲染的基础模块需要一个窗口句柄来初始化自己,否则无法使用。那么依赖这个渲染模块的其它模块的初始化部分就必须也知道这个窗口句柄。而窗口句柄是由窗口管理模块初始化后,构造一个窗口才能得到的。其它模块均无法自行构造出窗口来。
我们上一个版本的设计中,模块管理器拥有一快公有数据区,专门用于模块初始过程的数据交换。这种类似 Windows 注册表的设计,隐隐的,一直让我觉得不妥。这次重构代码时,就把它从设计中拿掉了。
重构代码到今天,发现该碰到的问题依旧存在,需要想办法更好的解决这个问题。昨天晚上躺在床上把怪物猎人2中的轰龙一举干掉,一扫几天来的郁闷心情。突然来了灵感,找到一个很简洁的方案解决这个问题。
首先,任何模块的初始化入口依旧不需要传递参数。这如同单件的设计一样,单件永远是自行构造的。这样,每个第一次使用单件的人都有可能触发单件的惰性初始化。若单件的构造还需要参数的话,代码复杂度会上升许多,显然是不合理的。
让需要构造的单件自行读取外部配置来了解如何构造自己,这也是一种解决方案。数据驱动、符合模块设计的原则:能自己解决的问题自己解决,减少数据的传递。但这不是一个普适的方法。因为有些工作就是一步步进行的,我们需要上一步的结果来进行下一步工作。
其实,我们需要的只是一个独立模块单独负责模块初始化阶段的阶段性衔接。
还是以 3d 渲染模块和窗口创建过程的依赖关系为例子。事实上,上层的逻辑并不需要直接驱动这些底层模块的初始化流程,它们只需要在自己初始化时,这些底层模块都已整装待发。所以,我们写一个独立模块初始化掉该初始化的东西即可:在这里,我们随便创建一个窗口,得到窗口句柄,传递给 3d 渲染器初始化。这已经足够单元测试使用。当以后游戏的复杂逻辑需要自定义的窗口时,简单把它换掉就够了。我把这个衔接用的模块起名叫 launch3d 。
我们的单元测试程序,只需要简单依赖一下这个 launch3d 模块。它能保证相关的底层模块都初始化完毕。
这个故事给了我启发:面对二次开发者,引擎开放出来的不一定是上层建筑的接口。整个设计可以是平坦的,无论上层还是下层构件都可以是可定制和可替换的。这样才是良好的设计。
Comments
Posted by: zhanxw | (16) June 21, 2010 01:56 PM
Posted by: 科士威 | (15) March 2, 2010 10:41 PM
Posted by: rockcarry | (14) June 13, 2007 12:30 PM
Posted by: rockcarry | (13) June 13, 2007 12:22 PM
Posted by: Zenberg | (12) June 4, 2007 10:55 PM
Posted by: Cloud | (11) June 4, 2007 01:05 PM
Posted by: lingate | (10) May 29, 2007 10:51 PM
Posted by: 开心 | (9) May 29, 2007 10:19 PM
Posted by: 夕霞孤雁 | (8) May 28, 2007 02:01 PM
Posted by: david | (7) May 27, 2007 08:59 PM
Posted by: Cloud | (6) May 27, 2007 08:51 PM
Posted by: fatfatson | (5) May 27, 2007 07:49 PM
Posted by: zelor | (4) May 27, 2007 05:30 PM
Posted by: Cloud | (3) May 26, 2007 04:34 PM
Posted by: ly | (2) May 26, 2007 02:11 PM
Posted by: 让人 | (1) May 25, 2007 08:41 PM