YSTest: Initialization.cpp 源文件

YSTest PreAlpha_b500_20140530 The YSLib Test Project

- 首页
- 相关页面
- 模块
- 命名空间
- 类
- 文件

- 文件列表
- 文件成员

全部 类 命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义 组 页
Initialization.cpp
浏览该文件的文档.
1 /*
2 © 2009-2014 FrankHB.
3
4 This file is part of the YSLib project, and may only be used,
5 modified, and distributed under the terms of the YSLib project
6 license, LICENSE.TXT. By continuing to use, modify, or distribute
7 this file you indicate that you have read the license and
8 understand and accept it fully.
9 */
10
28 #include "Helper/YModules.h"
29 #include YFM_Helper_Initialization
30 #include YFM_YSLib_Core_YApplication
31 #include YFM_Helper_GUIApplication
32 #include YFM_YCLib_Debug
33 #include YFM_CHRLib_MappingEx
34 #include YFM_YCLib_MemoryMapping
35 #include YFM_YSLib_Service_FileSystem
36 #include <cstring> // for std::strcmp;
37 //#include <clocale>
38 #include YFM_NPL_SContext
39
40 using namespace ystdex;
41 using namespace platform;
42 using std::puts;
43
44 namespace YSLib
45 {
46
47 using namespace Drawing;
48 using namespace IO;
49
50 namespace
51 {
52
54
55 stack<std::function<void()>> app_exit;
56 ValueNode* p_root;
57 Drawing::FontCache* p_font_cache;
59 #if !CHRLIB_NODYNAMIC_MAPPING
60 platform::MappedFile* p_mapped;
62 #endif
63 MIMEBiMapping* p_mapping;
66 const char TU_MIME[]{u8R"NPLA1(
67 (application
68 (octet-stream "bin" "so")
69 (x-msdownload "exe" "dll" "com" "bat" "msi")
70 (x-font-ttf "ttf" "ttc")
71 (xml "xml")
72 (zip "zip")
73 )
74 (audio
75 (midi "mid" "midi" "rmi")
76 (mpeg "mp3")
77 (x-mpegurl "m3u")
78 (x-wav "wav")
79 )
80 (image
81 (bmp "bmp")
82 (gif "gif")
83 (jpeg "jpeg" "jpg")
84 (png "png")
85 (tif "tif" "tiff")
86 )
87 (text
88 (html "html" "htm")
89 (plain "txt" "conf" "def" "ini" "log" "in")
90 (x-c "c" "h" "inl")
91 (x-c++ "cc" "cpp" "cxx" "h" "hh" "hpp" "hxx" "inl")
92 )
93 )NPLA1"};
94
95 #if YCL_DS
96 # define ROOTW
97 # define DATA_DIRECTORY ROOTW "/Data/"
98 //const char* DEF_FONT_NAME = ROOTW "方正姚体";
99 //const char* DEF_FONT_PATH = ROOTW "/Font/FZYTK.TTF";
100 # define DEF_FONT_PATH ROOTW "/Font/FZYTK.TTF"
101 # define DEF_FONT_DIRECTORY ROOTW "/Font/"
102 #else
103 # define ROOTW "."
104 # define DATA_DIRECTORY ROOTW "\\"
105 //const char* DEF_FONT_NAME = "方正姚体";
106 //const char* DEF_FONT_PATH = ROOTW "\\Font\\FZYTK.TTF";
107 # define DEF_FONT_PATH "C:\\Windows\\Fonts\\SimSun.ttc"
108 # define DEF_FONT_DIRECTORY ROOTW "\\"
109 #endif
110 #define CONF_PATH "yconf.txt"
111
112 void
113 LoadComponents(const ValueNode& node)
114 {
115 const auto& data_dir(AccessChild<string>(node, "DataDirectory"));
116 const auto& font_path(AccessChild<string>(node, "FontFile"));
117 const auto& font_dir(AccessChild<string>(node, "FontDirectory"));
118
119 if(!data_dir.empty() && !font_path.empty() && !font_dir.empty())
120 std::printf("Loaded default directory:\n%s\n"
121 "Loaded default font path:\n%s\n"
122 "Loaded default font directory:\n%s\n",
123 data_dir.c_str(), font_path.c_str(), font_dir.c_str());
124 else
125 throw LoggedEvent("Empty path loaded.");
126 #if !CHRLIB_NODYNAMIC_MAPPING
127 puts("Load character mapping file...");
128 p_mapped = new MappedFile(data_dir + "cp113.bin");
129 if(p_mapped->GetSize() != 0)
130 CHRLib::cp113 = p_mapped->GetPtr();
131 else
132 throw LoggedEvent("CHRMapEx loading fail.");
133 puts("CHRMapEx loaded successfully.");
134 #endif
135 std::printf("Trying entering directory %s ...\n", data_dir.c_str());
136 if(!IO::VerifyDirectory(data_dir))
137 throw LoggedEvent("Invalid default data directory found.");
138 if(!(ufexists(font_path) || IO::VerifyDirectory(font_dir)))
139 throw LoggedEvent("Invalid default font file path found.");
140 }
141
142 } // unnamed namespace;
143
144 void
145 HandleFatalError(const FatalError& e) ynothrow
146 {
147 YDebugSetStatus();
148 YDebugBegin();
149
150 const char* line("--------------------------------");
151
152 std::printf("%s%s%s\n%s\n%s",
153 line, e.GetTitle(), line, e.GetContent(), line);
154 terminate();
155 }
156
157
158 ValueNode
159 LoadNPLA1File(const char* disp, const char* path, ValueNode(*creator)(),
160 bool show_info)
161 {
162 if(!ufexists(path))
163 {
164 if(show_info)
165 std::printf("Creating %s '%s'...\n", disp, path);
166 if(creator)
167 {
168 if(TextFile tf{path, std::ios_base::out | std::ios_base::trunc})
169 tf << NPL::Configuration(creator());
170 else
171 throw LoggedEvent("Cannot create file.");
172 }
173 else
174 return {};
175 }
176
177 TextFile tf(path);
178
179 if(show_info)
180 std::printf("Found %s '%s'.\n", disp, path);
181 return ReadConfiguration(tf);
182 }
183
184
185 ValueNode
186 ReadConfiguration(TextFile& tf)
187 {
188 if(YB_LIKELY(tf))
189 {
190 if(YB_UNLIKELY(tf.Encoding != Text::CharSet::UTF_8))
191 throw LoggedEvent("Wrong encoding of configuration file.");
192
193 NPL::Configuration conf;
194
195 tf >> conf;
196 if(conf.GetNodeRRef().GetSize() != 0)
197 return conf.GetNodeRRef();
198 }
199 throw LoggedEvent("Invalid file found when reading configuration.");
200 }
201
202 void
203 WriteConfiguration(TextFile& tf, const ValueNode& node)
204 {
205 if(YB_UNLIKELY(!tf))
206 throw LoggedEvent("Invalid file found when writing configuration.");
207 tf << NPL::Configuration("", node.Value);
208 }
209
210 ValueNode
211 LoadConfiguration(bool show_info)
212 {
213 return LoadNPLA1File("configuration file", CONF_PATH, []{
214 return PackNodes("YFramework", MakeNode("DataDirectory",
215 string(DATA_DIRECTORY)), MakeNode("FontFile",
216 string(DEF_FONT_PATH)), MakeNode("FontDirectory",
217 string(DEF_FONT_DIRECTORY)));
218 }, show_info);
219 }
220
221 void
222 SaveConfiguration(const ValueNode& node)
223 {
224 TextFile tf(CONF_PATH, std::ios_base::out | std::ios_base::trunc);
225
226 WriteConfiguration(tf, node);
227 }
228
229
230 void
231 InitializeEnviornment()
232 {
233 //设置默认异常终止函数。
234 std::set_terminate(terminate);
235 #if YCL_DS
236 //启用设备。
237 ::powerOn(POWER_ALL);
238
239 //启用 LibNDS 默认异常处理。
240 ::defaultExceptionHandler();
241
242 //初始化主控制台。
243 platform::YConsoleInit(true, ColorSpace::Lime);
244
245 //初始化文件系统。
246 //初始化 EFSLib 和 LibFAT 。
247 //当 .nds 文件大于32MB时， EFS 行为异常。
248 # ifdef USE_EFS
249 if(!::EFS_Init(EFS_AND_FAT | EFS_DEFAULT_DEVICE, nullptr))
250 {
251 //如果初始化 EFS 失败则初始化 FAT 。
252 # endif
253 if(!::fatInitDefault())
254 throw FatalError(" LibFAT Failure ",
255 " An error is preventing the\n"
256 " program from accessing\n"
257 " external files.\n"
258 "\n"
259 " If you're using an emulator,\n"
260 " make sure it supports DLDI\n"
261 " and that it's activated.\n"
262 "\n"
263 " In case you're seeing this\n"
264 " screen on a real DS, make sure\n"
265 " you've applied the correct\n"
266 " DLDI patch (most modern\n"
267 " flashcards do this\n"
268 " automatically).\n"
269 "\n"
270 " Note: Some cards only\n"
271 " autopatch .nds files stored in\n"
272 " the root folder of the card.\n");
273 # ifdef USE_EFS
274 }
275 # endif
276 #endif
277 #if 0
278 // TODO: Review locale APIs compatibility.
279 static yconstexpr char locale_str[]{"zh_CN.GBK"};
280
281 if(!std::setlocale(LC_ALL, locale_str))
282 throw LoggedEvent("Call of std::setlocale() with %s failed.\n",
283 locale_str);
284 #endif
285 }
286
287 ValueNode
288 InitializeInstalled()
289 {
290 puts("Checking installation...");
291 try
292 {
293 auto node(LoadConfiguration(true));
294
295 if(node.GetName() == "YFramework")
296 node = PackNodes("", std::move(node));
297 LoadComponents(node.at("YFramework"));
298 puts("OK!");
299 return node;
300 }
301 catch(std::exception& e)
302 {
303 std::printf("Error occurred: %s\n", e.what());
304 }
305 throw FatalError(" Invalid Installation ",
306 " Please make sure the data is\n"
307 " stored in correct directory.\n");
308 }
309
310 void
311 InitializeSystemFontCache(FontCache& fc, const string& fong_file,
312 const string& font_dir)
313 {
314 puts("Loading font files...");
315 try
316 {
317 size_t nFileLoaded(fc.LoadTypefaces(fong_file) != 0);
318
319 if(!font_dir.empty())
320 //读取字体文件目录并载入目录下指定后缀名的字体文件。
321 try
322 {
323 HDirectory dir{font_dir.c_str()};
324 IO::PathNorm nm;
325
326 std::for_each(FileIterator(&dir), FileIterator(),
327 [&](const std::string& name){
328 if(!nm.is_self(name)
329 && dir.GetNodeCategory() != NodeCategory::Directory
330 /*&& IsExtensionOf(ext, dir.GetName())*/)
331 {
332 FontPath path(font_dir + dir.GetName());
333
334 if(path != fong_file)
335 nFileLoaded += fc.LoadTypefaces(path) != 0;
336 }
337 });
338 }
339 catch(FileOperationFailure&)
340 {}
341 fc.InitializeDefaultTypeface();
342 if(const auto nFaces = fc.GetFaces().size())
343 std::printf("%u face(s) in %u font file(s)"
344 " are loaded\nsuccessfully.\n", nFaces, nFileLoaded);
345 else
346 throw LoggedEvent("No fonts found.");
347 puts("Setting default font face...");
348 if(const auto* const pf = fc.GetDefaultTypefacePtr())
349 std::printf("\"%s\":\"%s\",\nsuccessfully.\n",
350 pf->GetFamilyName().c_str(), pf->GetStyleName().c_str());
351 else
352 throw LoggedEvent("Setting default font face failed.");
353 return;
354 }
355 // TODO: Use %std::nested_exception.
356 catch(std::exception& e)
357 {
358 puts(e.what());
359 }
360 throw FatalError(" Font Caching Failure ",
361 " Please make sure the fonts are\n"
362 " stored in correct path.\n");
363 }
364
365 void
366 Uninitialize() ynothrow
367 {
368 while(!app_exit.empty())
369 {
370 if(YB_LIKELY(app_exit.top()))
371 app_exit.top()();
372 app_exit.pop();
373 }
374 #if !CHRLIB_NODYNAMIC_MAPPING
375 delete p_mapped;
376 #endif
377 }
378
379
380 ValueNode&
381 FetchRoot()
382 {
383 if(YB_UNLIKELY(!p_root))
384 {
385 p_root = ynew ValueNode(InitializeInstalled());
386 app_exit.push([]{
387 ydelete(p_root);
388 });
389 }
390 return *p_root;
391 }
392
393 Drawing::FontCache&
394 FetchDefaultFontCache()
395 {
396 if(YB_UNLIKELY(!p_font_cache))
397 {
398 p_font_cache = ynew Drawing::FontCache;
399 app_exit.push([]{
400 ydelete(p_font_cache);
401 });
402
403 const auto& node(FetchRoot()["YFramework"]);
404
405 InitializeSystemFontCache(*p_font_cache,
406 AccessChild<string>(node, "FontFile"),
407 AccessChild<string>(node, "FontDirectory"));
408 }
409 return *p_font_cache;
410 }
411
412 MIMEBiMapping&
413 FetchMIMEBiMapping()
414 {
415 if(YB_UNLIKELY(!p_mapping))
416 {
417 p_mapping = ynew MIMEBiMapping;
418 app_exit.push([]{
419 ydelete(p_mapping);
420 });
421 AddMIMEItems(*p_mapping, LoadNPLA1File("MIME database",
422 (AccessChild<string>(FetchRoot()["YFramework"], "DataDirectory")
423 + "MIMEExtMap.txt").c_str(), []{
424 return
425 NPL::LoadNPLA1(NPL::SContext::Analyze(NPL::Session(TU_MIME)));
426 }, true));
427 }
428 return *p_mapping;
429 }
430
431 } // namespace YSLib;
432
NPL::Session
会话：分析指定 NPL 代码。
Definition: SContext.h:54
YSLib::Drawing::FontCache::InitializeDefaultTypeface
void InitializeDefaultTypeface()
初始化默认字型。
Definition: Font.cpp:486
YSLib::InitializeInstalled
YF_API ValueNode InitializeInstalled()
初始化已安装项：检查安装完整性并载入主配置文件的配置项。
Definition: Initialization.cpp:288
NPL::Configuration
设置：使用 S 表达式存储外部状态。
Definition: Configuration.h:49
YSLib::TextFile::Encoding
Text::Encoding Encoding
编码。
Definition: TextFile.h:67
YSLib::FetchRoot
YF_API ValueNode & FetchRoot()
取值类型根节点。
Definition: Initialization.cpp:381
platform::YDebugBegin
YF_API void YDebugBegin()
调试模式：显示控制台。
Definition: Debug.cpp:75
ystdex::path
一般路径模板。
Definition: path.hpp:149
NPL::LoadNPLA1
YF_API ValueNode LoadNPLA1(ValueNode &&)
读取 NPLA1 翻译单元。
Definition: NPLA1.cpp:86
YSLib::TextFile
文本文件类。
Definition: TextFile.h:56
DEF_FONT_PATH
#define DEF_FONT_PATH
Definition: Initialization.cpp:107
platform::ufexists
YF_API bool ufexists(const char *) ynothrow
判断指定 UTF-8 文件名的文件是否存在。
Definition: YCLib/FileSystem.cpp:307
CONF_PATH
#define CONF_PATH
Definition: Initialization.cpp:110
YSLib::FetchMIMEBiMapping
YF_API MIMEBiMapping & FetchMIMEBiMapping()
取 MIME 类型名和文件扩展名双向映射对象。
Definition: Initialization.cpp:413
YSLib::PackNodes
ValueNode PackNodes(_tString &&name, _tParams &&...args)
取以指定分量为参数对应初始化得到的值类型节点为子节点的值类型节点。
Definition: ValueNode.h:391
platform::MappedFile
只读内存映射文件。
Definition: MemoryMapping.h:42
YSLib::ValueNode::Value
ValueObject Value
Definition: ValueNode.h:59
DEF_FONT_DIRECTORY
#define DEF_FONT_DIRECTORY
Definition: Initialization.cpp:108
NPL::SContext::Analyze
YF_API void Analyze(ValueNode &, const TokenList &)
分析指定源，取抽象语法树储存至指定值类型节点。
Definition: SContext.cpp:96
ynew
#define ynew
Definition: ynew.h:205
platform::HDirectory
目录句柄：表示打开的目录和内容迭代状态。
Definition: YCLib/FileSystem.h:452
YSLib::SaveConfiguration
YF_API void SaveConfiguration(const ValueNode &)
保存默认配置。
Definition: Initialization.cpp:222
platform::YDebugSetStatus
YF_API void YDebugSetStatus(bool=true)
调试模式：设置状态。
Definition: Debug.cpp:63
platform::terminate
YB_NORETURN YF_API void terminate() ynothrow
异常终止函数。
Definition: ycommon.cpp:39
YSLib::MIMEBiMapping
MIME 和文件扩展名双向映射。
Definition: ContentType.h:45
YB_UNLIKELY
#define YB_UNLIKELY(expr)
分支预测提示。
Definition: ydef.h:298
YSLib::IO::PathNorm
文件路径范式。
Definition: YSLib/Service/FileSystem.h:45
YSLib::LoadConfiguration
YF_API ValueNode LoadConfiguration(bool={})
载入默认配置。
Definition: Initialization.cpp:211
YSLib::Drawing::FontCache
字体缓存。
Definition: Font.h:415
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:514
YSLib::UI::name
yconstfn const string & name
Definition: Loader.h:110
YSLib::FetchDefaultFontCache
YF_API Drawing::FontCache & FetchDefaultFontCache()
取默认字体缓存。
Definition: Initialization.cpp:394
YSLib::string
GSStringTemplate< char >::basic_string string
Definition: ycont.h:164
platform::YConsoleInit
YF_API void YConsoleInit(std::uint8_t dspIndex, Color fc=ColorSpace::White, Color bc=ColorSpace::Black)
启动控制台。
YSLib::ValueNode
值类型节点。
Definition: ValueNode.h:45
YSLib::LoadNPLA1File
YF_API ValueNode LoadNPLA1File(const char *disp, const char *path, ValueNode(*creator)(), bool show_info={})
载入 NPLA1 配置文件。
Definition: Initialization.cpp:159
YSLib::ReadConfiguration
YF_API ValueNode ReadConfiguration(TextFile &)
从文本文件中读取配置。
Definition: Initialization.cpp:186
YSLib::FatalError
致命错误。
Definition: yexcept.h:87
YSLib::InitializeSystemFontCache
YF_API void InitializeSystemFontCache(Drawing::FontCache &, const string &, const string &)
初始化系统字体缓存。
Definition: Initialization.cpp:311
platform::FileIterator
ystdex::indirect_input_iterator< HDirectory * > FileIterator
文件迭代器。
Definition: YCLib/FileSystem.h:539
ydelete
#define ydelete
Definition: ynew.h:207
ystdex::path_norm::is_self
virtual bool is_self(const value_type &)=0
YSLib::AddMIMEItems
YF_API void AddMIMEItems(MIMEBiMapping &, const ValueNode &, MIMEBiMapping::MIMEType &&={})
根据 NPLA1 节点内容增加 MIME 映射。
Definition: ContentType.cpp:62
YSLib::Uninitialize
YF_API void Uninitialize() ynothrow
反初始化。
Definition: Initialization.cpp:366
YSLib::HandleFatalError
YB_NORETURN YF_API void HandleFatalError(const FatalError &) ynothrow
处理致命错误：显示错误信息并终止程序。
Definition: Initialization.cpp:145
YModules.h
YSLib::Drawing::FontCache::LoadTypefaces
size_t LoadTypefaces(const FontPath &)
从字体文件组中载入字型信息。
Definition: Font.cpp:456
YSLib::InitializeEnviornment
YF_API void InitializeEnviornment()
初始化环境。
Definition: Initialization.cpp:231
YSLib::LoggedEvent
记录日志的异常事件类。
Definition: yexcept.h:58
yconstexpr
#define yconstexpr
指定编译时常量表达式。
Definition: ydef.h:462
YSLib::Drawing::FontPath
std::string FontPath
字体文件路径。
Definition: Font.h:68
YSLib::WriteConfiguration
YF_API void WriteConfiguration(TextFile &, const ValueNode &)
写入配置至文本文件。
Definition: Initialization.cpp:203
CHRLib::cp113
byte * cp113
Definition: MapEx.cpp:39
DATA_DIRECTORY
#define DATA_DIRECTORY
Definition: Initialization.cpp:104
platform::FileOperationFailure
表示文件操作失败的异常。
Definition: YCLib/FileSystem.h:390
YB_LIKELY
#define YB_LIKELY(expr)
Definition: ydef.h:297
CHRLib::CharSet::UTF_8
yconstexpr Encoding UTF_8(csUTF8)
YSLib::IO::VerifyDirectory
VerifyDirectory
Definition: YSLib/Service/FileSystem.h:312
YSLib::UI::fc
fc
Definition: Console.h:94
YSLib::Drawing::FontCache::GetDefaultTypefacePtr
const Typeface * GetDefaultTypefacePtr() const
取默认字型指针。
Definition: Font.cpp:408