YSTest: Loader.cpp 源文件

YSTest PreAlpha_b800_20170810 The YSLib Test Project

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

- 文件列表
- 文件成员

Loader.cpp
浏览该文件的文档.
1 /*
2 © 2013-2016 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 Rect res;
46
47 try
48 {
49 std::istringstream iss(str);
50
51 iss.exceptions(std::ios::failbit | std::ios::badbit);
52 iss >> res.X >> res.Y >> res.Width >> res.Height;
53 }
54 catch(std::exception& e)
55 {
56 YTraceDe(Warning, "Error: %s", e.what());
57 throw std::invalid_argument("Parse 'Rect' failed: bad state.");
58 }
59 YTraceDe(Debug, "ParseRect: %s.", to_string(res).c_str());
60 return res;
61 }
62
63
64 ImplDeDtor(WidgetNotFound)
65
66
67 IWidget&
68 AccessWidget(const ValueNode& node)
69 {
70 if(const auto p = AccessNodePtr(node, "$pointer"))
71 // NOTE: It may still throw %ystdex::bad_any_cast.
72 return Deref(Access<shared_ptr<IWidget>>(*p));
73 throw WidgetNotFound(node.GetName(), "Widget pointer not found.");
74 }
75
76
77 unique_ptr<IWidget>
78 WidgetLoader::DetectWidgetNode(const ValueNode& node)
79 {
80 const auto& child(AccessNode(node, "$type"));
81
82 if(const auto p_type_str = AccessPtr<string>(child))
83 {
84 if(const auto p_bounds_str = AccessChildPtr<string>(node, "$bounds"))
85 try
86 {
87 const Rect& bounds(ParseRect(*p_bounds_str));
88
89 return Bounds.Call(*p_type_str, bounds);
90 }
91 CatchIgnore(std::invalid_argument&)
92 return Default.Call(*p_type_str);
93 }
94 return {};
95 }
96
97 ValueNode
98 WidgetLoader::LoadUILayout(string_view sv)
99 {
100 using namespace NPL;
101
102 return TransformUILayout(A1::LoadNode(SContext::Analyze(sv)));
103 }
104
105 ValueNode
106 WidgetLoader::TransformUILayout(const ValueNode& node)
107 {
108 if(unique_ptr<IWidget> p_new_widget{DetectWidgetNode(node)})
109 {
110 ValueNode res(AsNode(node.GetName()));
111 const auto& key(AccessChild<string>(node, "$type"));
112 const bool ins(Insert.Contains(key));
113 const bool insz(InsertZOrdered.Contains(key));
114
115 if(ins || insz)
116 {
117 ValueNode::Container node_con;
118
119 for(const auto& vn : node)
120 if(CheckChildName(vn.GetName()))
121 if(ValueNode child{TransformUILayout(vn)})
122 {
123 const auto& wgt_ptr_nd(AccessNode(child, "$pointer"));
124
125 if(const auto p_wgt_ptr
126 = AccessPtr<shared_ptr<IWidget>>(wgt_ptr_nd))
127 {
128 const auto& wgt_ptr(Deref(p_wgt_ptr));
129
130 const auto p_z(AccessChildPtr<string>(vn, "$z"));
131 auto z(DefaultZOrder);
132
133 if(insz && p_z)
134 try
135 {
136 const auto r(std::stoul(*p_z));
137
138 // TODO: Do not use magic number.
139 if(r < 0x100)
140 z = r;
141 }
142 CatchIgnore(std::invalid_argument&)
143 if(node_con.insert(std::move(child)).second)
144 {
145 auto& wgt(*wgt_ptr);
146
147 if(insz && (p_z || !ins))
148 InsertZOrdered.Call(key, *p_new_widget, wgt,
149 z);
150 else
151 Insert.Call(key, *p_new_widget, wgt);
152 }
153 }
154 }
155 res += {std::move(node_con), "$children"};
156 }
157 res += AsNode("$pointer", shared_ptr<IWidget>(std::move(p_new_widget)));
158 return res;
159 }
160 return {};
161 }
162
163 } // namespace UI;
164
165 } // namespace YSLib;
166
YTraceDe
#define YTraceDe(...)
YCLib 默认调试跟踪。
Definition: Debug.h:313
YSLib::UI::WidgetLoader::InsertZOrdered
GWidgetInserterRegister< IWidget &, const ZOrder & > InsertZOrdered
Definition: Loader.h:244
platform::Descriptions::Debug
Definition: YCommon.h:170
YSLib::UI::DefaultZOrder
const ZOrder DefaultZOrder(64)
默认 Z 顺序值。
YSLib::Drawing::GBinaryGroup::Y
_type Y
分量。
Definition: YGDIBase.h:63
YSLib
YSLib 命名空间。
Definition: AndroidHost.h:45
ystdex::to_string
std::string to_string(const std::thread::id &)
转换 thread::id 为字符串表示。
UI
platform::Deref
yconstfn auto Deref(_type &&p) -> decltype(*p)
断言并解引用非空指针。
Definition: Debug.h:451
YSLib::Drawing::r
The boundary is out of the const Graphics const Rect const Point const Point Color c const Rect const Rect & r
Definition: YDraw.h:174
YSLib::UI::WidgetLoader::LoadUILayout
ValueNode LoadUILayout(string_view)
加载 NPLA1 翻译单元，翻译后变换为 UI 布局树。
Definition: Loader.cpp:98
YModules.h
YSLib::UI::wgt
IWidget & wgt
Definition: YControl.h:112
NPL::c_str
YF_API const char src c_str())) YF_API void InstallDirectory(const string &
安装目录：复制目录树。
Definition: Dependency.h:131
CatchIgnore
#define CatchIgnore(_ex)
指定异常处理器忽略指定异常。
Definition: YBaseMacro.h:133
YSLib::UI::WidgetLoader::DetectWidgetNode
unique_ptr< IWidget > DetectWidgetNode(const ValueNode &)
异常中立：找不到内部类型节点。
Definition: Loader.cpp:78
YSLib::AccessNode
const ValueNode & AccessNode(const ValueNode &node, const _tKey &name)
Definition: ValueNode.h:866
YSLib::UI::AccessWidget
IWidget & AccessWidget(ValueNode &node, const string &name, _tParams &&...args)
Definition: Loader.h:148
YSLib::UI::WidgetLoader::Default
GWidgetRegister Default
Definition: Loader.h:239
NPL::A1::LoadNode
ValueNode LoadNode(_type &&tree, _tParams &&...args)
加载 NPLA1 翻译单元。
Definition: NPLA1.h:154
YSLib::AsNode
typename _tParams ValueNode AsNode(_tString &&str, _tParams &&...args)
Definition: ValueNode.h:1065
YSLib::Drawing::Size::Width
SDst Width
Definition: YGDIBase.h:302
YSLib::AccessNodePtr
YF_API observer_ptr< ValueNode > AccessNodePtr(ValueNode::Container &, const string &) ynothrow
访问节点指针。
Definition: ValueNode.cpp:113
YSLib::UI::e
void e
Definition: YWidget.h:352
YModules.h
YSLib::Drawing::Rect
屏幕标准矩形：表示屏幕矩形区域。
Definition: YGDIBase.h:540
YSLib::Drawing::Size::Height
SDst Height
宽和高。
Definition: YGDIBase.h:302
YSLib::ValueNode
值类型节点。
Definition: ValueNode.h:58
NPL
Definition: NPL/Configuration.h:34
ystdex::mapped_set
允许指定不同于值类型的键的集合。
Definition: set.hpp:160
YSLib::UI::WidgetLoader::Insert
GWidgetInserterRegister< IWidget & > Insert
Definition: Loader.h:242
platform::Descriptions::Warning
Definition: YCommon.h:167
YSLib::Text::str
const char const char * str
Definition: TextFile.h:81
YSLib::Drawing::GBinaryGroup::X
_type X
Definition: YGDIBase.h:63
YSLib::Drawing::bounds
The boundary is out of the const Rect & bounds
Definition: YDraw.h:127
ystdex::mapped_set::insert
std::pair< iterator, bool > insert(const value_type &x)
Definition: set.hpp:395
YSLib::UI::ParseRect
YF_API Rect ParseRect(const string &)
Definition: Loader.cpp:43
ystdex::string_view
basic_string_view< char > string_view
Definition: string_view.hpp:415
NPL::SContext::Analyze
YF_API void Analyze(TermNode &, const TokenList &)
分析指定源，取抽象语法树储存至指定值类型节点。
Definition: SContext.cpp:92
YSLib::UI::WidgetLoader::TransformUILayout
ValueNode TransformUILayout(const ValueNode &)
变换 UI 布局树：根据 NPLA1 中间表示动态创建部件树。 异常中立：找不到 $type 节点。 异常中立：$type 节�...
Definition: Loader.cpp:106
YSLib::UI::WidgetLoader::Bounds
GWidgetRegister< const Rect & > Bounds
Definition: Loader.h:240
CHRLib::p
const auto p(d)
YSLib::UI::ImplDeDtor
ImplDeDtor(Thumb) void DecorateAsCloseButton(Thumb &tmb)
Definition: Button.cpp:125