|
- /*
- ==============================================================================
-
- This file is part of the JUCE library.
- Copyright (c) 2022 - Raw Material Software Limited
-
- JUCE is an open source library subject to commercial or open-source
- licensing.
-
- By using JUCE, you agree to the terms of both the JUCE 7 End-User License
- Agreement and JUCE Privacy Policy.
-
- End User License Agreement: www.juce.com/juce-7-licence
- Privacy Policy: www.juce.com/juce-privacy-policy
-
- Or: You may also use this code under the terms of the GPL v3 (see
- www.gnu.org/licenses).
-
- JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
- EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
- DISCLAIMED.
-
- ==============================================================================
- */
-
- namespace juce::midi_ci
- {
-
- /**
- A strongly-typed identifier for a 7-bit request ID with a nullable state.
-
- @tags{Audio}
- */
- class RequestID
- {
- public:
- /** Constructs a RequestID if the provided value is valid, i.e. its most significant bit is
- not set. Otherwise, returns nullopt.
- */
- static std::optional<RequestID> create (uint8_t v)
- {
- if (v < 128)
- return RequestID { v };
-
- return {};
- }
-
- /** Constructs a RequestID if the provided value is valid, i.e. its most significant bit is
- not set. Otherwise, returns nullopt.
- */
- static std::optional<RequestID> create (std::byte value)
- {
- return create (static_cast<uint8_t> (value));
- }
-
- /** Returns the byte corresponding to this ID. */
- std::byte asByte() const
- {
- return std::byte { value };
- }
-
- /** Returns the int value of this ID. */
- uint8_t asInt() const
- {
- return value;
- }
-
- /** Equality operator. */
- bool operator== (RequestID other) const
- {
- return value == other.value;
- }
-
- /** Inequality operator. */
- bool operator!= (RequestID other) const
- {
- return ! operator== (other);
- }
-
- private:
- /* Constructs a non-null request ID.
-
- The argument must not have its most significant bit set.
- */
- explicit RequestID (uint8_t index)
- : value (index)
- {
- // IDs must only use the lowest 7 bits
- jassert (value < 128);
- }
-
- uint8_t value{};
- };
-
- /** A strongly-typed 64-bit identifier. */
- enum class Token64 : uint64_t {};
-
- /** Compares Token64 instances. */
- constexpr bool operator< (Token64 a, Token64 b)
- {
- return toUnderlyingType (a) < toUnderlyingType (b);
- }
-
- /**
- Accumulates message chunks that have been sent by another device in response
- to a transaction initiated by a local device.
-
- @tags{Audio}
- */
- class InitiatorPropertyExchangeCache
- {
- public:
- InitiatorPropertyExchangeCache();
- ~InitiatorPropertyExchangeCache();
-
- InitiatorPropertyExchangeCache (InitiatorPropertyExchangeCache&&) noexcept;
- InitiatorPropertyExchangeCache& operator= (InitiatorPropertyExchangeCache&&) noexcept;
-
- JUCE_DECLARE_NON_COPYABLE (InitiatorPropertyExchangeCache)
-
- /** Picks an unused request ID, and prepares the cache for that ID to accumulate message chunks.
-
- Incoming chunks added with addChunk are generated by another device acting as a responder.
- */
- std::optional<Token64> primeCache (uint8_t maxSimultaneousRequests,
- std::function<void (const PropertyExchangeResult&)> onDone);
-
- /** Terminates/cancels an ongoing transaction.
-
- Returns true if the termination had an effect (i.e. the transaction was still ongoing), or
- false otherwise (the transaction already ended or never started).
- */
- bool terminate (Token64);
-
- /** If there's a transaction ongoing with the given request id, returns the token uniquely
- identifying that transaction, otherwise returns nullopt.
- */
- std::optional<Token64> getTokenForRequestId (RequestID) const;
-
- /** If the token refers to an ongoing transaction, returns the request id of that transaction.
- Otherwise, returns an invalid request id.
- */
- std::optional<RequestID> getRequestIdForToken (Token64) const;
-
- /** Adds a message chunk for the provided transaction id. */
- void addChunk (RequestID, const Message::DynamicSizePropertyExchange& chunk);
-
- /** Updates the transaction state based on the contents of the provided notification. */
- void notify (RequestID, Span<const std::byte> header);
-
- /** Returns all ongoing transactions. */
- std::vector<Token64> getOngoingTransactions() const;
-
- private:
- class Impl;
- std::unique_ptr<Impl> pimpl;
- };
-
- //==============================================================================
- /**
- Accumulates message chunks that form a request initiated by a remote device.
-
- @tags{Audio}
- */
- class ResponderPropertyExchangeCache
- {
- public:
- ResponderPropertyExchangeCache();
- ~ResponderPropertyExchangeCache();
-
- ResponderPropertyExchangeCache (ResponderPropertyExchangeCache&&) noexcept;
- ResponderPropertyExchangeCache& operator= (ResponderPropertyExchangeCache&&) noexcept;
-
- JUCE_DECLARE_NON_COPYABLE (ResponderPropertyExchangeCache)
-
- /** Prepares the cache for the given requestID to accumulate message chunks.
-
- Incoming chunks added with addChunk are generated by another device acting as an initiator.
- */
- void primeCache (uint8_t maxSimultaneousTransactions,
- std::function<void (const PropertyExchangeResult&)> onDone,
- RequestID id);
-
- /** Adds a message chunk for the provided transaction id. */
- void addChunk (RequestID, const Message::DynamicSizePropertyExchange& chunk);
-
- /** Updates the transaction state based on the contents of the provided notification. */
- void notify (RequestID, Span<const std::byte> header);
-
- /** Returns the number of transactions that have been started but not finished. */
- int countOngoingTransactions() const;
-
- private:
- class Impl;
- std::unique_ptr<Impl> pimpl;
- };
-
- //==============================================================================
- /**
- An interface for objects that provide resources for property exchange
- transactions.
-
- @tags{Audio}
- */
- class CacheProvider
- {
- public:
- virtual ~CacheProvider() = default;
-
- /** Returns a set containing all of the MUIDs currently known to the provider. */
- virtual std::set<MUID> getDiscoveredMuids() const = 0;
-
- /** Returns a property exchange cache for accumulating replies to transactions
- we initiated.
- */
- virtual InitiatorPropertyExchangeCache* getCacheForMuidAsInitiator (MUID m) = 0;
-
- /** Returns a property exchange cache for accumulating requests initiated
- by other devices.
- */
- virtual ResponderPropertyExchangeCache* getCacheForMuidAsResponder (MUID m) = 0;
-
- /** Returns the maximum sysex size supported by the device with the
- given MUID.
- */
- virtual int getMaxSysexSizeForMuid (MUID m) const = 0;
- };
-
- } // namespace juce::midi_ci
|