FlowArithmeticCalculator 1.0.0
Flow Arithmetic Calculator
Loading...
Searching...
No Matches
ConnectPortsInteraction.h
Go to the documentation of this file.
1#ifndef BUSINESS_LOGIC_INPUT_CONNECT_PORTS_INTERACTION_H
2#define BUSINESS_LOGIC_INPUT_CONNECT_PORTS_INTERACTION_H
3
4#include <functional>
5#include <vector>
6
10#include "logging/Loggable.h"
11
19 class ConnectPortsInteraction final : public business_logic::Loggable<ConnectPortsInteraction> {
20 public:
25 bool isStarted() const { return startSide.has_value(); }
26
31 void sanitize() {
32 if (isInvalid()) {
33 logger->info("Interaction is invalid, resetting");
34
36 }
37 }
38
43 blockLifecycleManagerDelegate) {
44 if (isStarted()) {
45 // NOLINTBEGIN(bugprone-unchecked-optional-access)
46 logger->info(
47 "Interaction handling new event; it was already started, completing it");
48
49 // complete the interaction
51 .block = block, .port = port});
52
53 // sanitization: the concept is to be sure that the start side is the output port
54 // and the end side is the input port
55 if (startSide.value().port->type ==
57 std::swap(startSide, endSide);
58 }
59
60 // validate if the connection is valid
61 if (startSide.value().port->type ==
63 endSide.value().port->type ==
65 if (startSide.value().block == endSide.value().block) {
66 logger->warn("Connection is invalid: start and end blocks are the same");
67
68 windowDelegate->showWarning(
69 "Invalid connection",
70 "This connection is invalid. A valid connection must "
71 "be between an input and output port of different blocks.");
72 } else {
73 // validate if the connection does not already exist
74 if (blockLifecycleManagerDelegate->hasConnectionBetween(startSide.value(),
75 endSide.value())) {
76 logger->warn("Connection is invalid: connection already exists");
77
78 windowDelegate->showWarning("Invalid connection",
79 "Such a connection already exists.");
80 } else {
81 // validate if the input port is not already connected to something
82 if (blockLifecycleManagerDelegate->isInputConnected(endSide.value())) {
83 logger->warn(
84 "Connection is invalid: input port is already connected to "
85 "something");
86
87 windowDelegate->showWarning(
88 "Invalid connection",
89 "The chosen input port is already connected.");
90 } else {
91 logger->info(
92 "Connection created between port '{}' (block {}) and port '{}' "
93 "(block "
94 "{})",
95 startSide.value().port->name,
96 startSide.value().block->getSelfId(),
97 endSide.value().port->name,
98 endSide.value().block->getSelfId());
99
100 // add the connection to the connections registry
101 blockLifecycleManagerDelegate->onPortsConnected(startSide.value(),
102 endSide.value());
103 }
104 }
105 }
106 } else {
107 logger->warn(
108 "Invalid connection: start side and end side are not valid port types");
109
110 windowDelegate->showWarning(
111 "Invalid connection",
112 "This connection is invalid. A valid connection must "
113 "be between an input and output port (the order is "
114 "not important).");
115 }
116
117 // reset the interaction
119
120 // NOLINTEND(bugprone-unchecked-optional-access)
121 } else {
122 logger->info("Interaction handling new event; it was not started, starting it");
123
124 // start the interaction
126 .block = block, .port = port});
127 }
128 }
129
133 [[maybe_unused]] const std::optional<
135 getStartSide() const {
136 return startSide;
137 }
138
142 [[maybe_unused]] const std::optional<
144 getEndSide() const {
145 return endSide;
146 }
147
152 startSide = std::nullopt;
153 endSide = std::nullopt;
154 }
155
156 protected:
160 std::optional<business_logic::elements::structures::BlocksConnectionSide> startSide;
161
165 std::optional<business_logic::elements::structures::BlocksConnectionSide> endSide;
166
171 bool isInvalid() {
172 // if side A was clicked but is no longer valid (i.e., block has been deleted),
173 // the interaction becomes invalid
174 if (startSide.has_value() && (startSide.value().block == nullptr)) {
175 return true;
176 }
177
178 // if side B was clicked but is no longer valid (i.e., block has been deleted),
179 // the interaction becomes invalid
180 if (endSide.has_value() && (endSide.value().block == nullptr)) {
181 return true;
182 }
183
184 return false;
185 }
186 };
187} // namespace business_logic::input
188
189#endif // BUSINESS_LOGIC_INPUT_CONNECT_PORTS_INTERACTION_H
Class that provides a logger for the given class; automatically deduces the logger.
Definition Loggable.h:37
std::shared_ptr< spdlog::logger > logger
Definition Loggable.h:75
virtual bool isInputConnected(const business_logic::elements::structures::BlocksConnectionSide &side) const =0
Checks if the input port is connected to anything.
virtual void onPortsConnected(const business_logic::elements::structures::BlocksConnectionSide &source, const business_logic::elements::structures::BlocksConnectionSide &dest)=0
Invoked when a connection is made between two ports + blocks (sides)
virtual bool hasConnectionBetween(const business_logic::elements::structures::BlocksConnectionSide &source, const business_logic::elements::structures::BlocksConnectionSide &dest) const =0
Checks if there is a connection between two entities.
virtual void showWarning(const std::string &title, const std::string &message)=0
Show a warning message.
The base class for all blocks, containing common functionality and members.
Definition BaseBlock.h:36
Connect ports via dragging interaction DTO.
const std::optional< business_logic::elements::structures::BlocksConnectionSide > & getStartSide() const
Gets an immutable reference to the start side.
bool isStarted() const
Returns whether the interaction has started (i.e., is pending and a dragging line should be rendered)
void resetInteraction()
Resets the interaction, setting both sides to std::nullopt
std::optional< business_logic::elements::structures::BlocksConnectionSide > startSide
the first interaction side
const std::optional< business_logic::elements::structures::BlocksConnectionSide > & getEndSide() const
Gets an immutable reference to the end side.
void handleUserInteractedWith(business_logic::elements::blocks::BaseBlock *block, const business_logic::elements::structures::Port *port, business_logic::delegate::IWindowDelegate *windowDelegate, business_logic::delegate::IBlockLifecycleManagerDelegate *blockLifecycleManagerDelegate)
void sanitize()
Sanitizes the interaction by removing both sides if any of them has become invalid.
bool isInvalid()
Returns whether the interaction is invalid (i.e., one of the sides is no longer valid)
std::optional< business_logic::elements::structures::BlocksConnectionSide > endSide
the second interaction side
Input primitives, either for GUI (models of components) or interaction with elements.
business_logic::elements::blocks::BaseBlock * block
The block.
Represents a port on a block.
Definition Port.h:11