Skip to content

Commit 11c32d6

Browse files
committed
[ECSCircuit] Clean up reflection in UIScene into Capabilities
1 parent e344422 commit 11c32d6

8 files changed

Lines changed: 514 additions & 421 deletions

File tree

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#pragma once
2+
#include "ECSCircuit/Components/ClickableC.h"
3+
#include "ECSCircuit/Core/Reflection.h"
4+
#include "ECSCircuit/Core/Widget.h"
5+
6+
#include <entt.hpp>
7+
8+
namespace UI
9+
{
10+
class UIScene;
11+
12+
template<typename T>
13+
concept HasOnClickBegin = requires
14+
{
15+
static_cast<void (*)(UIScene&, Widget, T&, const ClickInteraction&)>(&T::OnClickBegin);
16+
};
17+
template<typename T>
18+
concept HasAnyOnClickBegin = requires { T::OnClickBegin; };
19+
template<typename T>
20+
concept HasOnClickBeginWithWrongParameters = !HasOnClickBegin<T> && HasAnyOnClickBegin<T>;
21+
22+
template<typename T>
23+
concept HasOnClicked = requires
24+
{
25+
static_cast<void (*)(UIScene&, Widget, T&, const ClickInteraction&)>(&T::OnClicked);
26+
};
27+
template<typename T>
28+
concept HasAnyOnClicked = requires { T::OnClicked; };
29+
template<typename T>
30+
concept HasOnClickedWithWrongParameters = !HasOnClicked<T> && HasAnyOnClicked<T>;
31+
32+
template<typename T>
33+
concept HasOnClickCancelled = requires
34+
{
35+
static_cast<void (*)(UIScene&, Widget, T&, const ClickInteraction&)>(&T::OnClickCancelled);
36+
};
37+
template<typename T>
38+
concept HasAnyOnClickCancelled = requires { T::OnClickCancelled; };
39+
template<typename T>
40+
concept HasOnClickCancelledWithWrongParameters = !HasOnClickCancelled<T> && HasAnyOnClickCancelled<T>;
41+
42+
template<typename T>
43+
concept HasAnyClickHandler = HasOnClickBegin<T> || HasOnClicked<T> || HasOnClickCancelled<T>;
44+
45+
namespace Detail
46+
{
47+
template<typename TWidget>
48+
void OnClickBeginDispatch(UIScene& ui, Widget self, const ClickInteraction& interaction)
49+
{
50+
TWidget::OnClickBegin(ui, self, self.GetComponent<TWidget>(), interaction);
51+
}
52+
53+
template<typename TWidget>
54+
void OnClickedDispatch(UIScene& ui, Widget self, const ClickInteraction& interaction)
55+
{
56+
TWidget::OnClicked(ui, self, self.GetComponent<TWidget>(), interaction);
57+
}
58+
59+
template<typename TWidget>
60+
void OnClickCancelledDispatch(UIScene& ui, Widget self, const ClickInteraction& interaction)
61+
{
62+
TWidget::OnClickCancelled(ui, self, self.GetComponent<TWidget>(), interaction);
63+
}
64+
}
65+
66+
struct ClickCapability
67+
{
68+
template<typename TWidget>
69+
static constexpr void Validate()
70+
{
71+
if constexpr (HasAnyOnClickBegin<TWidget>)
72+
{
73+
static_assert(!HasOnClickBeginWithWrongParameters<TWidget>,
74+
"OnClickBegin function has invalid arguments! Should be: OnClickBegin(UIScene&, Widget, TWidget&, const ClickInteraction&)");
75+
}
76+
if constexpr (HasAnyOnClicked<TWidget>)
77+
{
78+
static_assert(!HasOnClickedWithWrongParameters<TWidget>,
79+
"OnClicked function has invalid arguments! Should be: OnClicked(UIScene&, Widget, TWidget&, const ClickInteraction&)");
80+
}
81+
if constexpr (HasAnyOnClickCancelled<TWidget>)
82+
{
83+
static_assert(!HasOnClickCancelledWithWrongParameters<TWidget>,
84+
"OnClickCancelled function has invalid arguments! Should be: OnClickCancelled(UIScene&, Widget, TWidget&, const ClickInteraction&)");
85+
}
86+
}
87+
88+
template<typename TWidget>
89+
static void Bind(entt::handle handle)
90+
{
91+
if constexpr (HasAnyClickHandler<TWidget>)
92+
{
93+
if constexpr (!HasComponent<TWidget, ClickableC>)
94+
{
95+
Detail::AddComponentWithRequires<ClickableC>(handle);
96+
}
97+
ClickableC& clickable = handle.get<ClickableC>();
98+
if constexpr (HasOnClickBegin<TWidget>)
99+
{
100+
clickable.staticOnClickBegin = &Detail::OnClickBeginDispatch<TWidget>;
101+
}
102+
if constexpr (HasOnClicked<TWidget>)
103+
{
104+
clickable.staticOnClicked = &Detail::OnClickedDispatch<TWidget>;
105+
}
106+
if constexpr (HasOnClickCancelled<TWidget>)
107+
{
108+
clickable.staticOnClickCancelled = &Detail::OnClickCancelledDispatch<TWidget>;
109+
}
110+
}
111+
}
112+
};
113+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#pragma once
2+
#include "ECSCircuit/Capabilities/ClickCapability.h"
3+
#include "ECSCircuit/Capabilities/DragCapability.h"
4+
#include "ECSCircuit/Capabilities/HoverCapability.h"
5+
#include "ECSCircuit/Capabilities/LayoutCapability.h"
6+
#include "ECSCircuit/Capabilities/PaintCapability.h"
7+
8+
#include <entt.hpp>
9+
10+
namespace UI
11+
{
12+
template<typename... TCapabilities>
13+
class Capabilities {};
14+
15+
using CoreCapabilities = Capabilities<
16+
PaintCapability,
17+
LayoutCapability,
18+
ClickCapability,
19+
HoverCapability,
20+
DragCapability>;
21+
22+
namespace Detail
23+
{
24+
template<typename TWidget, typename... TCapabilities>
25+
void ApplyCapabilities(entt::handle handle, Capabilities<TCapabilities...>)
26+
{
27+
(TCapabilities::template Validate<TWidget>(), ...);
28+
(TCapabilities::template Bind<TWidget>(handle), ...);
29+
}
30+
}
31+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#pragma once
2+
#include "ECSCircuit/Components/DraggableC.h"
3+
#include "ECSCircuit/Core/Reflection.h"
4+
#include "ECSCircuit/Core/Widget.h"
5+
6+
#include <entt.hpp>
7+
8+
namespace UI
9+
{
10+
class UIScene;
11+
12+
template<typename T>
13+
concept HasOnDragBegin = requires
14+
{
15+
static_cast<void (*)(UIScene&, Widget, T&, const DragInteraction&)>(&T::OnDragBegin);
16+
};
17+
template<typename T>
18+
concept HasAnyOnDragBegin = requires { T::OnDragBegin; };
19+
template<typename T>
20+
concept HasOnDragBeginWithWrongParameters = !HasOnDragBegin<T> && HasAnyOnDragBegin<T>;
21+
22+
template<typename T>
23+
concept HasOnDrag = requires
24+
{
25+
static_cast<void (*)(UIScene&, Widget, T&, const DragInteraction&)>(&T::OnDrag);
26+
};
27+
template<typename T>
28+
concept HasAnyOnDrag = requires { T::OnDrag; };
29+
template<typename T>
30+
concept HasOnDragWithWrongParameters = !HasOnDrag<T> && HasAnyOnDrag<T>;
31+
32+
template<typename T>
33+
concept HasOnDragEnd = requires
34+
{
35+
static_cast<void (*)(UIScene&, Widget, T&, const DragInteraction&)>(&T::OnDragEnd);
36+
};
37+
template<typename T>
38+
concept HasAnyOnDragEnd = requires { T::OnDragEnd; };
39+
template<typename T>
40+
concept HasOnDragEndWithWrongParameters = !HasOnDragEnd<T> && HasAnyOnDragEnd<T>;
41+
42+
template<typename T>
43+
concept HasAnyDragHandler = HasOnDragBegin<T> || HasOnDrag<T> || HasOnDragEnd<T>;
44+
45+
namespace Detail
46+
{
47+
template<typename TWidget>
48+
void OnDragBeginDispatch(UIScene& ui, Widget self, const DragInteraction& interaction)
49+
{
50+
TWidget::OnDragBegin(ui, self, self.GetComponent<TWidget>(), interaction);
51+
}
52+
53+
template<typename TWidget>
54+
void OnDragDispatch(UIScene& ui, Widget self, const DragInteraction& interaction)
55+
{
56+
TWidget::OnDrag(ui, self, self.GetComponent<TWidget>(), interaction);
57+
}
58+
59+
template<typename TWidget>
60+
void OnDragEndDispatch(UIScene& ui, Widget self, const DragInteraction& interaction)
61+
{
62+
TWidget::OnDragEnd(ui, self, self.GetComponent<TWidget>(), interaction);
63+
}
64+
}
65+
66+
struct DragCapability
67+
{
68+
template<typename TWidget>
69+
static constexpr void Validate()
70+
{
71+
if constexpr (HasAnyOnDragBegin<TWidget>)
72+
{
73+
static_assert(!HasOnDragBeginWithWrongParameters<TWidget>,
74+
"OnDragBegin function has invalid arguments! Should be: OnDragBegin(UIScene&, Widget, TWidget&, const DragInteraction&)");
75+
}
76+
if constexpr (HasAnyOnDrag<TWidget>)
77+
{
78+
static_assert(!HasOnDragWithWrongParameters<TWidget>,
79+
"OnDrag function has invalid arguments! Should be: OnDrag(UIScene&, Widget, TWidget&, const DragInteraction&)");
80+
}
81+
if constexpr (HasAnyOnDragEnd<TWidget>)
82+
{
83+
static_assert(!HasOnDragEndWithWrongParameters<TWidget>,
84+
"OnDragEnd function has invalid arguments! Should be: OnDragEnd(UIScene&, Widget, TWidget&, const DragInteraction&)");
85+
}
86+
}
87+
88+
template<typename TWidget>
89+
static void Bind(entt::handle handle)
90+
{
91+
if constexpr (HasAnyDragHandler<TWidget>)
92+
{
93+
if constexpr (!HasComponent<TWidget, DraggableC>)
94+
{
95+
Detail::AddComponentWithRequires<DraggableC>(handle);
96+
}
97+
DraggableC& draggable = handle.get<DraggableC>();
98+
if constexpr (HasOnDragBegin<TWidget>)
99+
{
100+
draggable.staticOnDragBegin = &Detail::OnDragBeginDispatch<TWidget>;
101+
}
102+
if constexpr (HasOnDrag<TWidget>)
103+
{
104+
draggable.staticOnDrag = &Detail::OnDragDispatch<TWidget>;
105+
}
106+
if constexpr (HasOnDragEnd<TWidget>)
107+
{
108+
draggable.staticOnDragEnd = &Detail::OnDragEndDispatch<TWidget>;
109+
}
110+
}
111+
}
112+
};
113+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#pragma once
2+
#include "ECSCircuit/Components/HoverableC.h"
3+
#include "ECSCircuit/Core/Reflection.h"
4+
#include "ECSCircuit/Core/Widget.h"
5+
6+
#include <entt.hpp>
7+
8+
namespace UI
9+
{
10+
class UIScene;
11+
12+
template<typename T>
13+
concept HasOnHoverBegin = requires
14+
{
15+
static_cast<void (*)(UIScene&, Widget, T&)>(&T::OnHoverBegin);
16+
};
17+
template<typename T>
18+
concept HasAnyOnHoverBegin = requires { T::OnHoverBegin; };
19+
template<typename T>
20+
concept HasOnHoverBeginWithWrongParameters = !HasOnHoverBegin<T> && HasAnyOnHoverBegin<T>;
21+
22+
template<typename T>
23+
concept HasOnHoverEnd = requires
24+
{
25+
static_cast<void (*)(UIScene&, Widget, T&)>(&T::OnHoverEnd);
26+
};
27+
template<typename T>
28+
concept HasAnyOnHoverEnd = requires { T::OnHoverEnd; };
29+
template<typename T>
30+
concept HasOnHoverEndWithWrongParameters = !HasOnHoverEnd<T> && HasAnyOnHoverEnd<T>;
31+
32+
template<typename T>
33+
concept HasAnyHoverHandler = HasOnHoverBegin<T> || HasOnHoverEnd<T>;
34+
35+
namespace Detail
36+
{
37+
template<typename TWidget>
38+
void OnHoverBeginDispatch(UIScene& ui, Widget self)
39+
{
40+
TWidget::OnHoverBegin(ui, self, self.GetComponent<TWidget>());
41+
}
42+
43+
template<typename TWidget>
44+
void OnHoverEndDispatch(UIScene& ui, Widget self)
45+
{
46+
TWidget::OnHoverEnd(ui, self, self.GetComponent<TWidget>());
47+
}
48+
}
49+
50+
struct HoverCapability
51+
{
52+
template<typename TWidget>
53+
static constexpr void Validate()
54+
{
55+
if constexpr (HasAnyOnHoverBegin<TWidget>)
56+
{
57+
static_assert(!HasOnHoverBeginWithWrongParameters<TWidget>,
58+
"OnHoverBegin function has invalid arguments! Should be: OnHoverBegin(UIScene&, Widget, TWidget&)");
59+
}
60+
if constexpr (HasAnyOnHoverEnd<TWidget>)
61+
{
62+
static_assert(!HasOnHoverEndWithWrongParameters<TWidget>,
63+
"OnHoverEnd function has invalid arguments! Should be: OnHoverEnd(UIScene&, Widget, TWidget&)");
64+
}
65+
}
66+
67+
template<typename TWidget>
68+
static void Bind(entt::handle handle)
69+
{
70+
if constexpr (HasAnyHoverHandler<TWidget>)
71+
{
72+
if constexpr (!HasComponent<TWidget, HoverableC>)
73+
{
74+
Detail::AddComponentWithRequires<HoverableC>(handle);
75+
}
76+
HoverableC& hoverable = handle.get<HoverableC>();
77+
if constexpr (HasOnHoverBegin<TWidget>)
78+
{
79+
hoverable.staticOnHoverBegin = &Detail::OnHoverBeginDispatch<TWidget>;
80+
}
81+
if constexpr (HasOnHoverEnd<TWidget>)
82+
{
83+
hoverable.staticOnHoverEnd = &Detail::OnHoverEndDispatch<TWidget>;
84+
}
85+
}
86+
}
87+
};
88+
}

0 commit comments

Comments
 (0)