plugins/score-plugin-remotecontrol/RemoteControl/DocumentPlugin.hpp
1 #pragma once
2 #include <State/Message.hpp>
3 
4 #include <score/plugins/documentdelegate/plugin/DocumentPlugin.hpp>
5 #include <score/tools/std/StringHash.hpp>
6 
7 #include <ossia/detail/flat_map.hpp>
8 #include <ossia/detail/hash_map.hpp>
9 
10 #include <QtWebSockets/QWebSocket>
11 #include <QtWebSockets/QWebSocketServer>
12 
13 #include <nano_observer.hpp>
14 #include <score_plugin_remotecontrol_export.h>
15 template <typename T>
16 class TreeNode;
17 namespace Device
18 {
19 class DeviceExplorerNode;
21 }
22 namespace Explorer
23 {
24 class DeviceDocumentPlugin;
25 }
26 namespace Scenario
27 {
28 class IntervalModel;
29 class TimeSyncModel;
30 }
31 namespace RemoteControl
32 {
33 class Interval;
34 
35 struct WSClient
36 {
37  QWebSocket* socket{};
38  friend bool operator==(const WSClient& lhs, const WSClient& rhs) noexcept
39  {
40  return lhs.socket == rhs.socket;
41  }
42 };
43 
44 struct Handler
45 {
46  ossia::flat_map<QString, std::function<void(const rapidjson::Value&, const WSClient&)>>
47  answers;
48 
49  std::function<void(const std::vector<WSClient>&)> onAdded;
50  std::function<void(const std::vector<WSClient>&)> onRemoved;
51  std::function<void(const WSClient&)> onClientConnection;
52  std::function<void(const WSClient&)> onClientDisconnection;
53 
57  template <typename T>
58  void setupDefaultHandler(T msgs)
59  {
60  onAdded = [msgs](const std::vector<RemoteControl::WSClient>& clts) {
61  auto msg = msgs.initMessage();
62  for(auto& clt : clts)
63  clt.socket->sendTextMessage(msg);
64  };
65  onRemoved = [msgs](const std::vector<RemoteControl::WSClient>& clts) {
66  auto msg = msgs.deinitMessage();
67  for(auto& clt : clts)
68  clt.socket->sendTextMessage(msg);
69  };
70 
71  onClientConnection = [msgs](const RemoteControl::WSClient& clt) {
72  auto msg = msgs.initMessage();
73  clt.socket->sendTextMessage(msg);
74  };
75  onClientDisconnection = [msgs](const RemoteControl::WSClient& clt) {
76  auto msg = msgs.deinitMessage();
77  clt.socket->sendTextMessage(msg);
78  };
79  }
80 };
81 
82 struct SCORE_PLUGIN_REMOTECONTROL_EXPORT Receiver
83  : public QObject
84  , public Nano::Observer
85 {
86 public:
87  explicit Receiver(const score::DocumentContext& doc, quint16 port);
88 
89  ~Receiver();
90 
91  void addHandler(QObject* context, Handler&& handler);
92  void removeHandler(QObject* context);
93 
94  void registerSync(Path<Scenario::TimeSyncModel> tn);
95  void unregisterSync(Path<Scenario::TimeSyncModel> tn);
96 
97  void onNewConnection();
98 
99  void processTextMessage(const QString& message, const WSClient& w);
100  void processBinaryMessage(QByteArray message, const WSClient& w);
101 
102  void sendMessage(const QString& str);
103 
104  void socketDisconnected();
105 
106  const std::vector<WSClient>& clients() const noexcept { return m_clients; }
107 
108 private:
109  void on_valueUpdated(const ::State::Address& addr, const ossia::value& v);
110 
111  QWebSocketServer m_server;
112  std::vector<WSClient> m_clients;
113 
114  Explorer::DeviceDocumentPlugin& m_dev;
115  std::list<Path<Scenario::TimeSyncModel>> m_activeSyncs;
116 
117  score::hash_map<QString, std::function<void(const rapidjson::Value&, const WSClient&)>>
118  m_answers;
119  score::hash_map<::State::Address, WSClient> m_listenedAddresses;
120 
121  std::vector<std::pair<QObject*, Handler>> m_handlers;
122 };
123 
124 class SCORE_PLUGIN_REMOTECONTROL_EXPORT DocumentPlugin : public score::DocumentPlugin
125 {
126 public:
127  DocumentPlugin(const score::DocumentContext& doc, QObject* parent);
128  ~DocumentPlugin();
129 
130  void timerEvent(QTimerEvent* event) override;
131 
132  void registerInterval(Scenario::IntervalModel& m);
133  void unregisterInterval(Scenario::IntervalModel& m);
134 
135  void on_documentClosing() override;
136 
137  Receiver receiver;
138 
139 private:
140  void create();
141  void cleanup();
142 
143  struct IntervalData
144  {
146  const double* progress;
148  };
149 
150  ossia::hash_map<int64_t, IntervalData> m_intervals;
151 
152  Interval* m_root{};
153 };
154 }
Definition: plugins/score-plugin-remotecontrol/RemoteControl/DocumentPlugin.hpp:125
Definition: Interval.hpp:44
Definition: IntervalModel.hpp:50
Definition: TreeNode.hpp:52
Extend a document with custom data and systems.
Definition: DocumentPluginBase.hpp:24
Manipulation of Devices from Qt.
Definition: AddressSettings.cpp:14
TreeNode< DeviceExplorerNode > Node
Definition: DeviceNode.hpp:74
Main plug-in of score.
Definition: score-plugin-dataflow/Dataflow/PortItem.hpp:14
Definition: plugins/score-plugin-remotecontrol/RemoteControl/DocumentPlugin.hpp:45
void setupDefaultHandler(T msgs)
Helper function to set handlers from a pair of init / deinit functions.
Definition: plugins/score-plugin-remotecontrol/RemoteControl/DocumentPlugin.hpp:58
Definition: plugins/score-plugin-remotecontrol/RemoteControl/DocumentPlugin.hpp:85
Definition: plugins/score-plugin-remotecontrol/RemoteControl/DocumentPlugin.hpp:36
Definition: DocumentContext.hpp:18