mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
238 lines
7.8 KiB
C++
238 lines
7.8 KiB
C++
/*
|
|
==============================================================================
|
|
|
|
This file is part of the JUCE framework.
|
|
Copyright (c) Raw Material Software Limited
|
|
|
|
JUCE is an open source framework subject to commercial or open source
|
|
licensing.
|
|
|
|
By downloading, installing, or using the JUCE framework, or combining the
|
|
JUCE framework with any other source code, object code, content or any other
|
|
copyrightable work, you agree to the terms of the JUCE End User Licence
|
|
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
|
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
|
do not agree to the terms of these agreements, we will not license the JUCE
|
|
framework to you, and you must discontinue the installation or download
|
|
process and cease use of the JUCE framework.
|
|
|
|
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
|
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
|
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
|
|
|
Or:
|
|
|
|
You may also use this code under the terms of the AGPLv3:
|
|
https://www.gnu.org/licenses/agpl-3.0.en.html
|
|
|
|
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
|
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
|
MERCHANTABILITY OR FITNESS FOR A PARTICULAR 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
|