HGE 系列教材(6) --- 程序流程与细节
HGE 的一些细节,通过源码可以更加清楚的了解,通过读源码,可以更加高效的使用 HGE Engine。
必要的第一步:
Help Classes 层建立于 Core Functions 层之上,这并不意味着用户只需要关心 Help Classes 而忽略 Core Functions,因此我们需要获得一个 HGE 指针,来使用 Core Functions 的函数:
1 获取 HGE 指针:
HGE* pHGE = pgeCreate(HGE_VERSION);
2 释放 HGE 指针:
使用之后,需要释放 HGE 指针。
pHGE- Release();
Create 和 Release 过程使用了引用计数,也就是说,一般来看,除了第一次的 Create 调用之外几乎不消耗CPU时间和资源,每调用一次 Create 函数,引用计数器就加一,只有在第一次调用的时候才会真正的分配空间,调用 Release 会使得引用计数器减一,当它为 0 的时候,才真正是释放资源。因此以下代码是可用的:
while(true)
{
HGE* pHGE = pgeCreate(HGE_VERSION); // 确保不是第一次调用 pgeCreate 函数,因为如果是第一次调用,会分配内存。
// ... do something
pHGE- Release();
}
此外,要成对的调用 pgeCreate 和 Release 函数,每次调用 Release 之后,调用它的指针将被赋值为0,例如:
HGE* pHGE = hgeCreate(HGE_VERSION);
pHGE- Release();
pHGE- Release(); // ERROR: pHGE == 0
另外,pHGE- Release 会调用 pHGE- System_Shutdown();
必要的第二步:
初始化: pHGE- System_Initiate();
初始化语句放在 Windows 入口函数中,这个函数将按顺序完成
1)窗口类的注册
2)创建窗口
3)初始化子系统
4)显示一个 HGE 的 LOGO(这个东西在 HGE 里面被称之为 HGE splash)
一般使用 System_Initiate() 都会是这样的:
if (pHGE- System_Initiate())
{
pHGE- System_Start();
}
else
{
MessageBox(NULL, pHGE- System_GetErrorMessage(), "Error", MB_OK | MB_ICONERROR | MB_APPLMODAL);
}
必要的第三步:
调用: pHGE- System_Start();
调用了 System_Start 的目的是开始消息循环,见必要的第二步代码
pHGE- System_Start 和 pHGE- System_Shutdown 是成对出现的,处于某些原因,即使我们知道 pHGE- Release 会调用 System_Shutdown 函数,我们还是应该去显示的调用 System_Shutdown 函数。System_Shutdown 相比 Release 要安全,我们可以这样调用,而不会出错:
pHGE- System_Start();
// ... Something
pHGE- System_Shutdown();
pHGE- System_Shutdown(); // OK
不论如何,Create 和 Release 成对调用,Start 和 Shutdown 成对调用,那么就不会有问题出现。
还有什么是需要的?
System_SetState 函数
常常需要设置窗口大小或者是设置为全屏模式,需要设置是否使用声音等,这一系列操作被称之为设置系统状态,统一通过调用 pHGE- System_SetState 函数来完成,最为关键的是设置帧函数,调用了 pHGE- System_Start 之后,会在绘制每帧图像时调用帧函数。
pHGE- System_SetState(XXX, XXX) 通常可以在如何地方,如何情况下调用,不要认为它们只能在 pHGE- System_Initiate 之前调用
System_SetState 函数的第一个参数表示状态,在内部实现时,它是 FSM 的状态,而第二个参数表示值,通过这个函数,可以绑定状态和相关的值
补充一下,帧函数必须是一个全局函数,而不能是一个类的成员函数,并且帧函数的原型必须是:
bool FunName(void);
惯用法:
我们通常会在程序初始化之前设置状态,即在 System_Initiate 调用之前,例如:
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
pHGE- System_SetState(HGE_FRAMEFUNC, FrameFunc);
pHGE- System_SetState(HGE_WINDOWED, true);
pHGE- System_SetState(HGE_USESOUND, false);
pHGE- System_SetState(HGE_TITLE, "HGE");
pHGE- System_SetState(HGE_SHOWSPLASH, false); // 用于去除 LOGO
if (pHGE- System_Initiate())
{
pHGE- System_Start();
}
else
{
MessageBox(NULL, pHGE- System_GetErrorMessage(), "Error", MB_OK | MB_ICONERROR | MB_APPLMODAL);
}
pHGE- System_Shutdown();
pHGE- Release();
return 0;
}
只要是做过编程的童鞋都知道模块化的思想,这样写出的代码更加简洁明了。模块化的代码让你的思路更加清晰,有利于当前编程,同时还有利于后期的维护。另外,很多有公共作用的代码,理所应当的提炼出来,以提高代码利用率。
相关文章
- Flask开发系列之数据库操作
- Spring系列.依赖注入配置
- Win10系列:C#应用控件进阶5
- 云上持续交付实践系列4 --- node 篇
- Nagios学习实践系列——产品介绍篇
- Web应用扩展系列(1):架构篇(转)
- 搜索引擎系列 ---lucene简介 创建索引和搜索初步
- java mongodb 基础系列---查询,排序,limit,$in,$or,输出为list,创建索引,$ne 非操作
- Android Studio系列教程四--Gradle基础(转载)
- dubbo源码分析系列(1)扩展机制的实现
- MOM系列文章之 - MQ可运维性
- CodeDom系列二---程序基本结构--符号三角形问题
- 深入浅出Mybatis系列(三)---配置详解之properties与environments(mybatis源码篇)
- Qt系列文章006-Qt元对象介绍
- 【云原生 | Kubernetes 系列】---Ceph Crush
- Spring读源码系列之AOP--01---aop基本概念扫盲---上
- Spring读源码系列番外篇08---BeanWrapper没有那么简单--上
- Spring读源码系列之AOP--09---aop源码流程一把拿下
- 白话经典算法系列之六 高速排序 高速搞定
- 【云原生 | Kubernetes 系列】---Prometheus监控Nginx
- Go语言自学系列 | golang defer语句
- linux基本功系列之hostname实战
- Linux基本功系列之usermod命令实战
- 【 D3.js 入门系列 --- 2 】 怎样使用数据和选择元素
- RK3399平台开发系列讲解(其他篇)1.13、 改进显示系统
- 【云原生 | Kubernetes 系列】---Prometheus监控Nginx