Hedgehog  3.1.0
A library to generate hybrid pipeline workflow systems
Loading...
Searching...
No Matches
graph_inputs_management_abstraction.h
Go to the documentation of this file.
1// NIST-developed software is provided by NIST as a public service. You may use, copy and distribute copies of the
2// software in any medium, provided that you keep intact this entire notice. You may improve, modify and create
3// derivative works of the software or any portion of the software, and you may copy and distribute such modifications
4// or works. Modified works should carry a notice stating that you changed the software and should note the date and
5// nature of any such change. Please explicitly acknowledge the National Institute of Standards and Technology as the
6// source of the software. NIST-developed software is expressly provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND,
7// EXPRESS, IMPLIED, IN FACT OR ARISING BY OPERATION OF LAW, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
8// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT AND DATA ACCURACY. NIST NEITHER REPRESENTS NOR
9// WARRANTS THAT THE OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR THAT ANY DEFECTS WILL BE
10// CORRECTED. NIST DOES NOT WARRANT OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF THE SOFTWARE OR THE RESULTS
11// THEREOF, INCLUDING BUT NOT LIMITED TO THE CORRECTNESS, ACCURACY, RELIABILITY, OR USEFULNESS OF THE SOFTWARE. You
12// are solely responsible for determining the appropriateness of using and distributing the software and you assume
13// all risks associated with its use, including but not limited to the risks and costs of program errors, compliance
14// with applicable laws, damage to or loss of data, programs or equipment, and the unavailability or interruption of
15// operation. This software is not intended to be used in any situation where a failure could cause risk of injury or
16// damage to property. The software developed by NIST employees is not subject to copyright protection within the
17// United States.
18
19
20
21#ifndef HEDGEHOG_GRAPH_INPUTS_MANAGEMENT_ABSTRACTION_H
22#define HEDGEHOG_GRAPH_INPUTS_MANAGEMENT_ABSTRACTION_H
23
24#include <sstream>
25#include <ostream>
26
27#include "../../implementors/concrete_implementor/graph/graph_receiver.h"
28#include "../../implementors/concrete_implementor/graph/graph_slot.h"
29
30#include "../../parts/graph_source.h"
31
32#include "../base/input_output/slot_abstraction.h"
33#include "../base/input_output/sender_abstraction.h"
34#include "../base/input_output/notifier_abstraction.h"
35#include "../base/input_output/receiver_abstraction.h"
36
37#include "../../../tools/concepts.h"
39namespace hh {
41namespace core {
43namespace abstraction {
44
47template<class ...Inputs>
49 public SlotAbstraction,
50 public ReceiverAbstraction<Inputs> ... {
51 private:
52 std::unique_ptr<GraphSource < Inputs...>> source_ = nullptr;
53
54 public:
55 using inputs_t = std::tuple<Inputs...>;
56
60 std::static_pointer_cast<implementor::ImplementorSlot>(
61 std::make_shared<implementor::GraphSlot>()
62 )
63 ),
64 ReceiverAbstraction<Inputs>(
65 std::make_shared<implementor::GraphReceiver<Inputs>>(), SlotAbstraction::mutex()
66 )...,
67 source_(std::make_unique<GraphSource < Inputs...>>
68 ()
69 ) {}
70
73
75 void wakeUp() override {
76 for (auto slot : this->slots()) {
77 slot->wakeUp();
78 }
79 }
80
84 bool wait() { throw std::runtime_error("A graph can not wait"); }
85
86 protected:
89 std::unique_ptr<GraphSource < Inputs...>> const &source() const { return source_; }
90
92 void terminateSource() { this->source_->notifyAllTerminated(); }
93
97 template<class InputDataType>
98 void addInputNodeToGraph(NodeAbstraction *const inputNode) {
99 static_assert(
100 tool::isContainedIn_v<InputDataType, Inputs...>,
101 "The input type (InputDataType) should be part of the list of input types (Inputs)");
102 auto inputAsSlot = dynamic_cast<SlotAbstraction *>(inputNode);
103 auto inputAsReceiver = dynamic_cast<ReceiverAbstraction<InputDataType> *>(inputNode);
104 assert(inputAsSlot != nullptr && inputAsReceiver != nullptr);
105
106 if (source_ != nullptr) {
107 auto sourceAsSender = static_cast<SenderAbstraction<InputDataType> *> (source_.get());
108 auto sourceAsNotifier = static_cast<NotifierAbstraction *> (source_.get());
109
110 for (auto sender : sourceAsSender->senders()) {
111 for (auto receiver : inputAsReceiver->receivers()) {
112 sender->addReceiver(receiver);
113 receiver->addSender(sender);
114 }
115 }
116
117 for (auto slot : inputAsSlot->slots()) {
118 for (auto notifier : sourceAsNotifier->notifiers()) {
119 slot->addNotifier(notifier);
120 notifier->addSlot(slot);
121 }
122 }
123
124 }
125 }
126
129 if (source_) {
130 auto sourceAsNotifier = static_cast<NotifierAbstraction *> (source_.get());
131 for (auto notifier : sourceAsNotifier->notifiers()) {
132 for (auto inputSlot : notifier->connectedSlots()) {
133 for (auto slot : inputSlot->slots()) {
134 this->slots().insert(slot);
135 slot->removeNotifier(notifier);
136 }
137 }
138 }
139 (disconnectSourceFromReceiver<Inputs>(), ...);
140 source_ = nullptr;
141 }
142 }
143
147 template<class Input>
148 void sendInputDataToSource(std::shared_ptr<Input> data) { source_->sendAndNotifyAllInputs(data); }
149
152 void printSource(Printer *printer) {
153 if (this->source_) {
154 this->source_->print(printer);
155 }
156 }
157
162 std::map<abstraction::NodeAbstraction *, std::shared_ptr<NodeAbstraction>> &mapping) {
163 (duplicateSourceEdge<Inputs>(rhs, mapping), ...);
164 }
165
166 private:
169 template<class Input>
171 auto sourceAsSender = static_cast<SenderAbstraction<Input> *>(source_.get());
172 for (auto &sender : sourceAsSender->senders()) {
173 for (auto &inputReceiver : sender->connectedReceivers()) {
174 for (auto &receiver : inputReceiver->receivers()) {
175 ReceiverAbstraction<Input>::receivers().insert(receiver);
176 receiver->removeSender(sender);
177 }
178 }
179 }
180 }
181
182
187 template<class Input>
190 std::map<abstraction::NodeAbstraction *, std::shared_ptr<NodeAbstraction>> &correspondenceMap) {
191 for (auto &receiver : ((ReceiverAbstraction<Input> *) &rhs)->receivers()) {
192 if (auto receiverAsClonable = dynamic_cast<abstraction::ClonableAbstraction *>(receiver)) {
193 if (auto receiverAsNode = dynamic_cast<abstraction::NodeAbstraction *>(receiver)) {
194 if (!correspondenceMap.contains(receiverAsNode)) {
195 auto duplicate = receiverAsClonable->clone(correspondenceMap);
196 dynamic_cast<hh::core::abstraction::GraphNodeAbstraction *>(this)->registerNodeInsideGraph(duplicate.get());
197 correspondenceMap.insert({receiverAsNode, duplicate});
198 }
199
200 auto inputNode = correspondenceMap.at(receiverAsNode).get();
201
202 auto inputAsSlot = dynamic_cast<SlotAbstraction *>(inputNode);
203 auto inputAsReceiver = dynamic_cast<ReceiverAbstraction<Input> *>(inputNode);
204
205 assert(inputAsSlot != nullptr && inputAsReceiver != nullptr);
206
207 for (auto &inputSlot : inputAsSlot->slots()) {
208 this->slots().insert(inputSlot);
209 }
210
211 for (auto &inputReceiver : inputAsReceiver->receivers()) {
212 ReceiverAbstraction<Input>::receivers().insert(inputReceiver);
213 }
214
215 } else {
216 throw std::runtime_error("An input node core is not a NodeAbstraction.");
217 }
218 }
219 }
220 }
221};
222}
223}
224}
225#endif //HEDGEHOG_GRAPH_INPUTS_MANAGEMENT_ABSTRACTION_H
Hedgehog main namespace.
constexpr bool isContainedIn_v
Helper testing if a type T is in variadic Ts.
Printer abstraction to get a snapshot of the metrics of the Hedgehog graph.
Definition: printer.h:52
Core abstraction for clonable nodes, nodes duplicated by execution pipeline.
Core abstraction to notify slots.
void addSlot(SlotAbstraction *const slot)
Add a SlotAbstraction to this notifier.
Core's abstraction to receive a piece of data.
std::set< ReceiverAbstraction * > const & receivers() const
Const accessor to receivers.
Core abstraction to send data.
Core's abstraction to receive a signal.
std::set< SlotAbstraction * > const & slots() const
Const accessor to slots.
std::shared_ptr< std::mutex > const & mutex() const
Protected accessor to mutex.
std::tuple< Inputs... > inputs_t
Accessor to the graph's inputs.
void duplicateSourceEdges(GraphInputsManagementAbstraction< Inputs... > const &rhs, std::map< abstraction::NodeAbstraction *, std::shared_ptr< NodeAbstraction > > &mapping)
Duplicate source edges.
bool wait()
Wait for the graph, should not be called a graph does not wait !
std::unique_ptr< GraphSource< Inputs... > > source_
Graph's source.
~GraphInputsManagementAbstraction() override=default
Default destructor.
void wakeUp() override
Graph wake up, wakes up all registered slots of the input node.
void terminateSource()
Terminate a source, notify all input nodes to terminate.
void disconnectSource()
Disconnect the source when the graph is set as inside.
void duplicateSourceEdge(GraphInputsManagementAbstraction< Inputs... > const &rhs, std::map< abstraction::NodeAbstraction *, std::shared_ptr< NodeAbstraction > > &correspondenceMap)
Duplicate source edge for a type.
void addInputNodeToGraph(NodeAbstraction *const inputNode)
Add an input node to a graph.
std::unique_ptr< GraphSource< Inputs... > > const & source() const
Source accessor.
void sendInputDataToSource(std::shared_ptr< Input > data)
Send a data to the source.
void disconnectSourceFromReceiver()
Disconnect the source from the input node receivers.
Source of the graph, only used in an outer graph.
Definition: graph_source.h:45