Open Lighting Architecture
 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15  *
16  * Universe.h
17  * Header file for the Universe class, see Universe.cpp for details.
18  * Copyright (C) 2005-2009 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/rdm/RDMCommand.h>
29 #include <ola/rdm/UID.h>
30 #include <ola/rdm/UIDSet.h>
31 #include <olad/DmxSource.h>
32 
33 #include <set>
34 #include <map>
35 #include <vector>
36 #include <string>
37 
38 namespace ola {
39 
41 using ola::rdm::UID;
42 using std::map;
43 using std::pair;
44 using std::set;
45 
46 class Client;
47 class InputPort;
48 class OutputPort;
49 
51  public:
52  enum merge_mode {
53  MERGE_HTP,
54  MERGE_LTP
55  };
56 
57  Universe(unsigned int uid, class UniverseStore *store,
58  ExportMap *export_map,
59  Clock *clock);
60  ~Universe();
61 
62  // Properties for this universe
63  string Name() const { return m_universe_name; }
64  unsigned int UniverseId() const { return m_universe_id; }
65  merge_mode MergeMode() const { return m_merge_mode; }
66  bool IsActive() const;
67  uint8_t ActivePriority() const { return m_active_priority; }
68 
75  return m_rdm_discovery_interval;
76  }
77 
81  const TimeStamp& LastRDMDiscovery() const {
82  return m_last_discovery_time;
83  }
84 
85  // Used to adjust the properties
86  void SetName(const string &name);
87  void SetMergeMode(merge_mode merge_mode);
88 
92  void SetRDMDiscoveryInterval(const TimeInterval &discovery_interval) {
93  m_rdm_discovery_interval = discovery_interval;
94  }
95 
96  // Each universe has a DMXBuffer
97  bool SetDMX(const DmxBuffer &buffer);
98  const DmxBuffer &GetDMX() const { return m_buffer; }
99 
100  // These are the ports we need to nofity when data changes
101  bool AddPort(InputPort *port);
102  bool AddPort(OutputPort *port);
103  bool RemovePort(InputPort *port);
104  bool RemovePort(OutputPort *port);
105  bool ContainsPort(InputPort *port) const;
106  bool ContainsPort(OutputPort *port) const;
107  unsigned int InputPortCount() const { return m_input_ports.size(); }
108  unsigned int OutputPortCount() const { return m_output_ports.size(); }
109  void InputPorts(vector<InputPort*> *ports);
110  void OutputPorts(vector<OutputPort*> *ports);
111 
112  // Source clients are those that provide us with data
113  bool AddSourceClient(Client *client);
114  bool RemoveSourceClient(Client *client);
115  bool ContainsSourceClient(Client *client) const;
116  unsigned int SourceClientCount() const { return m_source_clients.size(); }
117 
118  // Sink clients are those that we need to send data
119  bool AddSinkClient(Client *client);
120  bool RemoveSinkClient(Client *client);
121  bool ContainsSinkClient(Client *client) const;
122  unsigned int SinkClientCount() const { return m_sink_clients.size(); }
123 
124  // These are called when new data arrives on a port/client
125  bool PortDataChanged(InputPort *port);
126  bool SourceClientDataChanged(Client *client);
127 
128  // This is can be called periodically to clean stale clients
129  // stale == client that has not sent data
131 
132  // RDM methods
133  void SendRDMRequest(const ola::rdm::RDMRequest *request,
134  ola::rdm::RDMCallback *callback);
135  void RunRDMDiscovery(RDMDiscoveryCallback *on_complete,
136  bool full = true);
137  void NewUIDList(OutputPort *port, const ola::rdm::UIDSet &uids);
138  void GetUIDs(ola::rdm::UIDSet *uids) const;
139  unsigned int UIDCount() const;
140 
141  bool operator==(const Universe &other) {
142  return m_universe_id == other.UniverseId();
143  }
144 
145  static const char K_FPS_VAR[];
146  static const char K_MERGE_HTP_STR[];
147  static const char K_MERGE_LTP_STR[];
148  static const char K_UNIVERSE_INPUT_PORT_VAR[];
149  static const char K_UNIVERSE_MODE_VAR[];
150  static const char K_UNIVERSE_NAME_VAR[];
151  static const char K_UNIVERSE_OUTPUT_PORT_VAR[];
152  static const char K_UNIVERSE_RDM_REQUESTS[];
153  static const char K_UNIVERSE_SINK_CLIENTS_VAR[];
154  static const char K_UNIVERSE_SOURCE_CLIENTS_VAR[];
155  static const char K_UNIVERSE_UID_COUNT_VAR[];
156 
157  private:
158  typedef struct {
159  unsigned int expected_count;
160  unsigned int current_count;
161  ola::rdm::rdm_response_code response_code;
162  ola::rdm::RDMCallback *callback;
163  vector<string> packets;
164  } broadcast_request_tracker;
165 
166  typedef map<Client*, bool> SourceClientMap;
167 
168  string m_universe_name;
169  unsigned int m_universe_id;
170  string m_universe_id_str;
171  uint8_t m_active_priority;
172  enum merge_mode m_merge_mode; // merge mode
173  vector<InputPort*> m_input_ports;
174  vector<OutputPort*> m_output_ports;
175  set<Client*> m_sink_clients; // clients that require updates
180  SourceClientMap m_source_clients;
181  class UniverseStore *m_universe_store;
182  DmxBuffer m_buffer;
183  ExportMap *m_export_map;
184  map<UID, OutputPort*> m_output_uids;
185  Clock *m_clock;
186  TimeInterval m_rdm_discovery_interval;
187  TimeStamp m_last_discovery_time;
188 
189  Universe(const Universe&);
190  Universe& operator=(const Universe&);
191  void HandleBroadcastAck(broadcast_request_tracker *tracker,
192  ola::rdm::rdm_response_code code,
193  const ola::rdm::RDMResponse *response,
194  const std::vector<std::string> &packets);
195  void HandleBroadcastDiscovery(broadcast_request_tracker *tracker,
196  ola::rdm::rdm_response_code code,
197  const ola::rdm::RDMResponse *response,
198  const std::vector<std::string> &packets);
199  bool UpdateDependants();
200  void UpdateName();
201  void UpdateMode();
202  void HTPMergeSources(const vector<DmxSource> &sources);
203  bool MergeAll(const InputPort *port, const Client *client);
204  void PortDiscoveryComplete(BaseCallback0<void> *on_complete,
205  OutputPort *output_port,
206  const ola::rdm::UIDSet &uids);
207  void DiscoveryComplete(RDMDiscoveryCallback *on_complete);
208 
209  void SafeIncrement(const string &name);
210  void SafeDecrement(const string &name);
211 
212  template<class PortClass>
213  bool GenericAddPort(PortClass *port,
214  vector<PortClass*> *ports);
215 
216  template<class PortClass>
217  bool GenericRemovePort(PortClass *port,
218  vector<PortClass*> *ports,
219  map<UID, PortClass*> *uid_map = NULL);
220 
221  template<class PortClass>
222  bool GenericContainsPort(PortClass *port,
223  const vector<PortClass*> &ports) const;
224 };
225 } // namespace ola
226 #endif // INCLUDE_OLAD_UNIVERSE_H_