// 加载插件中的类 // 初始化数据核心 //13. 鼠标指针管理器 //16. 操作管理
s_pActionSystem = ( tActionSystem* ) g_theKernel.NewNode( _T( "CActionSystem"), _T( "bin" ), _T("action" ) ); //17. UI模型显示管理 s_pFakeObjSystem = ( tFakeObjSystem* ) g_theKernel.NewNode( _T( "CFakeObjSystem"), _T( "bin" ), _T("fake" ) ); //18. 外接帮助系统 s_pHelperSystem = ( tHelperSystem* ) g_theKernel.NewNode( _T( "CHelperSystem"), _T( "bin" ), _T("helper" ) ); //19. 资源提供 s_pResourceProvider = ( CResourceProvider* ) g_theKernel.NewNode( _T( "CResourceProvider"), _T( "bin" ), _T("resprovider" ) );
...//省略 |
CGameProcedure::InitStaticMemeber这一部分代码做了三件事情
1. 加载插件并检查其合法性
2. 创建并初始化游戏的各个过程类实例
3. 初始化数据核心
插件的加载就是载入dll并检查是不是合法的插件。代码很容易懂,就不看了。过程类实例的初始化等到按游戏的运行独到相应的过程时再看。这儿我们主要看看数据核心的初始化。
数据核心的初始化是创建一棵类树。g_theKernel.NewNode的主要在作用以root节点为根的树中的指定位置添加新的节点。它是怎么样创建类节点的呢?
在上一篇中,我们看到了,各个类已经注册在类检索表中了。我们可以通过类检索表可以方便的得到对应类的创建函数CreateObject(LPCTSTR szName)。这里有个小技巧,CreateObject只在TClass类中实现了,为什么可以创建不同类的节点呢? TClass只是各类的一个注册接口,我们先来看看它的结构
|
我们可以看到,它有一个函数指针。在定义各个节点类的时候,这个指针设为每个类的创建函数。(节点类的tClass类实例是通过WX_DECLARE_DYNAMIC,WX_DECLARE_DYNAMIC来声明和实现的)CreateObject是通过这些函数指针实现的统一创建接口。
下面研究g_theKernel.NewNode的代码,这个函数实现了重载。一个是根据字符串形式的路径来创建新节点,另一个根据父节点来创建新节点。两个的过程差不多,找到位置后,都调用CreateObject创建节点。
//打开类 tNode *pCurrentNode = &m_theRoot; //搜索父节点 |
这函数先调用OpenClass打开类,所谓的打开类,就是在类检索表中查到指定类的TClass指针。然后通过TDU_ConvertStringToVector把路径按照"\"或者"/"切分开,每一项都是要建节点的一个父节点。然后在循环中,依次检查父节点是否存在,不存在就创建。最后以路径中最后一个节点为父节点,先查看子节点中是否存在要新建的节点,不存在的话,就新建。
根据父节点创建比这个要更简单。由于父节点是以参数形式传入的,所以我们直接检查一下它的子节点中是否存在要建节点,不存在,创建就完事了。
|