YSTest: Loader.cpp 源文件

YSTest PreAlpha_b500_20140530 The YSLib Test Project

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

- 文件列表
- 文件成员

全部 类 命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义 组 页
Loader.cpp
浏览该文件的文档.
1 /*
2 © 2013-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 "YSLib/UI/YModules.h"
29 #include "NPL/YModules.h"
30 #include YFM_YSLib_UI_Loader
31 #include <sstream>
32 #include YFM_YSLib_UI_YPanel
33 #include YFM_NPL_SContext
34 #include YFM_NPL_Configuration
35
36 namespace YSLib
37 {
38
39 namespace UI
40 {
41
42 Rect
43 ParseRect(const string& str)
44 {
45 std::istringstream iss(str);
46 int buf[4];
47
48 for(size_t i(0); i < 4; ++i)
49 if(iss)
50 iss >> buf[i];
51 else
52 throw std::invalid_argument("Parse 'Rect' failed: bad state.");
53 // FIXME: Complete max value checking.
54 if(buf[2] < 0 || buf[3] < 0)
55 throw std::invalid_argument("Parse 'Rect' failed: underflow.");
56
57 Rect res(buf[0], buf[1], buf[2], buf[3]);
58
59 YTraceDe(Informative, "ParseRect: %s.", to_string(res).c_str());
60
61 return res;
62 }
63
64
65 IWidget&
66 AccessWidget(const ValueNode& node)
67 {
68 try
69 {
70 const auto& p(AccessChild<shared_ptr<IWidget>>(node, "$pointer"));
71
72 YAssertNonnull(p);
73
74 return *p;
75 }
76 catch(std::out_of_range&)
77 {
78 throw WidgetNotFound(node.GetName(), "Widget pointer not found.");
79 }
80 }
81
82
83 unique_ptr<IWidget>
84 WidgetLoader::DetectWidgetNode(const ValueNode& node)
85 {
86 try
87 {
88 const auto& type_str(AccessChild<string>(node, "$type"));
89
90 if(const auto* p_bounds_str = AccessChildPtr<string>(node, "$bounds"))
91 try
92 {
93 const Rect& bounds(ParseRect(*p_bounds_str));
94
95 return Bounds.Call(type_str, bounds);
96 }
97 catch(std::invalid_argument&)
98 {}
99 return Default.Call(type_str);
100 }
101 catch(ystdex::bad_any_cast&)
102 {}
103 return {};
104 }
105
106 ValueNode
107 WidgetLoader::LoadUILayout(const string& str)
108 {
109 return TransformUILayout(
110 NPL::LoadNPLA1(NPL::SContext::Analyze(NPL::Session(str))));
111 }
112
113 ValueNode
114 WidgetLoader::TransformUILayout(const ValueNode& node)
115 {
116 if(unique_ptr<IWidget> p_new_widget{DetectWidgetNode(node)})
117 {
118 ValueNode res(0, node.GetName());
119 const auto& key(AccessChild<string>(node, "$type"));
120 const bool ins(Insert.Contains(key));
121 const bool insz(InsertZOrdered.Contains(key));
122
123 if(ins || insz)
124 {
125 auto p_con(make_unique<ValueNode::Container>());
126
127 for(const auto& vn : node)
128 if(CheckChildName(vn.GetName()))
129 try
130 {
131 if(ValueNode child{TransformUILayout(vn)})
132 {
133 auto& wgt(*AccessChild<shared_ptr<IWidget>>(child,
134 "$pointer"));
135 const auto p_z(AccessChildPtr<string>(vn, "$z"));
136 auto z(DefaultZOrder);
137
138 if(insz && p_z)
139 try
140 {
141 const auto r(std::stoul(*p_z));
142
143 // XXX: Do not use magic number.
144 if(r < 0x100)
145 z = r;
146 }
147 catch(std::invalid_argument&)
148 {}
149 if(p_con->insert(std::move(child)).second)
150 {
151 if(insz && (p_z || !ins))
152 InsertZOrdered.Call(key, *p_new_widget, wgt,
153 z);
154 else
155 Insert.Call(key, *p_new_widget, wgt);
156 }
157 }
158 }
159 catch(ystdex::bad_any_cast&)
160 {}
161 res += {0, "$children", std::move(p_con), PointerTag()};
162 }
163 res += {0, "$pointer", shared_ptr<IWidget>(std::move(p_new_widget))};
164 return res;
165 }
166 return {};
167 }
168
169 } // namespace UI;
170
171 } // namespace YSLib;
172
NPL::Session
会话：分析指定 NPL 代码。
Definition: SContext.h:54
YSLib::UI::WidgetLoader::Insert
GWidgetInserterRegister< IWidget & > Insert
Definition: Loader.h:228
YSLib::UI::WidgetLoader::DetectWidgetNode
unique_ptr< IWidget > DetectWidgetNode(const ValueNode &)
Definition: Loader.cpp:84
ystdex::bad_any_cast
动态泛型转换失败异常。
Definition: any.h:741
YSLib::UI::WidgetLoader::InsertZOrdered
GWidgetInserterRegister< IWidget &, const ZOrderType & > InsertZOrdered
Definition: Loader.h:230
YModules.h
YSLib::Drawing::bounds
bounds
Definition: ydraw.h:188
NPL::LoadNPLA1
YF_API ValueNode LoadNPLA1(ValueNode &&)
读取 NPLA1 翻译单元。
Definition: NPLA1.cpp:86
YSLib::UI::WidgetLoader::TransformUILayout
ValueNode TransformUILayout(const ValueNode &)
Definition: Loader.cpp:114
NPL::SContext::Analyze
YF_API void Analyze(ValueNode &, const TokenList &)
分析指定源，取抽象语法树储存至指定值类型节点。
Definition: SContext.cpp:96
YSLib::PointerTag
指示指针的标记。
Definition: yobject.h:63
YModules.h
platform::Descriptions::Informative
Definition: ycommon.h:77
YSLib::UI::wgt
_tWidget & wgt
Definition: ywgtevt.h:596
YSLib::Drawing::Rect
屏幕标准矩形：表示屏幕矩形区域。
Definition: ygdibase.h:416
YSLib::ValueNode
值类型节点。
Definition: ValueNode.h:45
YAssertNonnull
#define YAssertNonnull(_expr)
Definition: cassert.h:81
YSLib::UI::WidgetLoader::Bounds
GWidgetRegister< const Rect & > Bounds
Definition: Loader.h:226
YSLib::UI::AccessWidget
IWidget & AccessWidget(const ValueNode &node, const string &name, _tParams &&...args)
Definition: Loader.h:135
YSLib::UI::DefaultZOrder
const ZOrderType DefaultZOrder(64)
默认 Z 顺序值。
ystdex::to_string
std::string to_string(unsigned char val)
转换为字符串。
Definition: string.hpp:353
YSLib::UI::WidgetLoader::Default
GWidgetRegister Default
Definition: Loader.h:225
YTraceDe
#define YTraceDe(...)
YCLib 默认调试跟踪。
Definition: Debug.h:269
YSLib::UI::ParseRect
YF_API Rect ParseRect(const string &)
Definition: Loader.cpp:43
YSLib::Drawing::r
bounds & r
Definition: ydraw.h:220
YSLib::UI::CheckChildName
bool CheckChildName(const string &str)
Definition: Loader.h:75
YSLib::UI::WidgetLoader::LoadUILayout
ValueNode LoadUILayout(const string &)
Definition: Loader.cpp:107
YSLib::UI::WidgetNotFound
找不到部件。
Definition: Loader.h:86