hammerspoon/Pods/MIKMIDI/Source/MIKMIDIConnectionManager.h

241 lines
10 KiB
Objective-C

//
// MIKMIDIConnectionManager.h
// MIKMIDI
//
// Created by Andrew Madsen on 11/5/15.
// Copyright © 2015 Mixed In Key. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "MIKMIDICompilerCompatibility.h"
#import "MIKMIDISourceEndpoint.h"
@class MIKMIDIDevice;
@class MIKMIDINoteOnCommand;
@protocol MIKMIDIConnectionManagerDelegate;
NS_ASSUME_NONNULL_BEGIN
/**
* MIKMIDIConnectionManager can be used to manage a set of connected devices. It can be configured to automatically
* connect to devices as they are added, and disconnect from them as they are removed. It also supports saving
* the list of connected to NSUserDefaults and restoring them upon relaunch.
*
* The use of MIKMIDIConnectionManager is optional. It is meant to be useful in implementing functionality that
* many MIDI device enabled apps need. However, simple connection to devices or MIDI endpoints can be done with
* MIKMIDIDeviceManager directly, if desired.
*/
@interface MIKMIDIConnectionManager : NSObject
/**
* This method will throw an exception if called. Use -initWithName:delegate:eventHandler: instead.
*
* @return nil
*/
- (instancetype)init NS_UNAVAILABLE;
/**
* Initializes an instance of MIKMIDIConnectionManager. The passed in name is used to independently
* store and load the connection manager's configuration using NSUserDefaults. The passed in name
* should be unique across your application, and the same from launch to launch.
*
* @param name The name to give the connection manager. Must not be nil or empty.
* @param delegate The delegate of the connection manager
* @param eventHandler An MIKMIDIEventHandlerBlock to be called with incoming MIDI messages from any connected device.
*
* @return An initialized MIKMIDIConnectionManager instance.
*/
- (instancetype)initWithName:(NSString *)name
delegate:(nullable id<MIKMIDIConnectionManagerDelegate>)delegate
eventHandler:(nullable MIKMIDIEventHandlerBlock)eventHandler NS_DESIGNATED_INITIALIZER;
/**
* Initializes an instance of MIKMIDIConnectionManager. The passed in name is used to independently
* store and load the connection manager's configuration using NSUserDefaults. The passed in name
* should be unique across your application, and the same from launch to launch. This is the same
* as calling -initWithName:delegate:eventHandler: with a nil delegate and eventHandler.
*
* @param name The name to give the connection manager. Must not be nil or empty.
*
* @return An initialized MIKMIDIConnectionManager instance.
*/
- (instancetype)initWithName:(NSString *)name;
/**
* Connect to the specified device. When MIDI messages are received, the connection manager's event handler
* block will be executed.
*
* @param device An MIKMIDIDevice instance.
* @param error If an error occurs, upon returns contains an NSError object that describes the problem.
* If you are not interested in possible errors, you may pass in NULL.
*
* @return YES if the connection was successful, NO if an error occurred.
*/
- (BOOL)connectToDevice:(MIKMIDIDevice *)device error:(NSError **)error;
/**
* Disconnect from a connected device. No further messages from the specified device will be processed.
*
* Note that you don't need to call this method when a previously-connected device was removed from the system.
* Disconnection in that situation is handled automatically.
*
* @param device An MIKMIDIDevice instance.
*/
- (void)disconnectFromDevice:(MIKMIDIDevice *)device;
/**
* This method can be used to determine if the receiver is connected to a given MIDI device.
*
* @param device An MIKMIDIDevice instance.
*
* @return YES if the receiver is connected to and processing MIDI input from the device, NO otherwise.
*/
- (BOOL)isConnectedToDevice:(MIKMIDIDevice *)device;
/**
* If YES (the default), the connection manager will automatically save its configuration at appropriate
* times. If this property is NO, -saveConfiguration can still be used to manually trigger saving the
* receiver's configuration. Note that -loadConfiguration must always be called manually, e.g. at launch.
*/
@property (nonatomic) BOOL automaticallySavesConfiguration;
/**
* Save the receiver's list of connected devices to disk for later restoration.
*/
- (void)saveConfiguration;
/**
* Load and reconnect to the devices previously saved to disk by a call to -saveConfiguration. For
* this to work, the receiver's name must be the same as it was upon the previous call to -saveConfiguration.
*
* @note: This method will only connect to new devices. It will not disconnect from devices not found in the
* saved configuration.
*/
- (void)loadConfiguration;
/**
* The name of the receiver. Used for configuration save/load.
*/
@property (nonatomic, copy, readonly) NSString *name;
/**
* An MIKMIDIEventHandlerBlock to be called with incoming MIDI messages from any connected device.
*
* If you need to determine which device sent the passed in messages, call source.entity.device on the
* passed in MIKMIDISourceEndpoint argument.
*/
@property (nonatomic, copy, null_resettable) MIKMIDIEventHandlerBlock eventHandler;
/**
* A delegate, used to customize MIKMIDIConnectionManager behavior.
*/
@property (nonatomic, weak, nullable) id<MIKMIDIConnectionManagerDelegate>delegate;
/**
* Controls whether the receiver's availableDevices property includes virtual devices (i.e. devices made
* up of automatically paired virtual sources and destinations).
*
* If this property is YES (the default), the connection manager will attempt to automtically related
* associated virtual sources and destinations and create "virtual" MIKMIDIDevice instances for them.
*
* If this property is NO, the connection manager's availableDevices array will _only_ contain non-virtual
* MIKMIDIDevices.
*
* For most applications, this should be left at the default YES, as even many physical MIDI devices present as
* "virtual" devices in software.
*
* @note: The caveat here is that this relies on some heuristics to match up source endpoints with destination endpoints.
* These heuristics are based on the way certain common MIDI devices behave, but may not be universal, and therefore
* may miss, or fail to properly associate endpoints for some devices. If this is a problem for your application,
* you should obtain and connect to virtual sources/endpoints using MIKMIDIDeviceManager directly instead.
*/
@property (nonatomic) BOOL includesVirtualDevices; // Default is YES
/**
* An array of available MIDI devices.
*
* This property is observable using Key Value Observing.
*/
@property (nonatomic, strong, readonly) MIKArrayOf(MIKMIDIDevice *) *availableDevices;
/**
* The set of MIDI devices to which the receiver is connected.
*
* This property is observable using Key Value Observing.
*/
@property (nonatomic, strong, readonly) MIKSetOf(MIKMIDIDevice *) *connectedDevices;
@end
/**
* Specifies behavior for connecting to a newly connected device. See
* -connectionManager:shouldConnectToNewlyAddedDevice:
*/
typedef NS_ENUM(NSInteger, MIKMIDIAutoConnectBehavior) {
/** Do not connect to the newly added device */
MIKMIDIAutoConnectBehaviorDoNotConnect,
/** Connect to the newly added device */
MIKMIDIAutoConnectBehaviorConnect,
/** Connect to the newly added device only if it was previously connected (ie. in the saved configuration data) */
MIKMIDIAutoConnectBehaviorConnectOnlyIfPreviouslyConnected,
/** Connect to the newly added device if it was previously connected, or is unknown in the configuration data.*/
MIKMIDIAutoConnectBehaviorConnectIfPreviouslyConnectedOrNew,
};
/**
* Protocol containing method(s) to be implemented by delegates of MIKMIDIConnectionManager.
*/
@protocol MIKMIDIConnectionManagerDelegate <NSObject>
@optional
/**
* A connection manager's delegate can implement this method to determine whether or not to automatically connect
* to a newly added MIDI device. See MIKMIDIAutoConnectBehavior for possible return values.
*
* If this method is not implemented, the default behavior is MIKMIDIAutoConnectBehaviorConnectIfPreviouslyConnectedOrNew.
*
* @param manager An instance of MIKMIDIConnectionManager.
* @param device The newly added MIDI device.
*
* @return One of the values defined in MIKMIDIAutoConnectBehavior.
*/
- (MIKMIDIAutoConnectBehavior)connectionManager:(MIKMIDIConnectionManager *)manager shouldConnectToNewlyAddedDevice:(MIKMIDIDevice *)device;
/**
* A connection manager's delegate can implement this method to be notified when a device is connected,
* either because -connectToDevice:error: was called, or because the device was plugged, and the manager
* automatically connected to it. You can for example use this method to update UI in response to a device being connected.
*
* @param manager An instance of MIKMIDIConnectionManager.
* @param device The MIKMIDIDevice that was disconnected.
*/
- (void)connectionManager:(MIKMIDIConnectionManager *)manager deviceWasConnected:(MIKMIDIDevice *)device;
/**
* A connection manager's delegate can implement this method to be notified when a connected device is disconnected,
* either because -disconnectFromDevice: was called, or because the device was unplugged.
*
* If a MIDI device is disconnected between sending a note on message and sending the corresponding note off command,
* this can cause a "stuck note" because the note off command will now never be delivered. e.g. a MIDI piano keyboard
* that is disconnected with a key held down. This method includes an array of these unterminated note on commands (if any)
* so that the receiver can appropriately deal with this situation. For example, corresponding note off commands could
* be generated and sent through whatever processing chain is processing incoming MIDI commands to terminate stuck notes.
*
* @param manager An instance of MIKMIDIConnectionManager.
* @param device The MIKMIDIDevice that was disconnected.
* @param commands An array of note on messages for which corresponding note off messages have not yet been received.
*/
- (void)connectionManager:(MIKMIDIConnectionManager *)manager deviceWasDisconnected:(MIKMIDIDevice *)device withUnterminatedNoteOnCommands:(MIKArrayOf(MIKMIDINoteOnCommand *) *)commands;
@end
NS_ASSUME_NONNULL_END