score-plugin-controlsurface/ControlSurface/Process.hpp
1 #pragma once
2 #include <State/Message.hpp>
3 
4 #include <Process/GenericProcessFactory.hpp>
5 #include <Process/Process.hpp>
6 
7 #include <Explorer/Explorer/DeviceExplorerModel.hpp>
8 
9 #include <ControlSurface/Metadata.hpp>
10 
11 #include <ossia/detail/hash_map.hpp>
12 
13 namespace Device
14 {
15 struct FullAddressAccessorSettings;
16 }
17 namespace Process
18 {
19 class ControlInlet;
20 }
21 
22 namespace ControlSurface
23 {
24 template <typename Identifier, typename Func>
25 struct NodeObserver : public QObject
26 {
28  Func f;
29 
30  NodeObserver(Explorer::DeviceExplorerModel& explorer, Func fun)
31  : model{explorer}
32  , f{fun}
33  {
34  // TODO handle the case where the node isn't available / gets removed and added again...
35  connect(
36  &explorer, &Explorer::DeviceExplorerModel::nodeChanged, this,
37  [this](Device::Node* n) {
38  if(auto it = available.find(n); it != available.end())
39  {
40  f(n, it->second.id);
41  }
42  });
43  }
44 
45  void listen(State::Address addr, Identifier identifier)
46  {
47  auto node = Device::try_getNodeFromAddress(model.rootNode(), addr);
48  if(node)
49  {
50  available[node] = {std::move(addr), std::move(identifier)};
51  }
52  else
53  {
54  missing.push_back({std::move(addr), std::move(identifier)});
55  }
56  }
57 
58  void unlisten(const State::Address& addr)
59  {
60  auto it = ossia::find_if(
61  available, [&](const auto& pair) { return pair.second.accessor == addr; });
62  if(it != available.end())
63  {
64  available.erase(it);
65  }
66  else
67  {
68  auto it
69  = ossia::find_if(missing, [&](const auto& p) { return p.accessor == addr; });
70  if(it != missing.end())
71  missing.erase(it);
72  }
73  }
74 
76  {
77  State::Address accessor;
78  Identifier id;
79  };
80 
81  ossia::hash_map<Device::Node*, AvailableNode> available;
82  std::vector<AvailableNode> missing;
83 };
84 
85 class Model final : public Process::ProcessModel
86 {
87  SCORE_SERIALIZE_FRIENDS
88  PROCESS_METADATA_IMPL(ControlSurface::Model)
89  W_OBJECT(Model)
90 
91 public:
92  using address_map = ossia::hash_map<int32_t, State::AddressAccessor>;
93  Model(const TimeVal& duration, const Id<Process::ProcessModel>& id, QObject* parent);
94 
95  template <typename Impl>
96  Model(Impl& vis, QObject* parent)
97  : Process::ProcessModel{vis, parent}
98  , m_observer{Explorer::deviceExplorerFromObject(*parent), Apply{*this}}
99  {
100  vis.writeTo(*this);
101  }
102 
103  ~Model() override;
104 
105  using Process::ProcessModel::inlets;
106  using Process::ProcessModel::outlets;
107 
108  Process::Inlets& inlets() noexcept { return m_inlets; }
109  Process::Outlets& outlets() noexcept { return m_outlets; }
110 
111  void addControl(
112  const Id<Process::Port>& id, const Device::FullAddressAccessorSettings& message);
113  void setupControl(Process::ControlInlet* ctl, const State::AddressAccessor& addr);
114  void removeControl(const Id<Process::Port>& id);
115 
116  const address_map& outputAddresses() const noexcept { return m_outputAddresses; }
117 
118 private:
119  QString prettyName() const noexcept override;
120 
121  void setDurationAndScale(const TimeVal& newDuration) noexcept override;
122  void setDurationAndGrow(const TimeVal& newDuration) noexcept override;
123  void setDurationAndShrink(const TimeVal& newDuration) noexcept override;
124 
125  address_map m_outputAddresses;
126 
127  struct Apply
128  {
129  ProcessModel& model;
130  void operator()(Device::Node*, int);
131  };
132 
133  NodeObserver<int, Apply> m_observer;
134 };
135 
137 }
Definition: QmlObjects.hpp:109
Definition: score-plugin-controlsurface/ControlSurface/Process.hpp:86
Definition: DeviceExplorerModel.hpp:67
Definition: score-lib-process/Process/Dataflow/Port.hpp:202
Definition: GenericProcessFactory.hpp:15
The Process class.
Definition: score-lib-process/Process/Process.hpp:61
The id_base_t class.
Definition: Identifier.hpp:57
Manipulation of Devices from Qt.
Definition: AddressSettings.cpp:14
Base classes and tools to implement processes and layers.
Definition: JSONVisitor.hpp:1324
@ ControlSurface
The process supports being exposed to the ControlSurface.
Definition: ProcessFlags.hpp:37
Definition: score-plugin-controlsurface/ControlSurface/Process.hpp:76
Definition: score-plugin-controlsurface/ControlSurface/Process.hpp:26
Definition: AddressSettings.hpp:131
Definition: PortForward.hpp:23
Definition: PortForward.hpp:27
Definition: Address.hpp:108
The Address struct.
Definition: Address.hpp:58
Definition: TimeValue.hpp:21