17#ifndef RESONANCE_AUDIO_NODE_NODE_H_
18#define RESONANCE_AUDIO_NODE_NODE_H_
22#include <unordered_map>
26#include "base/logging.h"
47class Node :
public std::enable_shared_from_this<Node> {
50 virtual void Process() = 0;
57 virtual bool CleanUp() = 0;
70 typedef std::unordered_map<Output<T>*, std::shared_ptr<Node>> OutputNodeMap;
76 const std::vector<T>& Read();
82 void Connect(
const std::shared_ptr<Node>& node,
Output<T>* output);
92 size_t GetNumConnections()
const;
96 const OutputNodeMap& GetConnectedNodeOutputPairs();
104 void AddOutput(
const std::shared_ptr<Node>& node,
Output<T>* output);
107 OutputNodeMap outputs_;
108 std::vector<T> read_data_;
119 template <
typename T>
122 explicit Output(
Node* node) : parent_(node) {}
137 typedef T (*CopyOperator)(
const T&);
146 std::set<Input<T>*> inputs_;
147 std::vector<T> written_data_;
154 for (
auto& o : outputs_) {
155 CHECK(o.first->RemoveInput(
this));
160const std::vector<T>& Node::Input<T>::Read() {
163 for (
auto& o : outputs_) {
165 T processed_data = o.first->PullData();
166 if (processed_data !=
nullptr) {
167 read_data_.emplace_back(std::move(processed_data));
175void Node::Input<T>::Connect(
const std::shared_ptr<Node>& node,
177 output->AddInput(
this);
178 AddOutput(node, output);
184void Node::Input<T>::Disconnect(Output<T>* output) {
185 output->RemoveInput(
this);
186 RemoveOutput(output);
190size_t Node::Input<T>::GetNumConnections()
const {
191 return outputs_.size();
195const typename Node::Input<T>::OutputNodeMap&
196Node::Input<T>::GetConnectedNodeOutputPairs() {
201void Node::Input<T>::AddOutput(
const std::shared_ptr<Node>& node,
203 outputs_[output] = node;
205 DCHECK(outputs_.find(output) != outputs_.end());
209void Node::Input<T>::RemoveOutput(Output<T>* output) {
210 outputs_.erase(output);
214T Node::Output<T>::PullData() {
215 if (written_data_.empty()) {
219 DCHECK(!written_data_.empty());
221 T return_value = std::move(written_data_.back());
222 written_data_.pop_back();
227void Node::Output<T>::Write(T data) {
228 DCHECK(written_data_.empty());
229 written_data_.clear();
230 written_data_.emplace_back(std::move(data));
233 for (
size_t i = 1; i < inputs_.size(); i++) {
234 written_data_.push_back(written_data_[0]);
237 DCHECK(written_data_.size() == inputs_.size());
241void Node::Output<T>::AddInput(Input<T>* input) {
242 inputs_.insert(input);
246bool Node::Output<T>::RemoveInput(Input<T>* input) {
247 auto it = inputs_.find(input);
248 if (it == inputs_.end()) {