Open Lighting Architecture  0.9.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Universe.h
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or
5  * (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU Library General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
15  *
16  * Universe.h
17  * Header file for the Universe class, see Universe.cpp for details.
18  * Copyright (C) 2005 Simon Newton
19  */
20 
21 #ifndef INCLUDE_OLAD_UNIVERSE_H_
22 #define INCLUDE_OLAD_UNIVERSE_H_
23 
24 #include <ola/Clock.h>
25 #include <ola/DmxBuffer.h>
26 #include <ola/ExportMap.h>
27 #include <ola/base/Macro.h>
28 #include <ola/rdm/RDMCommand.h>
30 #include <ola/rdm/UID.h>
31 #include <ola/rdm/UIDSet.h>
32 #include <olad/DmxSource.h>
33 
34 #include <set>
35 #include <map>
36 #include <vector>
37 #include <string>
38 
39 namespace ola {
40 
41 class Client;
42 class InputPort;
43 class OutputPort;
44 
46  public:
47  enum merge_mode {
48  MERGE_HTP,
49  MERGE_LTP
50  };
51 
52  Universe(unsigned int uid, class UniverseStore *store,
53  ExportMap *export_map,
54  Clock *clock);
55  ~Universe();
56 
57  // Properties for this universe
58  std::string Name() const { return m_universe_name; }
59  unsigned int UniverseId() const { return m_universe_id; }
60  merge_mode MergeMode() const { return m_merge_mode; }
61  bool IsActive() const;
62  uint8_t ActivePriority() const { return m_active_priority; }
63 
70  return m_rdm_discovery_interval;
71  }
72 
76  const TimeStamp& LastRDMDiscovery() const {
77  return m_last_discovery_time;
78  }
79 
80  // Used to adjust the properties
81  void SetName(const std::string &name);
82  void SetMergeMode(merge_mode merge_mode);
83 
87  void SetRDMDiscoveryInterval(const TimeInterval &discovery_interval) {
88  m_rdm_discovery_interval = discovery_interval;
89  }
90 
91  // Each universe has a DMXBuffer
92  bool SetDMX(const DmxBuffer &buffer);
93  const DmxBuffer &GetDMX() const { return m_buffer; }
94 
95  // These are the ports we need to nofity when data changes
96  bool AddPort(InputPort *port);
97  bool AddPort(OutputPort *port);
98  bool RemovePort(InputPort *port);
99  bool RemovePort(OutputPort *port);
100  bool ContainsPort(InputPort *port) const;
101  bool ContainsPort(OutputPort *port) const;
102  unsigned int InputPortCount() const { return m_input_ports.size(); }
103  unsigned int OutputPortCount() const { return m_output_ports.size(); }
104  void InputPorts(std::vector<InputPort*> *ports);
105  void OutputPorts(std::vector<OutputPort*> *ports);
106 
107  // Source clients are those that provide us with data
108  bool AddSourceClient(Client *client);
109  bool RemoveSourceClient(Client *client);
110  bool ContainsSourceClient(Client *client) const;
111  unsigned int SourceClientCount() const { return m_source_clients.size(); }
112 
113  // Sink clients are those that we need to send data
114  bool AddSinkClient(Client *client);
115  bool RemoveSinkClient(Client *client);
116  bool ContainsSinkClient(Client *client) const;
117  unsigned int SinkClientCount() const { return m_sink_clients.size(); }
118 
119  // These are called when new data arrives on a port/client
120  bool PortDataChanged(InputPort *port);
121  bool SourceClientDataChanged(Client *client);
122 
123  // This is can be called periodically to clean stale clients
124  // stale == client that has not sent data
126 
127  // RDM methods
128  void SendRDMRequest(const ola::rdm::RDMRequest *request,
129  ola::rdm::RDMCallback *callback);
130  void RunRDMDiscovery(ola::rdm::RDMDiscoveryCallback *on_complete,
131  bool full = true);
132  void NewUIDList(OutputPort *port, const ola::rdm::UIDSet &uids);
133  void GetUIDs(ola::rdm::UIDSet *uids) const;
134  unsigned int UIDCount() const;
135 
136  bool operator==(const Universe &other) {
137  return m_universe_id == other.UniverseId();
138  }
139 
140  static const char K_FPS_VAR[];
141  static const char K_MERGE_HTP_STR[];
142  static const char K_MERGE_LTP_STR[];
143  static const char K_UNIVERSE_INPUT_PORT_VAR[];
144  static const char K_UNIVERSE_MODE_VAR[];
145  static const char K_UNIVERSE_NAME_VAR[];
146  static const char K_UNIVERSE_OUTPUT_PORT_VAR[];
147  static const char K_UNIVERSE_RDM_REQUESTS[];
148  static const char K_UNIVERSE_SINK_CLIENTS_VAR[];
149  static const char K_UNIVERSE_SOURCE_CLIENTS_VAR[];
150  static const char K_UNIVERSE_UID_COUNT_VAR[];
151 
152  private:
153  typedef struct {
154  unsigned int expected_count;
155  unsigned int current_count;
156  ola::rdm::rdm_response_code response_code;
157  ola::rdm::RDMCallback *callback;
158  std::vector<std::string> packets;
159  } broadcast_request_tracker;
160 
161  typedef std::map<Client*, bool> SourceClientMap;
162 
163  std::string m_universe_name;
164  unsigned int m_universe_id;
165  std::string m_universe_id_str;
166  uint8_t m_active_priority;
167  enum merge_mode m_merge_mode; // merge mode
168  std::vector<InputPort*> m_input_ports;
169  std::vector<OutputPort*> m_output_ports;
170  std::set<Client*> m_sink_clients; // clients that require updates
175  SourceClientMap m_source_clients;
176  class UniverseStore *m_universe_store;
177  DmxBuffer m_buffer;
178  ExportMap *m_export_map;
179  std::map<ola::rdm::UID, OutputPort*> m_output_uids;
180  Clock *m_clock;
181  TimeInterval m_rdm_discovery_interval;
182  TimeStamp m_last_discovery_time;
183 
184  void HandleBroadcastAck(broadcast_request_tracker *tracker,
185  ola::rdm::rdm_response_code code,
186  const ola::rdm::RDMResponse *response,
187  const std::vector<std::string> &packets);
188  void HandleBroadcastDiscovery(broadcast_request_tracker *tracker,
189  ola::rdm::rdm_response_code code,
190  const ola::rdm::RDMResponse *response,
191  const std::vector<std::string> &packets);
192  bool UpdateDependants();
193  void UpdateName();
194  void UpdateMode();
195  void HTPMergeSources(const std::vector<DmxSource> &sources);
196  bool MergeAll(const InputPort *port, const Client *client);
197  void PortDiscoveryComplete(BaseCallback0<void> *on_complete,
198  OutputPort *output_port,
199  const ola::rdm::UIDSet &uids);
200  void DiscoveryComplete(ola::rdm::RDMDiscoveryCallback *on_complete);
201 
202  void SafeIncrement(const std::string &name);
203  void SafeDecrement(const std::string &name);
204 
205  template<class PortClass>
206  bool GenericAddPort(PortClass *port,
207  std::vector<PortClass*> *ports);
208 
209  template<class PortClass>
210  bool GenericRemovePort(PortClass *port,
211  std::vector<PortClass*> *ports,
212  std::map<ola::rdm::UID, PortClass*> *uid_map = NULL);
213 
214  template<class PortClass>
215  bool GenericContainsPort(PortClass *port,
216  const std::vector<PortClass*> &ports) const;
217 
218  DISALLOW_COPY_AND_ASSIGN(Universe);
219 };
220 } // namespace ola
221 #endif // INCLUDE_OLAD_UNIVERSE_H_