-
Notifications
You must be signed in to change notification settings - Fork 19
Overview.zh CN
在入门中已经解释了头文件宏的使用。
公开的头文件宏的命名是模块路径的直接应用:替换 ::
为 _
,加上前缀 YFM_
或 YFM_平台名
。
这些宏名直接定义在各个 include
目录的 YModules.h
中。而头文件 <YSBuild.h>
则包含了一系列的 YModules.h
和其它模块的头文件,因此可以直接包含它来简化使用。
YSLib 中不同的次级子项目引入不同的命名空间。
关于每个顶级子项目下不同的命名空间参见 doc/YBase.txt
和 doc/YFramework.txt
以及 Doxygen 生成的文档。
注意 在以下讨论中,若没有特别说明,所有非宏名的标识符都在 namespace YSLib
中。
注意避免命名空间使用冲突。除非是在一个很有限的块作用域内,一般而言,using namespace std;
总是不被推荐的,但 using namespace YSLib;
在非头文件中则是被允许的。
在 YSLib 的头文件中,无论是 using
声明还是 using
指令或是命名空间别名,都是经过慎重考虑的,特别是为了实现平台中立的兼容。
- 如 YCLib::Mutex 模块支持标准库的对应接口,即使语言的实现如 libstdc++ 在单线程平台上不提供支持,也通过回退到 YBase::PseudoMutex 而允许不改动用户代码并直接保证空行为。允许不改动用户代码的性质可通过
using namespace platform::Concurrency
实现。
所有其它不经意的在头文件中使用都应被避免。
因为无法完全避免使用不同风格命名的外部依赖,YSLib 强调区分命名的来源而不是使用单一命名风格。
YBase 使用和 ISO C++ 标准库相容的风格。YFramework 则约定使用框架名称,其中可能包含一些前缀,如 I
表示只有抽象方法的类(接口类),G
表示用于泛型(与元编程目的相区别)的类模板的名称等。
详细的命名规约参见 doc/CommonRules.txt
和 doc/YFramework.txt
。
启动一个应用一般可以分为两个部分:创建内容;让内容被显示。YSLib 对此提供了整体性的便利解决方案。以下说明以典型的 GUI 程序为例(非 GUI 程序实际上不必要使用特别的支持)。
Helper::GUIApplication 模块提供的 GUIApplication
类的单例对象初始化中集成了 GUI 程序必要的初始化。之后,可以部署必要的操作,例如决定哪些内容被初始地呈现。程序通过 Helper::GUIApplication 提供的函数 Execute
调用被封装的消息循环(message loop) ,接受用户输入并按需响应。最后,当特定条件被满足时,退出 Execute
函数,程序结束。
消息循环,或称事件循环(event loop) ,是交互式应用的典型实现方式。程序通过处理(handling) 不同的消息(message) 完成期望的行为。除了少数特殊消息(例如表示“退出”以结束程序的消息),消息循环自身通常不能决定如何处理一个消息,因此需要分发(dispatching) 到用户提供程序中。
基本的消息循环的是一个轮询(polling) 操作,一次循环尝试确定一个需要被处理的消息。所有被处理的消息储存于消息队列(message queue) 内。当消息循环从消息队列取得消息时,通常即在队列中删除此消息。适当的操作产生消息发送至消息队列内以待处理。这种机制能让消息之间具有一定的顺序保证。但要注意,为了满足调度的需要,此处的队列并不一定需要是严格先进先出的。YSLib 使用模块 YSLib::Core::YMessage 提供的 Messaging::Message
类表示消息,Messaging::MessageQueue
类表示支持优先级的消息队列。
当没有消息需要被处理时即进入空闲(idle) 状态,库需要保证消息循环不被立刻终止,可以采取如下操作:
- 发送特定的空闲消息并立即处理。
- 当可能有其它机制发送消息至消息队列时,放弃处理器资源以便节约能源或(在多任务环境中)使其它程序被调度,预定等待一定时间后再次轮询。
- 结合以上操作。
交互式程序中,用户动作和其它外部输入可以被抽象为一个消息。输入消息包含必要的状态数据。用户程序指定此处的响应逻辑,更新特定应用的状态,绘制屏幕图形等。由于一个 GUI 程序在此需要完成的任务具有典型性,可以在更高层次上加以抽象,不一定需要直接控制消息循环。但了解消息循环仍然是必要的。
YSLib 提供称为 Shell 的抽象使交互式程序易于被分隔为不同的实现。每个 Shell 类可以通过覆盖的虚函数 OnGotMessage 提供响应不同的消息一整套逻辑。