Kigs 框架介绍 (1/8)






4.58/5 (18投票s)
一个多用途、跨平台的免费开源 C++ 框架
目录
引言
Kigs 是一个用于快速应用程序开发的底层框架。它提供了对高级架构和功能(模块、序列化、反射、实例工厂、升级器、聚合器...)的访问,同时保持对底层(优化、平台特定自定义、易于使用 C/C++ 外部库...)的控制。
如今,借助商业(Unreal、Unity...)或开源(OpenSceneGraph、Ogre3D...)的 3D 引擎,开发 2D 或 3D 移动应用程序、跨平台游戏...变得相当容易。
这些引擎显然有它们的优点,也有它们的缺点
- 有些不免费。
- 有些是黑匣子,您只能访问暴露的功能。
- 有些非常侧重于场景图/渲染,而不是真正多用途。
我们开发 Kigs 框架是因为我们想要一个轻量级、快速、可扩展的框架,可以移植到不同的平台(这就是为什么我们使用 C++,它几乎在所有平台上都可用),并且可以用作构建我们所有项目的基石,从任天堂 DSi 游戏
到工业机器人模拟器(请看这里:https://kigs-framework.org/Projects)。我们还希望保持完全独立,并对我们所有的项目代码保持完全控制。
几周前,我们决定开源(MIT 许可证)我们框架的主要模块,支持 **Windows**(x86、x64,支持 OpenGL 和 D3D,WUP D3D)和 **HTML5**/Web Assembly(Emscripten)平台。现已提供功能齐全的(目前已不再维护,我们没有时间维护它,并很乐意获得一些帮助)**Android** 版本和未维护的 **iOS** 版本。这是 GitHub 存储库
有什么新内容?
在过去几个月里,我们花了一些时间重构框架
- 删除了不必要的/有 bug 的/已弃用的代码(可能还有一些!)。
- 添加了一些命名空间:Kigs 作为通用命名空间,然后为每个模块一个。
- 添加了管理 CoreModifiable 属性的新方法(映射现有成员变量)。
- 使用更现代的 C++ 来管理属性(减少了复制代码)。
- ...
为什么要使用 Kigs 框架?
- 您是一名 C++ 开发者,希望访问高级功能,如序列化、实例工厂、信号/槽管理、场景图/渲染、Lua 脚本...
- 您想通过 C++ 和 Lua 脚本学习游戏开发。
- 您想在不从头开始的情况下试验新想法。
- 您好奇我们如何实现这个或那个功能,并可能想帮助改进框架。
如果我们能让其他人接管我们的框架,改进它并根据他们的愿望和需求进行调整,我们将感到高兴。
总体架构
Kigs 框架分为不同的模块,每个模块在一个特定领域(输入、渲染、GUI...)中组织功能。有两种主要模块类型:通用和特定。
通用模块
通用模块定义了与 API/SDK/系统无关的类,和/或与 API/SDK/系统相关的类的基类(接口)。
特定模块
当然,特定模块做的是完全相反的事情:它们定义了与 API/SDK/系统相关的类,通常继承自通用类。
基础模块
主要模块包括 `Core`、`FileManager`、`Timer`、`XML`。然后是 `Input`(带有特定的 `InputWindows`、`InputWUP`...)、`GUI`(`GuiWindows`、`GUIWUP`...)、`SceneGraph`、`Renderer`(`RendererOpenGL3`、`RendererDirectX11`)...
核心功能
核心功能主要由 `KigsCore` 和 `CoreModifiable` 类支持。
实例工厂
继承 `CoreModifiable` 的类可以注册到实例工厂。要求 `KigsCore` 创建所需类的实例就很简单
// Ask for an instance of class Timer called "localtimer"
CMSP localtimer = KigsCore::GetInstanceOf("localtimer", "Timer");
这里 localtimer 以 CMSP(CoreModifiable SmartPointer)的形式返回。如果没有更多引用,当代码退出 localtimer 作用域时,localtimer 实例将被删除。
CoreModifiable 树
`CoreModifiable` 实例可以像这样组织成父子树
// add localtimer instance to this (this must inherit CoreModifiable too of course)
addItem(localtimer);
`addItem` 会增加实例的引用计数。`localtimer` 实例将在其引用计数达到 `0` 时销毁,所以在我们的例子中,当父类被销毁时。
`CoreModifiable` 在使用前应进行初始化
// init localtimer (timer is started)
localtimer->Init();
然后 `localtimer` 可以在代码的其他部分通过不同类型的搜索函数检索
// search son with given name
Timer* localtimer=GetFirstSonByName("Timer", "localtimer")->as<Timer>();
或
// search first instance found with given name
CMSP localtimer = GetFirstInstanceByName("Timer", "localtimer");
所有给定类型的实例也可以一次性检索
// search all instances of Timer
std::vector<CMSP> alltimers = GetInstances("Timer");
CoreModifiable 属性
`CoreModifiable` 可以拥有“编译时”属性,可以通过名称获取或设置
// retrieve "Sample1Value" value on this
int _value;
testInstance->getValue("Sample1Value", _value);
_value = 4 * _value - 12;
// change "Sample1Value" value with _value
testInstance->setValue("Sample1Value", _value);
属性也可以在运行时添加或删除
// add a dynamic attribute on instance of localtimer
localtimer->AddDynamicAttribute(ATTRIBUTE_TYPE::FLOAT, "floatValue", 12.0f);
// retrieve dynamic attribute value on localtimer
float timervalue=localtimer->getValue<float>("floatValue");
// set dynamic float attribute with string
localtimer->setValue("floatValue","24");
序列化
`CoreModifiable` 树及其所有属性都可以导出到 XML 文件
// export this and its sons in "Sample1.xml" file
CoreModifiable::Export("Sample1.xml", this, true);
当然,也可以从 XML 文件导入 `CoreModifiable` 树
// import instances from file "Sample1.xml"
CMSP imported=CoreModifiable::Import("Sample1.xml");
CoreModifiable 方法
方法可以添加到 `CoreModifiable` 中,然后只能通过它们的名称在运行时访问(而无需知道调用该方法的实例的确切类型)。
调用此类方法的简单方法是
// call SimpleSampleClass AddValue method directly on CoreModifiable
float result = simpleclass->SimpleCall<float>("AddValue", 10, 12.0f);
printf("result of calling AddValue = %f\n", result);
在 GitHub 上的“Sample1”项目中查找本介绍中的所有示例代码(浏览代码)。
入门
必备组件
我们将重点介绍我们使用过的主要开发平台:Windows。
我们的脚本需要 Visual Studio C++ 2022(社区版即可)。
最新版本的 CMake(在本例中设置为 3.15.5)。
创建新项目
克隆存储库后,转到 _kigs\projects_ 文件夹。
运行两个脚本之一:_CreateNewConsoleProject.vbs_(用于命令行项目)或 _CreateNewDDProject.vbs_(用于图形数据驱动项目)。
输入项目名称:将创建一个同名的新文件夹。例如“`SimpleTest`”并按 **OK**。
现在用文本编辑器打开“_kigs\projects\CMakeLists.txt_”文件,并添加以下行
add_subdirectory(MyProjectName)
将“`MyProjectName`”替换为项目名称(在我们的例子中是 `SimpleTest`)。
保存并关闭“_CMakeLists.txt_”文件。
然后转到 _kigs\scripts_ 文件夹并运行以下脚本之一
- _generateWinCMake.bat_ 用于 win32(opengl)应用程序
- _generateWinCMake64.bat_ 用于 win64(opengl)应用程序
- _generateWinD3DCMake.bat_ 用于 win32(D3D)应用程序
- _generateWinD3DCMake64.bat_ 用于 win64(D3D)应用程序
- _generateWUPD3DCMake.bat_ 用于通用 Windows 平台 D3D 应用程序(仅用于图形数据驱动项目)
将在 _kigs_ 文件夹的同级目录下创建一个新的 _Build\[solutionType]_ 文件夹。
构建和运行新项目
浏览此文件夹以到达 _Build\[solutionType]\kigs\projects\"MyProjectName"_ 并选择“`MyProjectName`”.sln 在 Visual Studio 中打开它。
解决方案在 Visual Studio 中加载后,将“`MyProjectName`”设置为启动项目,选择所需的构建配置:`StaticDebug`(用于带有完整调试信息的编译)、`StaticReleaseTools`(用于带有优化的编译,但保留所有导出功能)、`StaticRelease`(用于完全优化但无导出功能)。
构建,启动。就是这样!
下一步
在本系列接下来的文章中,我们将探讨框架的高级功能
- CoreModifiable 类详细信息
- CoreModifiable 属性
- CoreModifiable 方法
CoreItem
- 信号/槽/通知
- Lua 绑定
- 数据驱动应用程序
- ...
本系列已发布内容:
- Kigs框架介绍 (1/8) - 概述
- Kigs框架介绍 (2/8) - CoreModifiable
- Kigs框架介绍 (3/8) - 属性
- Kigs框架介绍 (4/8) - 方法
- Kigs框架介绍 (5/8) - CoreItem
- Kigs框架介绍 (6/8) - 信号,槽,通知
- Kigs框架介绍 (7/8) - Lua绑定
- Kigs框架介绍 (8/8) - 数据驱动应用程序
历史
- 2020年1月24日:初始版本
- 2020年1月29日:添加了目录
- 2020年2月1日:添加了 本系列已发布内容
- 2020年2月7日:将文章(3/8)添加到本系列
- 2020年2月8日:添加了 Rollway Puzzle 的截图并修复了 Projects 页面的链接
- 2020年2月14日:将文章(4/8)添加到本系列
- 2020年2月21日:将文章(5/8)添加到本系列并修复了代码中的小错误
- 2020年3月2日:将文章(6/8)添加到本系列
- 2020年3月6日:发布了新的 Android/iOS 平台,并将文章(7/8)添加到本系列
- 2020年3月19日:所有 GetInstances 方法现在都返回 CMSP 或 std::vector<CMSP>
- 2020年5月1日:GitHub 存储库已迁移。
- 2020年6月17日:添加了该系列的最后一篇文章
- 2020年6月19日:修改了介绍,使其更清晰
- 2023年3月1日:框架重构后更新文章。