中间状态暂存
This commit is contained in:
@@ -0,0 +1,210 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "renderive/inheritance/Inheritance.hpp"
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
namespace inheritance = renderive::inheritance;
|
||||
|
||||
struct Object_Chain {};
|
||||
struct Implementation_Chain {};
|
||||
|
||||
enum class Registration_Position : std::size_t {
|
||||
root,
|
||||
reserved,
|
||||
implementation_parent,
|
||||
object_branch
|
||||
};
|
||||
|
||||
constexpr auto position(Registration_Position value) noexcept {
|
||||
return static_cast<std::size_t>(value);
|
||||
}
|
||||
|
||||
enum class Trace_Step {
|
||||
parent,
|
||||
child,
|
||||
object_branch
|
||||
};
|
||||
|
||||
enum class Test_Payload {
|
||||
ready
|
||||
};
|
||||
|
||||
struct Test_Event {
|
||||
Test_Payload payload{Test_Payload::ready};
|
||||
};
|
||||
|
||||
struct Trace {
|
||||
std::vector<Trace_Step> order;
|
||||
};
|
||||
|
||||
struct Test_Root : inheritance::Type_Root {
|
||||
explicit Test_Root(Trace& trace) : trace(&trace) {}
|
||||
Trace* trace;
|
||||
};
|
||||
|
||||
struct Parent_Impl
|
||||
: inheritance::Dispatch_Root<
|
||||
Parent_Impl, Test_Root, Implementation_Chain, Test_Event,
|
||||
position(Registration_Position::implementation_parent)> {
|
||||
using Dispatch_Root::Dispatch_Root;
|
||||
|
||||
struct Event_Handler {
|
||||
using Owner = Parent_Impl;
|
||||
static void handle(Parent_Impl& impl, const Test_Event&) {
|
||||
impl.trace->order.push_back(Trace_Step::parent);
|
||||
}
|
||||
};
|
||||
using Handler = Event_Handler;
|
||||
};
|
||||
|
||||
struct Child_Impl
|
||||
: inheritance::Dispatch_Node<Child_Impl, Parent_Impl,
|
||||
Implementation_Chain, Test_Event> {
|
||||
using Dispatch_Node::Dispatch_Node;
|
||||
|
||||
struct Event_Handler : Parent_Impl::Event_Handler {
|
||||
using Owner = Child_Impl;
|
||||
static void handle(Child_Impl& impl, const Test_Event&) {
|
||||
impl.trace->order.push_back(Trace_Step::child);
|
||||
}
|
||||
};
|
||||
using Handler = Event_Handler;
|
||||
};
|
||||
|
||||
struct Object_Node
|
||||
: inheritance::Type_Node<
|
||||
Object_Node, Test_Root, Object_Chain,
|
||||
position(Registration_Position::object_branch)> {
|
||||
using Type_Node::Type_Node;
|
||||
};
|
||||
|
||||
struct Impl_With_Object_Branch
|
||||
: inheritance::Dispatch_Node<
|
||||
Impl_With_Object_Branch, Child_Impl, Object_Chain, Test_Event,
|
||||
position(Registration_Position::object_branch)> {
|
||||
using Dispatch_Node::Dispatch_Node;
|
||||
|
||||
struct Event_Handler : Child_Impl::Event_Handler {
|
||||
using Owner = Impl_With_Object_Branch;
|
||||
static void handle(Impl_With_Object_Branch& impl,
|
||||
const Test_Event&) {
|
||||
impl.trace->order.push_back(Trace_Step::object_branch);
|
||||
}
|
||||
};
|
||||
using Handler = Event_Handler;
|
||||
};
|
||||
|
||||
struct Reverse_Declared_Registry {
|
||||
using Inheritance_Registry = inheritance::Registry<
|
||||
inheritance::Registration<
|
||||
Implementation_Chain,
|
||||
position(Registration_Position::object_branch), Child_Impl>,
|
||||
inheritance::Registration<
|
||||
Implementation_Chain,
|
||||
position(Registration_Position::implementation_parent),
|
||||
Parent_Impl>>;
|
||||
|
||||
Trace* trace;
|
||||
};
|
||||
|
||||
using Implementation_View = inheritance::Chain_View<
|
||||
typename Child_Impl::Inheritance_Registry, Implementation_Chain>;
|
||||
using Combined_Registry = inheritance::Merge_Registries_T<
|
||||
typename Child_Impl::Inheritance_Registry,
|
||||
typename Object_Node::Inheritance_Registry>;
|
||||
|
||||
inline constexpr std::size_t Implementation_Layer_Count =
|
||||
position(Registration_Position::object_branch) -
|
||||
position(Registration_Position::reserved);
|
||||
inline constexpr std::size_t Object_Layer_Count =
|
||||
position(Registration_Position::reserved) -
|
||||
position(Registration_Position::root);
|
||||
|
||||
static_assert(Implementation_View::count == Implementation_Layer_Count);
|
||||
static_assert(Implementation_View::next_position ==
|
||||
position(Registration_Position::object_branch) +
|
||||
Object_Layer_Count);
|
||||
static_assert(std::same_as<
|
||||
Implementation_View::Type<position(
|
||||
Registration_Position::implementation_parent)>,
|
||||
Parent_Impl>);
|
||||
static_assert(std::same_as<
|
||||
Implementation_View::Type<position(
|
||||
Registration_Position::object_branch)>,
|
||||
Child_Impl>);
|
||||
static_assert(inheritance::Chain_Registration_Count_V<
|
||||
Combined_Registry, Implementation_Chain> ==
|
||||
Implementation_Layer_Count);
|
||||
static_assert(inheritance::Chain_Registration_Count_V<Combined_Registry,
|
||||
Object_Chain> ==
|
||||
Object_Layer_Count);
|
||||
static_assert(std::same_as<
|
||||
inheritance::Type_At_Position_T<
|
||||
Combined_Registry, Object_Chain,
|
||||
position(Registration_Position::object_branch)>,
|
||||
Object_Node>);
|
||||
|
||||
TEST(inheritance_test, dispatches_parent_before_child) {
|
||||
Trace trace;
|
||||
Child_Impl child(trace);
|
||||
|
||||
child.dispatch(Test_Event{});
|
||||
|
||||
EXPECT_EQ(trace.order,
|
||||
(std::vector{Trace_Step::parent, Trace_Step::child}));
|
||||
}
|
||||
|
||||
TEST(inheritance_test, exposes_named_registration_positions) {
|
||||
EXPECT_EQ(Parent_Impl::Inheritance_Position,
|
||||
position(Registration_Position::implementation_parent));
|
||||
EXPECT_EQ(Child_Impl::Inheritance_Position,
|
||||
position(Registration_Position::object_branch));
|
||||
}
|
||||
|
||||
TEST(inheritance_test, dispatches_only_the_selected_chain) {
|
||||
Trace trace;
|
||||
Impl_With_Object_Branch value(trace);
|
||||
const Test_Event event{};
|
||||
|
||||
value.dispatch(event);
|
||||
EXPECT_EQ(trace.order, (std::vector{Trace_Step::object_branch}));
|
||||
|
||||
trace.order.clear();
|
||||
value.dispatch_for<Implementation_Chain>(event);
|
||||
EXPECT_EQ(trace.order,
|
||||
(std::vector{Trace_Step::parent, Trace_Step::child}));
|
||||
}
|
||||
|
||||
TEST(inheritance_test, initializes_registered_layers_by_position) {
|
||||
Trace trace;
|
||||
Reverse_Declared_Registry registered{&trace};
|
||||
|
||||
inheritance::initialize<Implementation_Chain>(
|
||||
registered,
|
||||
[&]<class Layer>(std::type_identity<Layer>,
|
||||
Reverse_Declared_Registry& value) {
|
||||
if constexpr (std::same_as<Layer, Parent_Impl>)
|
||||
value.trace->order.push_back(Trace_Step::parent);
|
||||
else if constexpr (std::same_as<Layer, Child_Impl>)
|
||||
value.trace->order.push_back(Trace_Step::child);
|
||||
});
|
||||
|
||||
EXPECT_EQ(trace.order,
|
||||
(std::vector{Trace_Step::parent, Trace_Step::child}));
|
||||
}
|
||||
|
||||
TEST(inheritance_test, initializes_final_value_with_ordered_steps) {
|
||||
auto initialized = inheritance::initialize(
|
||||
Trace{},
|
||||
[](Trace& value) { value.order.push_back(Trace_Step::parent); },
|
||||
[](Trace& value) { value.order.push_back(Trace_Step::child); });
|
||||
|
||||
EXPECT_EQ(initialized.order,
|
||||
(std::vector{Trace_Step::parent, Trace_Step::child}));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
Reference in New Issue
Block a user