Open Lighting Architecture  Latest Git
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 <ola/util/SequenceNumber.h>
33 #include <olad/DmxSource.h>
34 
35 #include <set>
36 #include <map>
37 #include <vector>
38 #include <string>
39 
40 namespace ola {
41 
42 class Client;
43 class InputPort;
44 class OutputPort;
45 
47  public:
48  enum merge_mode {
49  MERGE_HTP,
50  MERGE_LTP
51  };
52 
53  Universe(unsigned int uid, class UniverseStore *store,
54  ExportMap *export_map,
55  Clock *clock);
56  ~Universe();
57 
58  // Properties for this universe
59  std::string Name() const { return m_universe_name; }
60  unsigned int UniverseId() const { return m_universe_id; }
61  merge_mode MergeMode() const { return m_merge_mode; }
62  bool IsActive() const;
63  uint8_t ActivePriority() const { return m_active_priority; }
64 
71  return m_rdm_discovery_interval;
72  }
73 
77  const TimeStamp& LastRDMDiscovery() const {
78  return m_last_discovery_time;
79  }
80 
81  // Used to adjust the properties
82  void SetName(const std::string &name);
83  void SetMergeMode(merge_mode merge_mode);
84 
88  void SetRDMDiscoveryInterval(const TimeInterval &discovery_interval) {
89  m_rdm_discovery_interval = discovery_interval;
90  }
91 
92  // Each universe has a DMXBuffer
93  bool SetDMX(const DmxBuffer &buffer);
94  const DmxBuffer &GetDMX() const { return m_buffer; }
95 
96  // These are the ports we need to notify when data changes
97  bool AddPort(InputPort *port);
98  bool AddPort(OutputPort *port);
99  bool RemovePort(InputPort *port);
100  bool RemovePort(OutputPort *port);
101  bool ContainsPort(InputPort *port) const;
102  bool ContainsPort(OutputPort *port) const;
103  unsigned int InputPortCount() const { return m_input_ports.size(); }
104  unsigned int OutputPortCount() const { return m_output_ports.size(); }
105  void InputPorts(std::vector<InputPort*> *ports) const;
106  void OutputPorts(std::vector<OutputPort*> *ports) const;
107 
108  // Source clients are those that provide us with data
109  bool AddSourceClient(Client *client);
110  bool RemoveSourceClient(Client *client);
111  bool ContainsSourceClient(Client *client) const;
112  unsigned int SourceClientCount() const { return m_source_clients.size(); }
113 
114  // Sink clients are those that we need to send data
115  bool AddSinkClient(Client *client);
116  bool RemoveSinkClient(Client *client);
117  bool ContainsSinkClient(Client *client) const;
118  unsigned int SinkClientCount() const { return m_sink_clients.size(); }
119 
120  // These are called when new data arrives on a port/client
121  bool PortDataChanged(InputPort *port);
122  bool SourceClientDataChanged(Client *client);
123 
124  // This is can be called periodically to clean stale clients
125  // stale == client that has not sent data
127 
128  // RDM methods
129  void SendRDMRequest(ola::rdm::RDMRequest *request,
130  ola::rdm::RDMCallback *callback);
131  void RunRDMDiscovery(ola::rdm::RDMDiscoveryCallback *on_complete,
132  bool full = true);
133  void NewUIDList(OutputPort *port, const ola::rdm::UIDSet &uids);
134  void GetUIDs(ola::rdm::UIDSet *uids) const;
135  unsigned int UIDCount() const;
136  uint8_t GetRDMTransactionNumber();
137 
138  bool operator==(const Universe &other) {
139  return m_universe_id == other.UniverseId();
140  }
141 
142  static const char K_FPS_VAR[];
143  static const char K_MERGE_HTP_STR[];
144  static const char K_MERGE_LTP_STR[];
145  static const char K_UNIVERSE_INPUT_PORT_VAR[];
146  static const char K_UNIVERSE_MODE_VAR[];
147  static const char K_UNIVERSE_NAME_VAR[];
148  static const char K_UNIVERSE_OUTPUT_PORT_VAR[];
149  static const char K_UNIVERSE_RDM_REQUESTS[];
150  static const char K_UNIVERSE_SINK_CLIENTS_VAR[];
151  static const char K_UNIVERSE_SOURCE_CLIENTS_VAR[];
152  static const char K_UNIVERSE_UID_COUNT_VAR[];
153 
154  private:
155  typedef struct {
156  unsigned int expected_count;
157  unsigned int current_count;
158  ola::rdm::RDMStatusCode status_code;
159  ola::rdm::RDMCallback *callback;
160  std::vector<rdm::RDMFrame> frames;
161  } broadcast_request_tracker;
162 
163  typedef std::map<Client*, bool> SourceClientMap;
164 
165  std::string m_universe_name;
166  unsigned int m_universe_id;
167  std::string m_universe_id_str;
168  uint8_t m_active_priority;
169  enum merge_mode m_merge_mode; // merge mode
170  std::vector<InputPort*> m_input_ports;
171  std::vector<OutputPort*> m_output_ports;
172  std::set<Client*> m_sink_clients; // clients that require updates
177  SourceClientMap m_source_clients;
178  class UniverseStore *m_universe_store;
179  DmxBuffer m_buffer;
180  ExportMap *m_export_map;
181  std::map<ola::rdm::UID, OutputPort*> m_output_uids;
182  Clock *m_clock;
183  TimeInterval m_rdm_discovery_interval;
184  TimeStamp m_last_discovery_time;
185  ola::SequenceNumber<uint8_t> m_transaction_number_sequence;
186 
187  void HandleBroadcastAck(broadcast_request_tracker *tracker,
188  ola::rdm::RDMReply *reply);
189  void HandleBroadcastDiscovery(broadcast_request_tracker *tracker,
190  ola::rdm::RDMReply *reply);
191  bool UpdateDependants();
192  void UpdateName();
193  void UpdateMode();
194  void HTPMergeSources(const std::vector<DmxSource> &sources);
195  bool MergeAll(const InputPort *port, const Client *client);
196  void PortDiscoveryComplete(BaseCallback0<void> *on_complete,
197  OutputPort *output_port,
198  const ola::rdm::UIDSet &uids);
199  void DiscoveryComplete(ola::rdm::RDMDiscoveryCallback *on_complete);
200 
201  void SafeIncrement(const std::string &name);
202  void SafeDecrement(const std::string &name);
203 
204  template<class PortClass>
205  bool GenericAddPort(PortClass *port,
206  std::vector<PortClass*> *ports);
207 
208  template<class PortClass>
209  bool GenericRemovePort(PortClass *port,
210  std::vector<PortClass*> *ports,
211  std::map<ola::rdm::UID, PortClass*> *uid_map = NULL);
212 
213  template<class PortClass>
214  bool GenericContainsPort(PortClass *port,
215  const std::vector<PortClass*> &ports) const;
216 
218 };
219 } // namespace ola
220 #endif // INCLUDE_OLAD_UNIVERSE_H_
A time interval, with usecond accuracy.
Definition: Clock.h:138
Represents a set of RDM UIDs.
Definition: UIDSet.h:48
Definitions and Interfaces to implement an RDMController that sends a single message at a time...
RDMStatusCode
RDM Status Codes.
Definition: RDMResponseCodes.h:45
Definition: Universe.h:46
A port that receives DMX512 data.
Definition: Port.h:137
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Creates dummy copy constructor and assignment operator declarations.
Definition: Macro.h:44
A container for the exported variables.
Definition: ExportMap.h:324
RDM Commands that represent requests (GET, SET or DISCOVER).
Definition: RDMCommand.h:234
Used to hold a single universe of DMX data.
Definition: DmxBuffer.h:49
A RDM unique identifier (UID).
Export variables on the http server.
const TimeStamp & LastRDMDiscovery() const
Get the time of the last discovery run.
Definition: Universe.h:77
const TimeInterval & RDMDiscoveryInterval() const
Return the time between RDM discovery operations.
Definition: Universe.h:70
void SendRDMRequest(ola::rdm::RDMRequest *request, ola::rdm::RDMCallback *callback)
Send a RDM command.
Definition: Universe.cpp:456
Maintains a collection of Universe objects.
Definition: UniverseStore.h:39
A port that sends DMX512 data.
Definition: Port.h:163
A set of UIDs.
A class used to hold a single universe of DMX data.
void CleanStaleSourceClients()
Clean old source clients.
Definition: Universe.cpp:432
Used to get the current time.
Definition: Clock.h:242
The base class for all 1 argument callbacks.
Definition: Callback.h:982
Holds the final state of an RDM request.
Definition: RDMReply.h:43
uint8_t GetRDMTransactionNumber()
Definition: Universe.cpp:614
void SetRDMDiscoveryInterval(const TimeInterval &discovery_interval)
Definition: Universe.h:88
Represents a connected OLA client on the OLA server side.
Definition: Client.h:46
Helper macros.
The interface that can send RDMRequest.
Definition: RDMControllerInterface.h:73
The namespace containing all OLA symbols.
Definition: Credentials.cpp:44
unsigned int UIDCount() const
Definition: Universe.cpp:607
Represents a point in time with microsecond accuracy.
Definition: Clock.h:191
Classes that represent RDM commands.