<2021SC@SDUSC> 开源游戏引擎 Overload 代码模块分析 之 OvGame(七)—— Core(四)Application & Main.cpp

2021SC@SDUSC
开源游戏引擎 Overload 代码模块分析 之 OvGame(七)—— Core(四)Application & Main.cpp

前言

本篇是 OvGame 的 Core 的第四篇,也是 Core 的最后一篇,将探究其最后的 Application 部分。这部分的内容很少,所以本篇也将进一步探究完 OvGame 的最后内容 Main.cpp

其中,Application 包含了同是 Core 的 Context 与 Game,如果读者已经有些遗忘、或是尚未了解过,请先前往 Core(一)Core(三) 阅读。

另外,若想先大致了解该引擎各个大模块,可前往笔者这篇相关文章查看。
若想了解 OvGame 大纲,可前往笔者这篇文章

分析

1、Application

1.1 Application.h

1.1.1 头文件
#include "OvGame/Core/Context.h"
#include "OvGame/Core/Game.h"

该文件仅包含了前言中提及的两个头文件,请读者自行前往了解了解。

1.1.2 主要代码

主要代码是一个 Application 类,是 OvGame 模块的接口点,定义如下:

	class Application
	{
	public:
		/**
		* Constructor
		*/
		Application();

		/**
		* Destructor
		*/
		~Application();

		/**
		* Run the app
		*/
		void Run();

		/**
		* Returns true if the app is running
		*/
		bool IsRunning() const;

	private:
		Context m_context;
		Game m_game;
	};

显然,作为一个综合接口,该类函数都是负责运行程序,变量也是老朋友 Context 和 Game,不多赘述。

1.2 Application.cpp

1.2.1 头文件
#include <OvTools/Time/Clock.h>

#include "OvGame/Core/Application.h"

该文件除了 Application.h,还引入了 Overload 的 OvTools 模块。巧合的是,笔者之前的文章探究过该模块,感兴趣的读者可以前往阅读。

1.2.2 主体代码
Application() 与 ~Application() 函数
OvGame::Core::Application::Application() :
	m_game(m_context)
{

}

OvGame::Core::Application::~Application()
{
}

这两个分别是构造函数和析构函数,都没有定义具体代码,不多赘述。其中构造函数是用参数初始化表更新了 m_game。

IsRunning() 函数
bool OvGame::Core::Application::IsRunning() const
{
	return !m_context.window->ShouldClose();
}

该函数负责判断是否在运行应用。m_context.window(窗口)的函数 ShouldClose() 能调用 GLFW 的 glfwWindowShouldClose() 得到窗口是否关闭的讯息真值并返回:要关闭为真,不关闭为假。所以,代码直接调用 ShouldClose() 并取反真值,再返回即可。

Run() 函数
void OvGame::Core::Application::Run()
{
	OvTools::Time::Clock clock;

	while (IsRunning())
	{
		m_game.PreUpdate();
		m_game.Update(clock.GetDeltaTime());
		m_game.PostUpdate();

		clock.Update();
	}
}

该函数负责运行应用。先声明一个 Clock 类对象记录时间;然后,利用上文的 IsRunning() 判断是否还在运行即没有关闭应用,是则进入 while 循环;接着,在 while 循环内,m_game 调用依次函数,进行从 PreUpdate() 启用输入和事件、经过 Update() 更新、到 PostUpdate() 结束输入输出缓存的一套逻辑更新;最后,clock 调用 Update() 更新时间记录。

至此,Application 的内容就全部探究完毕了。为什么这么快呢?是因为 Application 完全是一个使用者,几乎是应用其它类与功能函数来完成自己的任务。所以,如果想更多地了解 Application 的运行过程,需要读者们去认真阅读笔者在前言中提及的文章,以及这些文章提及的其它文章,挨个了解好背后封装好的各种函数。

另一方面,根据 Overload 的 OvGame 模块大纲,OvGame 模块的三个文件夹也都探究完毕了。不过,读者们如果没有了解好 OvGame 这些部分的封装功能以及嵌套调用关系,也可以继续前往最后一部分,OvGame 模块的 Main.cpp 文件。

2、Main.cpp

2.1 头文件

#include <OvRendering/Utils/Defines.h>

#include "OvGame/Core/Application.h"

该文件包含了上文的 Application 文件以及 Overload 的另一模块文件 OvRendering/Utils/Defines.h,该头文件和 GPU 相关。

2.2 主要代码

FORCE_DEDICATED_GPU

#ifdef _DEBUG
int main()
#else
#undef APIENTRY
#include "Windows.h"
INT WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow)
#endif
{
	OvGame::Core::Application app;
	app.Run();

	return EXIT_SUCCESS;
}

首先,声明 FORCE_DEDICATED_GPU,强制独占 GPU;接着进入条件编译命令,此处的含义是选择要编译的函数名:

如果定义 _DEBUG 即进入 Debug 模式,则选择函数名为 int 型 main() ,没有参数;否则进行下一个判断:如果没有定义 API 接口,则引入 C++ 头文件 Windows.h(有关 Windows 系统),选择函数名为 INT(重定义前即 int)型 WinMain(),并加入多个有关应用程序信息的参数,其中用到的类型是 Windows 的 HINSTANCE(应用程序模块的实例)与 PSTR(相当于 C++ 的 char*)。

而不论哪个函数名,运行内容都是 “ #endif ” 之后的那段代码:先声明一个 app 应用类,再直接调用上文提及的 Run() 运行该应用程序。最后,当关闭该应用、退出 Run() 函数后,则返回 EXIT_SUCCESS 命令,退出并中止程序。

总结

现在,Application 与 main 函数的内容都探究完了,都是使用封装内容,并不复杂;另一方面,这也同样意味着 OvGame 的所有内容都探究完毕了。所以,下一篇,笔者将写一个 OvGame 模块的终篇总结,作为该系列的结尾。

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值