added constexpr hash based enum for faster switch on attributes and node names

This commit is contained in:
2017-01-27 22:09:37 +00:00
parent d413e49821
commit 7436706b37
3 changed files with 81 additions and 57 deletions

View File

@@ -1,8 +1,8 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<layout> <layout>
<flex dir="col" wrap="0" width="100%" height="100%" pad="5"> <node dir="col" wrap="0" width="100%" height="100%" pad="5">
<!-- toolbar --> <!-- toolbar -->
<plane height="50" width="100%" pad="5" dir="row" color=".2"> <border height="50" width="100%" pad="5" dir="row" color=".2">
<plane width="50" margin="0 5 0 0" color=".1"></plane> <plane width="50" margin="0 5 0 0" color=".1"></plane>
<plane width="50" margin="0 5 0 0" color=".2"></plane> <plane width="50" margin="0 5 0 0" color=".2"></plane>
<plane width="50" margin="0 5 0 0" color=".3"></plane> <plane width="50" margin="0 5 0 0" color=".3"></plane>
@@ -14,7 +14,7 @@
<plane width="50" margin="0 5 0 0"></plane> <plane width="50" margin="0 5 0 0"></plane>
<plane width="50" margin="0 5 0 0"></plane> <plane width="50" margin="0 5 0 0"></plane>
<plane width="50" margin="0 5 0 0"></plane> <plane width="50" margin="0 5 0 0"></plane>
</plane> </border>
<!-- central row --> <!-- central row -->
<plane grow="1" dir="row" wrap="1" height="0"> <plane grow="1" dir="row" wrap="1" height="0">
<!-- side bar --> <!-- side bar -->
@@ -39,5 +39,5 @@
</plane> </plane>
<!-- status bar --> <!-- status bar -->
<plane height="30" width="100%" /> <plane height="30" width="100%" />
</flex> </node>
</layout> </layout>

View File

@@ -21,7 +21,7 @@ void Node::update_internal(glm::vec2 origin)
m_clip = glm::vec4(m_pos, m_size); m_clip = glm::vec4(m_pos, m_size);
else else
m_clip = rect_intersection(glm::vec4(m_pos, m_size), parent->m_clip); m_clip = rect_intersection(glm::vec4(m_pos, m_size), parent->m_clip);
for (auto& c : children) for (auto& c : m_children)
c.update_internal(m_pos); c.update_internal(m_pos);
} }
@@ -165,7 +165,7 @@ void Node::load(const char* path)
m_file_info = tmp_info; m_file_info = tmp_info;
m_path = path; m_path = path;
children.clear(); m_children.clear();
YGNodeReset(y_node); YGNodeReset(y_node);
tinyxml2::XMLDocument xml; tinyxml2::XMLDocument xml;
@@ -177,10 +177,11 @@ void Node::load(const char* path)
void Node::load_internal(const tinyxml2::XMLElement* x_node) void Node::load_internal(const tinyxml2::XMLElement* x_node)
{ {
m_name = x_node->Name();
auto attr = x_node->FirstAttribute(); auto attr = x_node->FirstAttribute();
while (attr) while (attr)
{ {
parse_attributes(att::value(attr->Name()), attr); parse_attributes((att::kAttribute)att::const_hash(attr->Name()), attr);
attr = attr->Next(); attr = attr->Next();
} }
@@ -188,8 +189,8 @@ void Node::load_internal(const tinyxml2::XMLElement* x_node)
while (x_child) while (x_child)
{ {
//Node n; //Node n;
children.emplace_back(); m_children.emplace_back();
auto& n = children.back(); auto& n = m_children.back();
n.parent = this; n.parent = this;
YGNodeInsertChild(y_node, n.y_node, YGNodeGetChildCount(y_node)); YGNodeInsertChild(y_node, n.y_node, YGNodeGetChildCount(y_node));
n.load_internal(x_child); n.load_internal(x_child);

View File

@@ -2,13 +2,36 @@
namespace att namespace att
{ {
enum class kAttribute : uint8_t { uint16_t constexpr const_hash(char const *input)
Width, MinWidth, MaxWidth, {
Height, MinHeight, MaxHeight, return *input ?
Divisions, InnerRadius, OuterRadius, static_cast<uint16_t>(*input) + 33 * const_hash(input + 1) :
Grow, Shrink, FlexDir, FlexWrap, 5381;
Padding, Margin, }
Color
enum class kAttribute : uint16_t
{
Width = const_hash("width"),
MinWidth = const_hash("max-width"),
MaxWidth = const_hash("min-width"),
Height = const_hash("height"),
MinHeight = const_hash("min-height"),
MaxHeight = const_hash("max-height"),
Divisions = const_hash("divisions"),
InnerRadius = const_hash("inner-radius"),
OuterRadius = const_hash("outer-radius"),
Grow = const_hash("grow"),
Shrink = const_hash("shrink"),
FlexDir = const_hash("dir"),
FlexWrap = const_hash("wrap"),
Padding = const_hash("pad"),
Margin = const_hash("margin"),
Color = const_hash("color"),
};
enum class kWidget : uint16_t
{
Border = const_hash("border"),
}; };
struct AttributeBase struct AttributeBase
@@ -27,50 +50,37 @@ namespace att
Attribute(V v) : value(v) { id = static_id; } Attribute(V v) : value(v) { id = static_id; }
}; };
struct typemap struct kAttributeMap
{ {
const char* name;
kAttribute value; kAttribute value;
const char* name;
}; };
static constexpr typemap map[] = static constexpr kAttributeMap map[] =
{ {
{ "width", kAttribute::Width }, { kAttribute::Width, "width" },
{ "min-width", kAttribute::MinWidth }, { kAttribute::MinWidth, "min-width" },
{ "max-width", kAttribute::MaxWidth }, { kAttribute::MaxWidth, "max-width" },
{ "height", kAttribute::Height }, { kAttribute::Height, "height" },
{ "min-height", kAttribute::MinHeight }, { kAttribute::MinHeight, "min-height" },
{ "max-height", kAttribute::MaxHeight }, { kAttribute::MaxHeight, "max-height" },
{ "divisions", kAttribute::Divisions }, { kAttribute::Divisions, "divisions" },
{ "inner-radius", kAttribute::InnerRadius }, { kAttribute::InnerRadius, "inner-radius" },
{ "outer-radius", kAttribute::OuterRadius }, { kAttribute::OuterRadius, "outer-radius" },
{ "grow", kAttribute::Grow }, { kAttribute::Grow, "grow" },
{ "shrink", kAttribute::Shrink }, { kAttribute::Shrink, "shrink" },
{ "dir", kAttribute::FlexDir }, { kAttribute::FlexDir, "dir" },
{ "wrap", kAttribute::FlexWrap }, { kAttribute::FlexWrap, "wrap" },
{ "pad", kAttribute::Padding }, { kAttribute::Padding, "pad" },
{ "margin", kAttribute::Margin }, { kAttribute::Margin, "margin" },
{ "color", kAttribute::Color }, { kAttribute::Color, "color" },
}; };
static constexpr int map_size = sizeof(map) / sizeof(typemap) - 1;
constexpr bool same(const char* a, const char* b)
{
return (*a && *b) ? (*a == *b && same(a + 1, b + 1)) : !(*a || *b);
}
constexpr const kAttribute value(char const *name, int i = 0)
{
return ((i >= map_size) || same(map[i].name, name)) ?
map[i].value : value(name, i + 1);
}
constexpr const char* string(const kAttribute value, int i = 0) constexpr const char* string(const kAttribute value, int i = 0)
{ {
// no check on size, value MUST be found
return (map[i].value == value) ? map[i].name : string(value, i + 1); return (map[i].value == value) ? map[i].name : string(value, i + 1);
} }
//constexpr const char* string(kAttribute a) { return names[(int)a]; }
// template<kAttribute T, typename V>
// constexpr const char* string(const Attribute<T, V> a) { return names[(int)a.id]; }
#define DECLARE_ATTRIBUTE(N,T) \ #define DECLARE_ATTRIBUTE(N,T) \
struct N : public Attribute<kAttribute::N,T> \ struct N : public Attribute<kAttribute::N,T> \
{ using Attribute<kAttribute::N,T>::Attribute; }; { using Attribute<kAttribute::N,T>::Attribute; };
@@ -95,6 +105,17 @@ namespace att
#undef DECLARE_ATTRIBUTE #undef DECLARE_ATTRIBUTE
} }
class Widget
{
};
class WidgetBorder : public Widget
{
public:
static class Plane* m_plane;
};
class Node class Node
{ {
const Node* parent{ nullptr }; const Node* parent{ nullptr };
@@ -103,25 +124,27 @@ class Node
std::string m_path; std::string m_path;
public: public:
std::vector<Node> children; std::vector<Node> m_children;
glm::vec4 color; std::unique_ptr<Widget> m_widget;
glm::vec2 m_pos; glm::vec2 m_pos;
glm::vec2 m_size; glm::vec2 m_size;
glm::vec4 m_clip; glm::vec4 m_clip;
glm::vec4 color;
std::string m_name;
Node(const Node&) = delete; Node(const Node&) = delete;
Node& operator=(const Node&) = delete; Node& operator=(const Node&) = delete;
Node&& operator=(Node&& o) { return std::forward<Node>(o); } Node&& operator=(Node&& o) { return std::forward<Node>(o); }
Node(Node&& o) Node(Node&& o)
{ {
children = std::move(o.children); m_children = std::move(o.m_children);
for (auto& c : children) for (auto& c : m_children)
c.parent = this; c.parent = this;
parent = o.parent; parent = o.parent;
y_node = o.y_node; y_node = o.y_node;
color = o.color;
m_pos = o.m_pos; m_pos = o.m_pos;
m_size = o.m_size; m_size = o.m_size;
m_clip = o.m_clip; m_clip = o.m_clip;
color = o.color;
m_file_info = o.m_file_info; m_file_info = o.m_file_info;
o.y_node = nullptr; o.y_node = nullptr;
o.parent = nullptr; o.parent = nullptr;
@@ -129,7 +152,7 @@ public:
Node() { y_node = YGNodeNew(); } Node() { y_node = YGNodeNew(); }
~Node() ~Node()
{ {
children.clear(); m_children.clear();
if (y_node) if (y_node)
YGNodeFree(y_node); YGNodeFree(y_node);
} }
@@ -183,7 +206,7 @@ public:
iterator& operator++() iterator& operator++()
{ {
m_nodes.pop(); m_nodes.pop();
for (auto& c : m_current->children) for (auto& c : m_current->m_children)
m_nodes.push(&c); m_nodes.push(&c);
m_current = m_nodes.size() ? m_nodes.top() : nullptr; m_current = m_nodes.size() ? m_nodes.top() : nullptr;
return *this; return *this;