mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
166 lines
6.6 KiB
C++
166 lines
6.6 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 key used to uniquely identify ongoing transactions initiated by a ci::Device.
|
|
|
|
@tags{Audio}
|
|
*/
|
|
class RequestKey
|
|
{
|
|
auto tie() const { return std::tuple (m, v); }
|
|
|
|
public:
|
|
/** Constructor. */
|
|
RequestKey (MUID muid, Token64 key) : m (muid), v (key) {}
|
|
|
|
/** Returns the muid of the device to which we are subscribed. */
|
|
MUID getMuid() const { return m; }
|
|
|
|
/** Returns an identifier unique to this subscription. */
|
|
Token64 getKey() const { return v; }
|
|
|
|
/** Equality operator. */
|
|
bool operator== (const RequestKey& other) const { return tie() == other.tie(); }
|
|
|
|
/** Inequality operator. */
|
|
bool operator!= (const RequestKey& other) const { return tie() != other.tie(); }
|
|
|
|
/** Less-than operator. */
|
|
bool operator< (const RequestKey& other) const { return tie() < other.tie(); }
|
|
|
|
private:
|
|
MUID m;
|
|
Token64 v{};
|
|
};
|
|
|
|
/**
|
|
Acting as a ResponderListener, instances of this class can formulate
|
|
appropriate replies to property transactions initiated by remote devices.
|
|
|
|
PropertyHost instances also contain methods to inform remote devices about
|
|
changes to local property state.
|
|
|
|
Keeps track of property subscriptions requested by remote devices.
|
|
|
|
@tags{Audio}
|
|
*/
|
|
class PropertyHost final : public ResponderDelegate
|
|
{
|
|
public:
|
|
/** @internal
|
|
|
|
Rather than constructing one of these objects yourself, you should configure
|
|
a Device with property exchange support, and then use Device::getPropertyHost()
|
|
to retrieve a property host that has been set up to work with that device.
|
|
*/
|
|
PropertyHost (FunctionBlock fb, PropertyDelegate& d, BufferOutput& o, CacheProvider& p)
|
|
: functionBlock (fb), delegate (d), output (o), cacheProvider (p) {}
|
|
|
|
/** Sends a "Subscription" message from a device, when acting as a
|
|
subscription responder. You should call this for all registered
|
|
subscribers whenever the subscribed property is modified in a way that
|
|
remote devices don't know about (if a remote device requests a
|
|
property update, there's no need to send a subscription update after
|
|
changing the property accordingly).
|
|
|
|
You should *not* attempt to start a new subscription on another device
|
|
using this function. Valid subscription commands are "full", "partial",
|
|
and "notify". Check the property exchange specification for the intended
|
|
use of these commands.
|
|
|
|
To terminate a subscription that was initiated by a remote device,
|
|
use terminateSubscription().
|
|
|
|
The provided callback will be called once the remote device has confirmed
|
|
receipt of the subscription update. If the state of your application
|
|
changes such that you no longer need to respond/wait for confirmation,
|
|
you can pass the request key to Device::abortPropertyRequest().
|
|
*/
|
|
std::optional<RequestKey> sendSubscriptionUpdate (MUID device,
|
|
const PropertySubscriptionHeader& header,
|
|
Span<const std::byte> body,
|
|
std::function<void (const PropertyExchangeResult&)> callback);
|
|
|
|
/** Terminates a subscription that was started by a remote device.
|
|
|
|
This may be useful if your application has properties that can be
|
|
added and removed - you can terminate subscriptions to subscribed
|
|
properties before removing those properties.
|
|
*/
|
|
void terminateSubscription (MUID device, const String& subscribeId);
|
|
|
|
/** Returns a set of subscribed resources.
|
|
|
|
This set contains all active subscriptionIDs for the given device,
|
|
along with the resources to which those subscriptionIDs refer.
|
|
*/
|
|
std::set<Subscription> findSubscriptionsForDevice (MUID device) const;
|
|
|
|
/** Returns the number of transactions that have been initiated by other devices, but not yet
|
|
completed, normally because the request has been split into several messages.
|
|
*/
|
|
int countOngoingTransactions() const;
|
|
|
|
/** @internal */
|
|
bool tryRespond (ResponderOutput&, const Message::Parsed&) override;
|
|
|
|
private:
|
|
class Visitor;
|
|
|
|
struct SubscriptionToken
|
|
{
|
|
size_t uid{};
|
|
|
|
bool operator< (const SubscriptionToken& other) const { return uid < other.uid; }
|
|
bool operator== (const SubscriptionToken& other) const { return uid == other.uid; }
|
|
bool operator!= (const SubscriptionToken& other) const { return uid != other.uid; }
|
|
};
|
|
|
|
static SubscriptionToken uidFromSubscribeId (String id);
|
|
static String subscribeIdFromUid (SubscriptionToken uid);
|
|
static SubscriptionToken findUnusedSubscribeId (const std::map<SubscriptionToken, String>& used);
|
|
|
|
FunctionBlock functionBlock;
|
|
PropertyDelegate& delegate;
|
|
BufferOutput& output;
|
|
CacheProvider& cacheProvider;
|
|
|
|
std::map<MUID, std::map<SubscriptionToken, String>> registry;
|
|
};
|
|
|
|
} // namespace juce::midi_ci
|