游戏引擎的启动与终止【笔记】
2018-03-14 18:26
225 查看
1.游戏引擎 包含 许多子系统,之间可能存在 相互依赖 。
2.子系统一般设计为单例类【称为管理器,管理子系统启动,运行,终止】。
3.C++原生的初始化次序:
(首先).编译器完成 全局和静态对象 的内存分配并初始化(在可执行映像内)
(然后).运行时 调用堆栈 内的 局部变量 的内存分配及初始化(在程序堆栈/又称调用堆栈内) ①
(最后).运行时的动态分配,即new出来的数据(在堆内存中)
→(方法1)原生的C++初始化次序不可用,因为单例作为全局或静态对象,总是在调用入口函数main之前初始化,因而无法手动控制他们初始化的次序,这样就没办法处理1所述的子系统间相互依赖。析构也是同理,你看不到他的析构过程,也没法控制他的次序。
4.标记①:
调用堆栈内的对象总是在 函数被调用的时候才创建 ,那么在函数内我们就可以控制对象的构造及初始化顺序。但是函数内的对象在函数退出时就 可以看做 被析构了(实际上是移动了调用堆栈的内存指针,如果在一个函数退出后,调用下一个新函数以前,仍然可以使用指针访问到这段内存的数据。在新函数调用时,会从内存指针开始进行内存覆盖,这样以后,旧的数据才会丢失)。
如何把函数内的对象持久化呢?答案是使用static,将它变成函数内静态变量。这种变量不再是存储在调用堆栈内,而是在可执行映像内就被分配好了内存,存储在其数据段或BSS段。虽然存储位置变了,但他初始化的时机却还是函数被调用时。
不过这样仍然存在问题,虽然数据保存下来了,但是函数退出后,这个数据的访问入口丢了,因为他只在该函数内可见。不过仔细想想,这个问题其实已经解决了,答案在于上文所述的 单例 。只需要函数外再建一个该单例的对象,访问入口就出现了。
→(方法2)按需构建。此法存在问题,即析构不可控。【且开销很大】
5.简便可行的办法:
功能拆分,不把子系统的启动功能放在其构造函数里面。即构造析构不做操作,另写 启动和终止函数。
→(方法3)蛮力法,优点明显,推荐使用。
6.构建专门的管理类,在管理类的内部保存子系统映射,并通过Coding管理类的构造函数,达到所需的子系统构造和启动次序。这相当于在程序外打了个包,管理类模拟了进程的执行,把子系统对象封包到类内部,从而可以直接控制他们的初始化次序。
→(方法4)OGRE的做法。缺点在于违反了 开闭原则 ,当你需要新的子系统时,你非得回来修改管理类的代码不可。而且一旦这个系统不开源,即你没办法获取管理类的具体代码,对他的修改就束手无策了。严重
4000
影响可扩展性。【幸好它是开源的】
→神海1的做法类似方法4,但是更多的使用静态分配的单例对象,而非new出来的。new操作很慢,十分影响效能。而且另外,动态分配的内存分布散乱,地址跨度大,比起静态分配的连续内存块,效率也会低很多,而且其减益很可能大于优质算法带来的效能增益
2.子系统一般设计为单例类【称为管理器,管理子系统启动,运行,终止】。
3.C++原生的初始化次序:
(首先).编译器完成 全局和静态对象 的内存分配并初始化(在可执行映像内)
(然后).运行时 调用堆栈 内的 局部变量 的内存分配及初始化(在程序堆栈/又称调用堆栈内) ①
(最后).运行时的动态分配,即new出来的数据(在堆内存中)
→(方法1)原生的C++初始化次序不可用,因为单例作为全局或静态对象,总是在调用入口函数main之前初始化,因而无法手动控制他们初始化的次序,这样就没办法处理1所述的子系统间相互依赖。析构也是同理,你看不到他的析构过程,也没法控制他的次序。
4.标记①:
调用堆栈内的对象总是在 函数被调用的时候才创建 ,那么在函数内我们就可以控制对象的构造及初始化顺序。但是函数内的对象在函数退出时就 可以看做 被析构了(实际上是移动了调用堆栈的内存指针,如果在一个函数退出后,调用下一个新函数以前,仍然可以使用指针访问到这段内存的数据。在新函数调用时,会从内存指针开始进行内存覆盖,这样以后,旧的数据才会丢失)。
如何把函数内的对象持久化呢?答案是使用static,将它变成函数内静态变量。这种变量不再是存储在调用堆栈内,而是在可执行映像内就被分配好了内存,存储在其数据段或BSS段。虽然存储位置变了,但他初始化的时机却还是函数被调用时。
不过这样仍然存在问题,虽然数据保存下来了,但是函数退出后,这个数据的访问入口丢了,因为他只在该函数内可见。不过仔细想想,这个问题其实已经解决了,答案在于上文所述的 单例 。只需要函数外再建一个该单例的对象,访问入口就出现了。
→(方法2)按需构建。此法存在问题,即析构不可控。【且开销很大】
5.简便可行的办法:
功能拆分,不把子系统的启动功能放在其构造函数里面。即构造析构不做操作,另写 启动和终止函数。
→(方法3)蛮力法,优点明显,推荐使用。
6.构建专门的管理类,在管理类的内部保存子系统映射,并通过Coding管理类的构造函数,达到所需的子系统构造和启动次序。这相当于在程序外打了个包,管理类模拟了进程的执行,把子系统对象封包到类内部,从而可以直接控制他们的初始化次序。
→(方法4)OGRE的做法。缺点在于违反了 开闭原则 ,当你需要新的子系统时,你非得回来修改管理类的代码不可。而且一旦这个系统不开源,即你没办法获取管理类的具体代码,对他的修改就束手无策了。严重
4000
影响可扩展性。【幸好它是开源的】
→神海1的做法类似方法4,但是更多的使用静态分配的单例对象,而非new出来的。new操作很慢,十分影响效能。而且另外,动态分配的内存分布散乱,地址跨度大,比起静态分配的连续内存块,效率也会低很多,而且其减益很可能大于优质算法带来的效能增益
相关文章推荐
- [读书笔记]<游戏引擎架构>|管理器的启动与终止
- [学习笔记]小型java游戏引擎_1
- 【游戏支持系统】子系统的启动和终止
- libgdx游戏引擎开发笔记(八)SuperJumper游戏例子的讲解(篇二)---- 游戏界面跳转
- 【Cocos2d-x游戏引擎开发笔记(4)】系统动画
- 【Cocos2d-x游戏引擎开发笔记(15)】Tiled Map Editor(三)
- 【Cocos2d-x游戏引擎开发笔记(24)】CURL实现get和post联网
- 【Cocos2d-x游戏引擎开发笔记(21)】CCHttpRequest联网
- 非典型2D游戏引擎 Orx 源码阅读笔记(2) 基础模块与模块管理模块
- 【Cocos2d-x游戏引擎开发笔记(17)】实现运动的尾巴效果
- 【麦可网】Cocos2d-X跨平台游戏开发学习笔记---第八课: Cocos2D-X引擎框架3
- libgdx游戏引擎开发笔记(九)SuperJumper游戏例子的讲解(篇三)---- 主游戏界面显示框架
- Unity3D手游开发系列笔记(二)—— 游戏引擎介绍
- 【游戏客户端开发】Unity3D 学习笔记2——了解U3D引擎的操作面板和各种工具
- 【Cocos2d-x游戏引擎开发笔记(5)】自定义动画
- 【Cocos2d-x游戏引擎开发笔记(16)】动画速度的控制
- 【Cocos2d-html5游戏引擎学习笔记(4)】菜单按钮
- 【Cocos2d-x游戏引擎开发笔记(24)】CURL实现get和post联网
- LGame学习笔记1-----LGame游戏引擎大体架构