Skip to content

Commit 01be6ec

Browse files
committed
break cyclic dependencies, don't include environment.hh in assert.hh
1 parent a13eda6 commit 01be6ec

File tree

9 files changed

+56
-53
lines changed

9 files changed

+56
-53
lines changed

include/reactor-cpp/assert.hh

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ constexpr bool runtime_assertion = false;
2121
constexpr bool runtime_assertion = true;
2222
#endif
2323

24-
#include "environment.hh"
24+
#include "fwd.hh"
2525

2626
#include <cassert>
2727
#include <sstream>
@@ -37,7 +37,6 @@ constexpr bool runtime_assertion = true;
3737
#define reactor_assert(x) assert(x)
3838

3939
namespace reactor {
40-
using EnvPhase = Environment::Phase;
4140

4241
class ValidationError : public std::runtime_error {
4342
private:
@@ -74,31 +73,8 @@ template <typename E> constexpr auto extract_value(E enum_value) -> typename std
7473
return static_cast<typename std::underlying_type<E>::type>(enum_value);
7574
}
7675

77-
inline void assert_phase([[maybe_unused]] const ReactorElement* ptr, [[maybe_unused]] EnvPhase phase) {
78-
if constexpr (runtime_assertion) { // NOLINT
79-
if (ptr->environment()->phase() != phase) {
80-
auto enum_value_to_name = [](EnvPhase phase) -> std::string {
81-
const std::map<EnvPhase, std::string> conversation_map = {
82-
// NOLINT
83-
{EnvPhase::Construction, "Construction"}, {EnvPhase::Assembly, "Assembly"},
84-
{EnvPhase::Startup, "Startup"}, {EnvPhase::Execution, "Execution"},
85-
{EnvPhase::Shutdown, "Shutdown"}, {EnvPhase::Deconstruction, "Deconstruction"}};
86-
// in C++20 use .contains()
87-
if (conversation_map.find(phase) != std::end(conversation_map)) {
88-
return conversation_map.at(phase);
89-
}
90-
return "Unknown Phase: Value: " + std::to_string(extract_value(phase));
91-
};
92-
#ifdef __linux__
93-
print_debug_backtrace();
94-
#endif
76+
void assert_phase([[maybe_unused]] const ReactorElement* ptr, [[maybe_unused]] Phase phase);
9577

96-
// C++20 std::format
97-
throw ValidationError("Expected Phase: " + enum_value_to_name(phase) +
98-
" Current Phase: " + enum_value_to_name(ptr->environment()->phase()));
99-
}
100-
}
101-
}
10278
} // namespace reactor
10379

10480
#endif // REACTOR_CPP_ASSERT_HH

include/reactor-cpp/environment.hh

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,9 @@ constexpr unsigned int default_max_reaction_index = 0;
2626
constexpr bool default_run_forever = false;
2727
constexpr bool default_fast_fwd_execution = false;
2828

