OSSIA
Open Scenario System for Interactive Application
graph_node.hpp
1 #pragma once
2 #include <cstdint>
3 #if SIZE_MAX == 0xFFFFFFFF // 32-bit
4 #include <ossia/dataflow/audio_port.hpp>
5 #include <ossia/dataflow/midi_port.hpp>
6 #include <ossia/dataflow/value_port.hpp>
7 #endif
8 
9 #include <ossia/dataflow/dataflow_fwd.hpp>
10 #include <ossia/dataflow/exec_state_facade.hpp>
11 #include <ossia/dataflow/token_request.hpp>
12 #include <ossia/detail/small_vector.hpp>
13 #include <ossia/detail/string_view.hpp>
15 
16 namespace ossia
17 {
18 class graph;
19 struct timed_value;
20 struct typed_value;
21 class state;
22 using token_request_vec = ossia::small_vector<token_request, 4>;
23 using simple_token_request_vec = ossia::small_vector<simple_token_request, 4>;
24 inline bool operator==(const token_request_vec& lhs, const simple_token_request_vec& rhs)
25 {
26  if(lhs.size() != rhs.size())
27  return false;
28 
29  auto it1 = lhs.begin();
30  auto it2 = rhs.begin();
31  auto e1 = lhs.end();
32  for(; it1 < e1; ++it1, ++it2)
33  {
34  if(*it1 == *it2)
35  continue;
36  else
37  return false;
38  }
39  return true;
40 }
41 
42 inline bool operator!=(const token_request_vec& lhs, const simple_token_request_vec& rhs)
43 {
44  if(lhs.size() != rhs.size())
45  return true;
46 
47  auto it1 = lhs.begin();
48  auto it2 = rhs.begin();
49  auto e1 = lhs.end();
50  for(; it1 < e1; ++it1, ++it2)
51  {
52  if(*it1 != *it2)
53  continue;
54  else
55  return false;
56  }
57  return true;
58 }
59 inline bool operator==(const simple_token_request_vec& lhs, const token_request_vec& rhs)
60 {
61  return rhs == lhs;
62 }
63 inline bool operator!=(const simple_token_request_vec& lhs, const token_request_vec& rhs)
64 {
65  return rhs != lhs;
66 }
67 
68 using inlets = ossia::small_vector<inlet_ptr, 2>;
69 using outlets = ossia::small_vector<outlet_ptr, 2>;
70 /*
71 class inlet_iterator
72 {
73  using iterator_category = std::forward_iterator_tag;
74  using value_type = ossia::inlet*;
75  using difference_type = std::ptrdiff_t;
76  using pointer = ossia::inlet**;
77  using reference = ossia::inlet*&;
78 private:
79  ossia::small_vector<const inlets*, 2> m_parent{};
80  std::size_t m_index{};
81 public:
82  explicit inlet_iterator(const inlets* parent, std::size_t index) noexcept
83  : m_parent{parent}
84  , m_index{index}
85  {
86 
87  }
88 
89  inlet* operator*() const noexcept
90  { return (*m_parent.back())[m_index]; }
91  bool operator==(const inlet_iterator& other) const noexcept
92  { return m_parent == other.m_parent && m_index == other.m_index; }
93  bool operator!=(const inlet_iterator& other) const noexcept
94  { return !(*this == other); }
95 
96  inlet_iterator operator++(int) noexcept
97  {
98  auto ret = *this;
99  ++*this;
100  return ret;
101  }
102  inlet_iterator& operator++() noexcept
103  {
104 
105  return *this;
106  }
107 };
108 */
109 
110 class OSSIA_EXPORT graph_node
111 {
112 public:
113  graph_node() noexcept;
114  virtual ~graph_node();
115 
116  [[nodiscard]] bool enabled() const noexcept { return !requested_tokens.empty(); }
117 
118  [[nodiscard]] bool executed() const noexcept { return m_executed; }
119 
120  void set_start_discontinuous(bool b) noexcept { m_start_discontinuous = b; }
121  void set_end_discontinuous(bool b) noexcept { m_end_discontinuous = b; }
122 
123  virtual void prepare(const execution_state& st) noexcept;
124  [[nodiscard]] virtual bool consumes(const execution_state&) const noexcept;
125  virtual void run(const token_request&, exec_state_facade) noexcept;
126  [[nodiscard]] virtual std::string label() const noexcept;
127 
128  [[nodiscard]] bool has_port_inputs() const noexcept;
129  [[nodiscard]] bool has_global_inputs() const noexcept;
130  [[nodiscard]] bool has_local_inputs(const execution_state& st) const noexcept;
131 
132  [[nodiscard]] const inlets& root_inputs() const noexcept { return m_inlets; }
133  [[nodiscard]] const outlets& root_outputs() const noexcept { return m_outlets; }
134  inlets& root_inputs() noexcept { return m_inlets; }
135  outlets& root_outputs() noexcept { return m_outlets; }
136 
137  virtual void clear() noexcept;
138 
139  [[nodiscard]] bool start_discontinuous() const noexcept
140  {
141  return m_start_discontinuous;
142  }
143  [[nodiscard]] bool end_discontinuous() const noexcept { return m_end_discontinuous; }
144 
145  void set_executed(bool b) noexcept { m_executed = b; }
146 
147  void request(const ossia::token_request& req) noexcept;
148 
149  void disable() noexcept { requested_tokens.clear(); }
150 
151  void set_logging(bool b) noexcept { m_logging = b; }
152  [[nodiscard]] bool logged() const noexcept { return m_logging; }
153 
154  void set_mute(bool b) noexcept { m_muted = b; }
155  [[nodiscard]] bool muted() const noexcept { return m_muted; }
156 
157  virtual void all_notes_off() noexcept;
158  token_request_vec requested_tokens;
159 
160 protected:
161  inlets m_inlets;
162  outlets m_outlets;
163 
164  bool m_executed{};
165 
166 private:
167  bool m_start_discontinuous{};
168  bool m_end_discontinuous{};
169  bool m_logging{};
170  bool m_muted{};
171 };
172 
173 class OSSIA_EXPORT nonowning_graph_node : public graph_node
174 {
175 public:
176  using graph_node::graph_node;
177  ~nonowning_graph_node() override;
178 
179  void clear() noexcept override;
180 };
181 
182 template <typename T, typename... Args>
183 auto make_node(const execution_state& st, Args&&... args)
184 {
185  auto n = std::make_shared<T>(std::forward<Args>(args)...);
186  n->prepare(st);
187  return n;
188 }
189 }
Definition: git_info.h:7
bool muted
Means that the node should not send / receives network messages.
Definition: node_attributes.hpp:104