OSSIA
Open Scenario System for Interactive Application
execution_policy.hpp
1 #pragma once
2 
3 #include <ossia/audio/audio_parameter.hpp>
4 #include <ossia/dataflow/audio_port.hpp>
5 #include <ossia/dataflow/midi_port.hpp>
6 #include <ossia/dataflow/timed_value.hpp>
7 #include <ossia/dataflow/typed_value.hpp>
8 #include <ossia/dataflow/value_vector.hpp>
9 #include <ossia/detail/flat_map.hpp>
10 #include <ossia/detail/hash_map.hpp>
11 #include <ossia/detail/lockfree_queue.hpp>
12 #include <ossia/detail/mutex.hpp>
13 #include <ossia/editor/state/flat_vec_state.hpp>
14 #include <ossia/network/base/device.hpp>
15 #include <ossia/protocols/midi/midi_device.hpp>
16 #include <ossia/protocols/midi/midi_protocol.hpp>
17 #if defined(OSSIA_SMALL_VECTOR)
18 #include <libremidi/message.hpp>
19 #endif
20 
21 #include <cstdint>
22 #if SIZE_MAX == 0xFFFFFFFF // 32-bit
23 #include <ossia/dataflow/audio_port.hpp>
24 #include <ossia/dataflow/midi_port.hpp>
25 #include <ossia/dataflow/value_port.hpp>
26 #endif
27 
28 #include <ossia/detail/audio_spin_mutex.hpp>
29 
30 #include <smallfun.hpp>
31 
32 #if defined(OSSIA_PARALLEL)
33 using ossia_audio_lock_t = std::unique_lock<ossia::audio_spin_mutex>;
34 #define OSSIA_EXEC_STATE_LOCK_READ(state) \
35  ossia_audio_lock_t ossia_read_lock \
36  { \
37  (state).mutex \
38  }
39 #define OSSIA_EXEC_STATE_LOCK_WRITE(state) \
40  ossia_audio_lock_t ossia_write_lock \
41  { \
42  (state).mutex \
43  }
44 #else
45 struct ossia_audio_lock_t
46 {
47  void lock() { }
48  void unlock() { }
49 };
50 #define OSSIA_EXEC_STATE_LOCK_READ(state) \
51  ossia_audio_lock_t ossia_read_lock; \
52  (void)ossia_read_lock;
53 #define OSSIA_EXEC_STATE_LOCK_WRITE(state) \
54  ossia_audio_lock_t ossia_write_lock; \
55  (void)ossia_write_lock;
56 #endif
57 namespace ossia
58 {
59 
60 struct execution_state_policy
61 {
62  execution_state_policy();
63  virtual ~execution_state_policy();
64 
65  virtual void commit() = 0;
66 
67  virtual void clear_local_state() = 0;
68  //virtual void reset() = 0;
69 
70  virtual bool find_and_copy(net::parameter_base& addr, inlet& in) = 0;
71  virtual bool in_local_scope(net::parameter_base& other) const = 0;
72 
73  virtual void insert(ossia::net::parameter_base& dest, const ossia::value_port& v) = 0;
74  virtual void insert(ossia::audio_parameter& dest, const audio_port& v) = 0;
75  virtual void insert(ossia::net::midi::midi_parameter& dest, const midi_port& v) = 0;
76 };
77 
78 struct local_state_execution_policy : execution_state_policy
79 {
80  local_state_execution_policy();
81  virtual ~local_state_execution_policy();
82 
83  bool find_and_copy(net::parameter_base& addr, inlet& in) override;
84  void clear_local_state() override;
85 
86  void commit_common();
87 
88  bool in_local_scope(net::parameter_base& other) const override;
89 
90  void insert(ossia::net::parameter_base& dest, const ossia::value_port& v) override;
91  void insert(ossia::audio_parameter& dest, const audio_port& v) override;
92  void insert(ossia::net::midi::midi_parameter& dest, const midi_port& v) override;
93 
94  mutable ossia::audio_spin_mutex mutex;
95  // private:// disabled due to tests, but for some reason can't make friend
96  // work
97  // using value_state_impl = ossia::flat_multimap<int64_t,
98  // std::pair<ossia::value, int>>;
99 
100  TS_GUARDED_BY(mutex)
101  ossia::hash_map<ossia::net::parameter_base*, value_vector<std::pair<typed_value, int>>>
102  m_valueState;
103 
104  TS_GUARDED_BY(mutex)
105  ossia::hash_map<ossia::audio_parameter*, audio_port> m_audioState;
106 
107  TS_GUARDED_BY(mutex)
108  ossia::hash_map<ossia::net::parameter_base*, value_vector<libremidi::message>>
109  m_midiState;
110 
111  TS_GUARDED_BY(mutex)
112  int m_msgIndex{};
113 };
114 
115 inline ossia::message
116 to_state_element(ossia::net::parameter_base& p, ossia::typed_value&& v)
117 {
118  ossia::message m{p, std::move(v.value)};
119  if(auto u = v.type.target<ossia::unit_t>())
120  m.dest.unit = std::move(*u);
121  m.dest.index = std::move(v.index);
122  return m;
123 }
124 
125 inline ossia::message
126 to_state_element(ossia::net::parameter_base& p, const ossia::typed_value& v)
127 {
128  ossia::message m{p, v.value};
129  if(auto u = v.type.target<ossia::unit_t>())
130  m.dest.unit = std::move(*u);
131  m.dest.index = std::move(v.index);
132  return m;
133 }
134 
135 }
The parameter_base class.
Definition: ossia/network/base/parameter.hpp:48
virtual ossia::value value() const =0
Clone the current value without any network request.
Definition: git_info.h:7
The message struct.
Definition: message.hpp:29
Definition: dataspace.hpp:24