/* universe.h Copyright (c) 2020 Kevin Matz (kevin.matz@gmail.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #pragma once #include "sacn.h" #include "data.h" #include "../dmx/universe.h" #include "../uuid/uuid.h" #include #include #include namespace SACN { /** * @brief The UniverseSource class */ class UniverseSource { public: UniverseSource(); UniverseSource(std::shared_ptr); const UUID::uuid CID() const {return cid_;}; const std::string description() const {return description_;} uint16_t universe() const {return universe_;} uint8_t priority() const {return priority_;} uint16_t syncAddress() const {return sync_address_;} bool isTerminated() const {return options_ & DATA::STREAM_TERMINATED;} bool isPreview() const {return options_ & DATA::PREVIEW_DATA;} bool isForced() const {return options_ & DATA::FORCE_SYNCHRONIZATION;} friend bool operator== (const UniverseSource& a, const UniverseSource& b); void setCID(UUID::uuid cid) { cid_ = cid; } void setDescription(std::string desc) { description_ = desc; } void setOptions(uint8_t o) { options_ = o; } void setUniverse(uint16_t n) { if (n >= 1 && n <= 63999) universe_ = n; } void setSyncAddress(uint16_t a) { if (a >= 1 && a <= 63999) sync_address_ = a; } void setPriority(uint8_t p) { if (p <= 200) priority_ = p; } private: UUID::uuid cid_; std::string description_; uint16_t universe_; uint8_t priority_; uint16_t sync_address_; uint8_t options_; }; } // SACN namespace namespace std { template<> /** * @brief The hash struct specilizaton for SACN::UniverseSource */ struct hash { /** * @brief operator () * @param src * @return */ size_t operator()(SACN::UniverseSource const& src) const noexcept { size_t h1 = hash{}(src.description()); size_t h2 = hash{}(src.CID()); size_t h3 = hash{}(src.priority()); size_t h = h1 ^ h2 ^ h3; // or use boost::hash_combine return h; } }; } // std namespace namespace SACN { /** * @brief The Universe class */ class Universe : public DMX::Universe { public: Universe(); ~Universe(); virtual bool isSyncronized() const { return (sync_data_.size() > 0); }; virtual std::shared_ptr source() const { return source_; } virtual uint8_t slot (const uint16_t) override; virtual void set(std::shared_ptr, std::shared_ptr); virtual void setSource(std::shared_ptr); virtual void synchronize(); private: std::shared_ptr source_; std::vector sync_data_; }; /** * @brief The MergeProxyUniverse class * 6.2.3.1 Multiple Sources at Highest Priority * It is possible for there to be multiple sources, all transmitting data * at the highest currently active priority for a given universe. When this * occurs, receivers must handle these sources in some way. */ class MergeProxyUniverse : public SACN::Universe { public: MergeProxyUniverse(); ~MergeProxyUniverse(); // Source universes: const std::vector sources() const; Universe* sourceUniverse(const UniverseSource&); bool hasSourceUniverse(const UniverseSource&) const; bool hasSources() const; void deleteSourceUniverse(const UniverseSource&); void addSourceUniverse(Universe *); void dataChangedNotifier(DMX::Universe* universe); // SACN::Universe overrides: bool isSyncronized() const override; std::shared_ptr source() const override; void set(std::shared_ptr, std::shared_ptr) override; void setSource(std::shared_ptr) override {}; void synchronize() override; // DMX::Universe Overrides: const DMX::DimmerData *data() const override; uint8_t slot(const uint16_t) override; double rxRate() override; private: std::unordered_map sources_; Universe* dominant_() const; void newSource_(const UniverseSource&); }; } // SACN namespace