【游戏支持系统】子系统的启动和终止

引擎由各种子系统构成。引擎启动时需要考虑子系统启动的顺序问题。比如A依赖B的话那么就应该先启动B再启动A,终止的时候应该先终止A再终止B。

C++的静态初始化次序(是不可用的)

一般用单例类来使用子系统(管理器) 实例用全局变量来避免使用动态内存,如:

class RenderManager{public:RenderManager(){//启动管理器…}~RenderManager(){//终止管理器…}};//单例一个实例static RenderManager gRenderManager;

然而,C++全局变量的建构,析构顺序是没有办法直接控制的,所以这种方法行不通。

按需架构

C++有一个特性:函数内声明的静态变量并不会与main()之前建构,而是在第一次调用该函数时才建构。于是可采用如下的代码

class RenderManager{public://取得唯一实例static RenderManager& get(){//此函数中的静态变量将于函数被首次调用时建构static RenderManager sSingleton;return sSingleton;}RenderManager(){//对于需依赖的管理器,先通过调用他们的get()启动它们VideoManager::get();TextureManager::get();//现在启动渲染管理器…}~RenderManager(){//终止管理器}};

下面是使用动态内存的变种

static RenderManager& get(){static RenderManager& gpSingleton = NULL;if(gpSingleton == NULL) gpSingleton = new RenderManager;ASSERT(gpSingleton);//断言return *gpSingleton;}

但是用这种方法无法控制析构的顺序。并且get函数的开销可能很大。我们要用一个更加简单并且有效的方法。

行之有效的简单方法

让建构和析构函数完全不作任何事情。按所需的明确次序调用各个启动和终止函数。如

class RenderManager{public:RenderManager() {} //不做任何事情~RenderManager() {} //不做任何事情void startUp(){//启动管理器}void shutDown(){//终止管理器}};};};};};//…….RenderManagergRenderManager;PhysicManagergPhysicsManager;AnimationManagergAnimationManager;TextureManagergTextureManager;VideoManagergVideoManager;MemoryManagergMemoryManager;FileSystemManager gFileSystemManager;* argv){//以正确次序启动各引擎系统gMemoryManager.startUp();gFileSystemManager.startUp();gVideoManager.startUp();gTextureManager.startUp();gRenderManager.startUp();gAnimationManager.startUp();gPhysicsManager.startUp();//……//运行游戏gSimulationManager.run();//以反向次序终止各引擎系统gPhysicsManager.shutDown();gAnimationManager.shutDown();gRenderManager.shutDown();gTextureManager.shutDown();gVideoManager.shutDown();gFileSystemManager.shutDown();gMemoryManager.shutDown();reutrn 0;}

**优点: ①简单 容易实现 ②方法是明确的 看代码就可以知道顺序 ③容易调试和维护**

一些实际引擎的例子OGRE

OGRE中的一切对象都是由Ogre::Root单例控制。此单例含有指向其他OGRE子系统的指针,并负责启动和终止这些子系统。 所以启动OGRE,,只需要new一个Ogre::Root实例就可以了。

//OgreRoot.hclass _OgreExport Root : public Singleton<Root>{//各单例LogManager* mLogManager;ControllerManager* mControllerManager;//等等};//OgreRoot.cppRoot::Root(const String& pluginFileName,const String& configFileName,const String& logFileName):mLogManager(0),mCurrentFrame(0),mFrameSmoothingTime(0.0f);mNextMovableObjectTypeFlag(1),mIsInitiailised(false){//基类会检查单例//初始化mActiveRenderer = 0;mVersion (LogManager::getSingletonPtr() == 0){mLogManager = new LogManager();mLogManager->createLog(logFileName,true,true);}//动态库管理员mDynLibManager = new DynLibManager();mArchiveManager = new ArchiveManager();//资源群管理员mResourceGroupManager = new ResourceGroupManager();//资源北京队列mResourceBackgroundQueue = new ResourceBackgroundQueue();//等等…}

真正的爱,应该超越生命的长度、心灵的宽度、灵魂的深度

【游戏支持系统】子系统的启动和终止

相关文章:

你感兴趣的文章:

标签云: