added constexpr hash based enum for faster switch on attributes and node names
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
119
engine/layout.h
119
engine/layout.h
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user