29-
class Environment {
30-
public:
31-
enum class Phase { Construction = 0, Assembly = 1, Startup = 2, Execution = 3, Shutdown = 4, Deconstruction = 5 };
29+
enum class Phase { Construction = 0, Assembly = 1, Startup = 2, Execution = 3, Shutdown = 4, Deconstruction = 5 };
3230

31+
class Environment {
3332
private:
3433
using Dependency = std::pair<Reaction*, Reaction*>;
3534

include/reactor-cpp/fwd.hh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ namespace reactor {
1616
class BaseAction;
1717
class BasePort;
1818
class Environment;
19+
enum class Phase;
1920
class Reaction;
2021
class Reactor;
22+
class ReactorElement;
2123
class Scheduler;
2224
class Tag;
2325

lib/action.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ namespace reactor {
1818
void BaseAction::register_trigger(Reaction* reaction) {
1919
reactor_assert(reaction != nullptr);
2020
reactor_assert(this->environment() == reaction->environment());
21-
assert_phase(this, Environment::Phase::Assembly);
21+
assert_phase(this, Phase::Assembly);
2222
validate(this->container() == reaction->container(),
2323
"Action triggers must belong to the same reactor as the triggered "
2424
"reaction");
@@ -29,7 +29,7 @@ void BaseAction::register_trigger(Reaction* reaction) {
2929
void BaseAction::register_scheduler(Reaction* reaction) {
3030
reactor_assert(reaction != nullptr);
3131
reactor_assert(this->environment() == reaction->environment());
32-
assert_phase(this, Environment::Phase::Assembly);
32+
assert_phase(this, Phase::Assembly);
3333
// the reaction must belong to the same reactor as this action
3434
validate(this->container() == reaction->container(), "Scheduable actions must belong to the same reactor as the "
3535
"triggered reaction");

lib/assert.cc

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
#include "reactor-cpp/assert.hh"
10+
#include "reactor-cpp/environment.hh"
1011

1112
namespace reactor {
1213

@@ -16,4 +17,30 @@ auto ValidationError::build_message(const std::string_view msg) noexcept -> std:
1617
return string_stream.str();
1718
}
1819

20+
void assert_phase([[maybe_unused]] const ReactorElement* ptr, [[maybe_unused]] Phase phase) {
21+
if constexpr (runtime_assertion) { // NOLINT
22+
if (ptr->environment()->phase() != phase) {
23+
auto enum_value_to_name = [](Phase phase) -> std::string {
24+
const std::map<Phase, std::string> conversation_map = {
25+
// NOLINT
26+
{Phase::Construction, "Construction"}, {Phase::Assembly, "Assembly"},
27+
{Phase::Startup, "Startup"}, {Phase::Execution, "Execution"},
28+
{Phase::Shutdown, "Shutdown"}, {Phase::Deconstruction, "Deconstruction"}};
29+
// in C++20 use .contains()
30+
if (conversation_map.find(phase) != std::end(conversation_map)) {
31+
return conversation_map.at(phase);
32+
}
33+
return "Unknown Phase: Value: " + std::to_string(extract_value(phase));
34+
};
35+
#ifdef __linux__
36+
print_debug_backtrace();
37+
#endif
38+
39+
// C++20 std::format
40+
throw ValidationError("Expected Phase: " + enum_value_to_name(phase) +
41+
" Current Phase: " + enum_value_to_name(ptr->environment()->phase()));
42+
}
43+
}
44+
}
45+
1946
} // namespace reactor

lib/port.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ void BasePort::base_bind_to(BasePort* port) {
2020
reactor_assert(this->environment() == port->environment());
2121
validate(!port->has_inward_binding(), "Ports may only be connected once");
2222
validate(!port->has_anti_dependencies(), "Ports with anti dependencies may not be connected to other ports");
23-
assert_phase(this, Environment::Phase::Assembly);
23+
assert_phase(this, Phase::Assembly);
2424
if (this->is_input() && port->is_input()) {
2525
validate(this->container() == port->container()->container(),
2626
"An input port A may only be bound to another input port B if B is contained by a reactor that in turn is "
@@ -52,7 +52,7 @@ void BasePort::register_dependency(Reaction* reaction, bool is_trigger) noexcept
5252
reactor_assert(reaction != nullptr);
5353
reactor_assert(this->environment() == reaction->environment());
5454
validate(!this->has_outward_bindings(), "Dependencies may no be declared on ports with an outward binding!");
55-
assert_phase(this, Environment::Phase::Assembly);
55+
assert_phase(this, Phase::Assembly);
5656

5757
if (this->is_input()) {
5858
validate(this->container() == reaction->container(), "Dependent input ports must belong to the same reactor as the "
@@ -74,7 +74,7 @@ void BasePort::register_antidependency(Reaction* reaction) noexcept {
7474
reactor_assert(reaction != nullptr);
7575
reactor_assert(this->environment() == reaction->environment());
7676
validate(!this->has_inward_binding(), "Antidependencies may no be declared on ports with an inward binding!");
77-
assert_phase(this, Environment::Phase::Assembly);
77+
assert_phase(this, Phase::Assembly);
7878

7979
if (this->is_output()) {
8080
validate(this->container() == reaction->container(),

lib/reaction.cc

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Reaction::Reaction(const std::string& name, int priority, Reactor* container, st
2727
void Reaction::declare_trigger(BaseAction* action) {
2828
reactor_assert(action != nullptr);
2929
reactor_assert(this->environment() == action->environment());
30-
assert_phase(this, Environment::Phase::Assembly);
30+
assert_phase(this, Phase::Assembly);
3131
validate(this->container() == action->container(), "Action triggers must belong to the same reactor as the triggered "
3232
"reaction");
3333

@@ -39,7 +39,7 @@ void Reaction::declare_trigger(BaseAction* action) {
3939
void Reaction::declare_schedulable_action(BaseAction* action) {
4040
reactor_assert(action != nullptr);
4141
reactor_assert(this->environment() == action->environment());
42-
assert_phase(this, Environment::Phase::Assembly);
42+
assert_phase(this, Phase::Assembly);
4343
validate(this->container() == action->container(), "Scheduable actions must belong to the same reactor as the "
4444
"triggered reaction");
4545

@@ -51,8 +51,7 @@ void Reaction::declare_schedulable_action(BaseAction* action) {
5151
void Reaction::declare_trigger(BasePort* port) {
5252
reactor_assert(port != nullptr);
5353
reactor_assert(this->environment() == port->environment());
54-
reactor_assert(this->environment()->phase() == Environment::Phase::Assembly);
55-
assert_phase(this, Environment::Phase::Assembly);
54+
assert_phase(this, Phase::Assembly);
5655

5756
if (port->is_input()) {
5857
validate(this->container() == port->container(),
@@ -73,7 +72,7 @@ void Reaction::declare_trigger(BasePort* port) {
7372
void Reaction::declare_dependency(BasePort* port) {
7473
reactor_assert(port != nullptr);
7574
reactor_assert(this->environment() == port->environment());
76-
assert_phase(this, Environment::Phase::Assembly);
75+
assert_phase(this, Phase::Assembly);
7776

7877
if (port->is_input()) {
7978
validate(this->container() == port->container(), "Dependent input ports must belong to the same reactor as the "
@@ -91,7 +90,7 @@ void Reaction::declare_dependency(BasePort* port) {
9190
void Reaction::declare_antidependency(BasePort* port) {
9291
reactor_assert(port != nullptr);
9392
reactor_assert(this->environment() == port->environment());
94-
assert_phase(this, Environment::Phase::Assembly);
93+
assert_phase(this, Phase::Assembly);
9594

9695
if (port->is_output()) {
9796
validate(this->container() == port->container(), "Antidependent output ports must belong to the same reactor as "
@@ -127,7 +126,7 @@ void Reaction::set_deadline_impl(Duration deadline, const std::function<void(voi
127126
}
128127

129128
void Reaction::set_index(unsigned index) {
130-
validate(this->environment()->phase() == Environment::Phase::Assembly,
129+
validate(this->environment()->phase() == Phase::Assembly,
131130
"Reaction indexes may only be set during assembly phase!");
132131
this->index_ = index;
133132
}

lib/reactor.cc

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ ReactorElement::ReactorElement(const std::string& name, ReactorElement::Type typ
2424
reactor_assert(container != nullptr);
2525
this->environment_ = container->environment(); // NOLINT container can be NULL
2626
reactor_assert(this->environment_ != nullptr);
27-
validate(this->environment_->phase() == Environment::Phase::Construction ||
28-
(type == Type::Action && this->environment_->phase() == Environment::Phase::Assembly),
27+
validate(this->environment_->phase() == Phase::Construction ||
28+
(type == Type::Action && this->environment_->phase() == Phase::Assembly),
2929
"Reactor elements can only be created during construction phase!");
3030
// We need a reinterpret_cast here as the derived class is not yet created
3131
// when this constructor is executed. dynamic_cast only works for
@@ -65,7 +65,7 @@ ReactorElement::ReactorElement(const std::string& name, ReactorElement::Type typ
6565
, environment_(environment) {
6666
reactor_assert(environment != nullptr);
6767
validate(type == Type::Reactor || type == Type::Action, "Only reactors and actions can be owned by the environment!");
68-
validate(this->environment_->phase() == Environment::Phase::Construction,
68+
validate(this->environment_->phase() == Phase::Construction,
6969
"Reactor elements can only be created during construction phase!");
7070

7171
switch (type) {
@@ -89,8 +89,8 @@ Reactor::Reactor(const std::string& name, Environment* environment)
8989

9090
void Reactor::register_action([[maybe_unused]] BaseAction* action) {
9191
reactor_assert(action != nullptr);
92-
reactor::validate(this->environment()->phase() == Environment::Phase::Construction ||
93-
this->environment()->phase() == Environment::Phase::Assembly,
92+
reactor::validate(this->environment()->phase() == Phase::Construction ||
93+
this->environment()->phase() == Phase::Assembly,
9494
"Actions can only be registered during construction phase!");
9595
[[maybe_unused]] bool result = actions_.insert(action).second;
9696
reactor_assert(result);
@@ -99,7 +99,7 @@ void Reactor::register_action([[maybe_unused]] BaseAction* action) {
9999

100100
void Reactor::register_input(BasePort* port) {
101101
reactor_assert(port != nullptr);
102-
reactor::validate(this->environment()->phase() == Environment::Phase::Construction,
102+
reactor::validate(this->environment()->phase() == Phase::Construction,
103103
"Ports can only be registered during construction phase!");
104104
[[maybe_unused]] bool result = inputs_.insert(port).second;
105105
reactor_assert(result);
@@ -108,7 +108,7 @@ void Reactor::register_input(BasePort* port) {
108108

109109
void Reactor::register_output(BasePort* port) {
110110
reactor_assert(port != nullptr);
111-
reactor::validate(this->environment()->phase() == Environment::Phase::Construction,
111+
reactor::validate(this->environment()->phase() == Phase::Construction,
112112
"Ports can only be registered during construction phase!");
113113
[[maybe_unused]] bool result = inputs_.insert(port).second;
114114
reactor_assert(result);
@@ -118,7 +118,7 @@ void Reactor::register_output(BasePort* port) {
118118
void Reactor::register_reaction([[maybe_unused]] Reaction* reaction) {
119119
reactor_assert(reaction != nullptr);
120120

121-
validate(this->environment()->phase() == Environment::Phase::Construction,
121+
validate(this->environment()->phase() == Phase::Construction,
122122
"Reactions can only be registered during construction phase!");
123123
[[maybe_unused]] bool result = reactions_.insert(reaction).second;
124124
reactor_assert(result);
@@ -127,15 +127,15 @@ void Reactor::register_reaction([[maybe_unused]] Reaction* reaction) {
127127

128128
void Reactor::register_reactor([[maybe_unused]] Reactor* reactor) {
129129
reactor_assert(reactor != nullptr);
130-
validate(this->environment()->phase() == Environment::Phase::Construction,
130+
validate(this->environment()->phase() == Phase::Construction,
131131
"Reactions can only be registered during construction phase!");
132132
[[maybe_unused]] bool result = reactors_.insert(reactor).second;
133133
reactor_assert(result);
134134
Statistics::increment_reactor_instances();
135135
}
136136

137137
void Reactor::startup() {
138-
reactor_assert(environment()->phase() == Environment::Phase::Startup);
138+
reactor_assert(environment()->phase() == Phase::Startup);
139139
log::Debug() << "Starting up reactor " << fqn();
140140
// call startup on all contained objects
141141
for (auto* base_action : actions_) {
@@ -156,7 +156,7 @@ void Reactor::startup() {
156156
}
157157

158158
void Reactor::shutdown() {
159-
reactor_assert(environment()->phase() == Environment::Phase::Shutdown);
159+
reactor_assert(environment()->phase() == Phase::Shutdown);
160160
log::Debug() << "Terminating reactor " << fqn();
161161
// call shutdown on all contained objects
162162
for (auto* action : actions_) {

lib/scheduler.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ void Scheduler::register_release_tag_callback(const ReleaseTagCallback& callback
523523
// Callbacks should only be registered during assembly, which happens strictly
524524
// sequentially. Therefore, we should be fine accessing the vector directly
525525
// and do not need to lock.
526-
validate(environment_->phase() <= Environment::Phase::Assembly,
526+
validate(environment_->phase() <= Phase::Assembly,
527527
"registering callbacks is only allowed during construction and assembly");
528528
release_tag_callbacks_.push_back(callback);
529529
}

0 commit comments

Comments
 (0)