[][src]Struct reaper_medium::Reaper

pub struct Reaper { /* fields omitted */ }

This is the main hub for accessing medium-level API functions.

In order to use this struct, you first must obtain an instance of it by invoking new() or load(). This struct itself is limited to REAPER functions for registering/unregistering certain things. You can access all the other functions by calling functions().

Please note that this struct will take care of unregistering everything (also audio hooks) automatically when it gets dropped (good RAII manners).

Design

Why is there a separation into Reaper and ReaperFunctions?

Functions for registering/unregistering things have been separated from the rest because they require more than just access to REAPER function pointers. They also need data structures to keep track of the registered things and to offer them a warm and cosy place in memory. As a result, this struct gains special importance, needs to be mutable and can't just be cloned as desired. But there's no reason why this restriction should also apply to all other REAPER functions. After all, being able to clone and pass things around freely can simplify things a lot.

Example

Here's an example how things can get difficult without the ability to clone: In order to be able to use REAPER functions also from e.g. the audio hook register, we would need to wrap it in an Arc (not an Rc, because we access it from multiple threads). That's not enough though for most real-world cases. We probably want to register/unregister things (in the main thread) not only in the beginning but also at a later time. That means we need mutable access. So we end up with Arc<Mutex<Reaper>>. However, why going through all that trouble and put up with possible performance issues if we can avoid it?

Implementations

impl Reaper[src]

pub fn new(low: Reaper) -> Reaper[src]

Creates a new instance by getting hold of a low-level Reaper instance.

pub fn load(context: &ReaperPluginContext) -> Reaper[src]

Loads all available REAPER functions from the given plug-in context.

Returns a medium-level Reaper instance which allows you to call these functions.

pub fn functions(&self) -> &ReaperFunctions<MainThreadScope>[src]

Gives access to all REAPER functions which can be safely executed in the main thread.

pub fn create_real_time_functions(
    &self
) -> ReaperFunctions<RealTimeAudioThreadScope>
[src]

Creates a new container of REAPER functions with only those unlocked that can be safely executed in the real-time audio thread.

pub unsafe fn plugin_register_add(
    &mut self,
    object: RegistrationObject
) -> Result<i32, ReaperFunctionError>
[src]

This is the primary function for plug-ins to register things.

Things can be keyboard shortcuts, project importers etc. Typically you register things when the plug-in is loaded.

It is not recommended to use this function directly because it's unsafe. Consider using the safe convenience functions instead. They all start with plugin_register_add_.

The meaning of the return value depends very much on the actual thing being registered. In most cases it just returns 1. In any case it's not 0, reaper-rs translates this into an error.

Also see plugin_register_remove().

Errors

Returns an error if the registration failed.

Safety

REAPER can crash if you pass an invalid pointer or if it dangles during the time it is registered. So you must ensure that the registered thing lives long enough and has a stable address in memory. Additionally, mutation of the thing while it is registered can lead to subtle bugs.

pub unsafe fn plugin_register_remove(
    &mut self,
    object: RegistrationObject
) -> i32
[src]

Unregisters things that you have registered with plugin_register_add().

Please note that unregistering things manually just for cleaning up is unnecessary in most situations because reaper-rs takes care of automatically unregistering everything when this struct is dropped (RAII). This happens even when using the unsafe function variants.

Safety

REAPER can crash if you pass an invalid pointer.

pub fn plugin_register_add_hook_command<T: MediumHookCommand>(
    &mut self
) -> Result<(), ReaperFunctionError>
[src]

Registers a hook command.

REAPER calls hook commands whenever an action is requested to be run.

This method doesn't take a closure because REAPER expects a plain function pointer here. Unlike audio_reg_hardware_hook_add, REAPER doesn't offer the possibiity to pass a context to the function. So we can't access any context data in the hook command. You will probably have to use a kind of static variable which contains command IDs in order to make proper use of this method. The high-level API makes that much easier (it just takes an arbitrary closure). For the medium-level API this is out of scope.

Errors

Returns an error if the registration failed.

Example

use reaper_medium::{MediumHookCommand, CommandId};

// Usually you would use a dynamic command ID that you have obtained via
// `plugin_register_add_command_id()`. Unfortunately that command ID must be exposed as
// a static variable. The high-level API provides a solution for that.
const MY_COMMAND_ID: CommandId = unsafe { CommandId::new_unchecked(42000) };

struct MyHookCommand;

impl MediumHookCommand for MyHookCommand {
    fn call(command_id: CommandId, _flag: i32) -> bool {
        if command_id != MY_COMMAND_ID {
            return false;
        }           
        println!("Executing my command!");
        true
    }
}
reaper.plugin_register_add_hook_command::<MyHookCommand>();

Design

You will note that this method has a somewhat strange signature: It expects a type parameter only, not a function pointer. That allows us to lift the API to medium-level style. The alternative would have been to expect a function pointer, but then consumers would have to deal with raw types.

pub fn plugin_register_remove_hook_command<T: MediumHookCommand>(&mut self)[src]

Unregisters a hook command.

pub fn plugin_register_add_toggle_action<T: MediumToggleAction>(
    &mut self
) -> Result<(), ReaperFunctionError>
[src]

Registers a toggle action.

REAPER calls toggle actions whenever it wants to know the on/off state of an action.

See plugin_register_add_hook_command() for an example.

Errors

Returns an error if the registration failed.

pub fn plugin_register_remove_toggle_action<T: MediumToggleAction>(&mut self)[src]

Unregisters a toggle action.

pub fn plugin_register_add_hook_post_command<T: MediumHookPostCommand>(
    &mut self
) -> Result<(), ReaperFunctionError>
[src]

Registers a hook post command.

REAPER calls hook post commands whenever an action of the main section has been performed.

See plugin_register_add_hook_command() for an example.

Errors

Returns an error if the registration failed.

pub fn plugin_register_remove_hook_post_command<T: MediumHookPostCommand>(
    &mut self
)
[src]

Unregisters a hook post command.

pub fn plugin_register_add_command_id<'a>(
    &mut self,
    command_name: impl Into<ReaperStringArg<'a>>
) -> Result<CommandId, ReaperFunctionError>
[src]

Registers a command ID for the given command name.

The given command name must be a unique identifier with only A-Z and 0-9.

Returns the assigned command ID, an ID which is guaranteed to be unique within the current REAPER session. If the command name is already in use, it just seems to return the ID which has been assigned before.

Errors

Returns an error if the registration failed (e.g. because not supported or out of actions).

pub fn plugin_register_add_gaccel(
    &mut self,
    register: MediumGaccelRegister
) -> Result<NonNull<gaccel_register_t>, ReaperFunctionError>
[src]

Registers a an action into the main section.

This consists of a command ID, a description and a default binding for it. It doesn't include the actual code to be executed when the action runs (use plugin_register_add_hook_command() for that).

This function returns a handle which you can use to unregister the action at any time via plugin_register_remove_gaccel().

Errors

Returns an error if the registration failed.

Design

This function takes ownership of the passed struct in order to take complete care of it. Compared to the alternative of taking a reference or pointer, that releases the API consumer from the responsibilities to guarantee a long enough lifetime and to maintain a stable address in memory. Giving up ownership also means that the consumer doesn't have access to the struct anymore - which is a good thing, because REAPER should be the new rightful owner of this struct. Thanks to this we don't need to mark this function as unsafe!

pub fn plugin_register_remove_gaccel(
    &mut self,
    handle: NonNull<gaccel_register_t>
)
[src]

Unregisters an action.

pub fn plugin_register_add_csurf_inst(
    &mut self,
    control_surface: impl MediumReaperControlSurface + 'static
) -> Result<NonNull<IReaperControlSurface>, ReaperFunctionError>
[src]

Registers a hidden control surface.

This is very useful for being notified by REAPER about all kinds of events in the main thread.

This function returns a handle which you can use to unregister the control surface at any time via plugin_register_remove_csurf_inst().

Errors

Returns an error if the registration failed.

Example

use reaper_medium::MediumReaperControlSurface;

#[derive(Debug)]
struct MyControlSurface;

impl MediumReaperControlSurface for MyControlSurface {
    fn set_track_list_change(&self) {
        println!("Tracks changed");
    }
}
reaper.plugin_register_add_csurf_inst(MyControlSurface);

pub fn plugin_register_remove_csurf_inst(
    &mut self,
    handle: NonNull<IReaperControlSurface>
)
[src]

Unregisters a hidden control surface.

pub unsafe fn audio_reg_hardware_hook_add_unchecked(
    &mut self,
    register: NonNull<audio_hook_register_t>
) -> Result<(), ReaperFunctionError>
[src]

Like audio_reg_hardware_hook_add but doesn't manage memory for you.

Also see audio_reg_hardware_hook_remove_unchecked().

Errors

Returns an error if the registration failed.

Safety

REAPER can crash if you pass an invalid pointer or if it dangles during the time it is registered. So you must ensure that the audio hook register lives long enough and has a stable address in memory. Additionally, incorrectly accessing the audio hook register while it is registered can lead to horrible race conditions and other undefined behavior.

pub unsafe fn audio_reg_hardware_hook_remove_unchecked(
    &mut self,
    register: NonNull<audio_hook_register_t>
)
[src]

Unregisters the audio hook register that you have registered with audio_reg_hardware_hook_add_unchecked().

Please note that unregistering audio hook registers manually just for cleaning up is unnecessary in most situations because reaper-rs takes care of automatically unregistering everything when this struct is dropped (RAII). This happens even when using the unsafe function variants.

Safety

REAPER can crash if you pass an invalid pointer.

pub fn audio_reg_hardware_hook_add<T: MediumOnAudioBuffer + 'static>(
    &mut self,
    callback: T
) -> Result<NonNull<audio_hook_register_t>, ReaperFunctionError>
[src]

Registers an audio hook register.

This allows you to get called back in the real-time audio thread before and after REAPER's processing. You should be careful with this because you are entering real-time world.

This function returns a handle which you can use to unregister the audio hook register at any time via audio_reg_hardware_hook_remove() (from the main thread).

Errors

Returns an error if the registration failed.

Example

use reaper_medium::{
    MediumReaperControlSurface, MediumOnAudioBuffer, OnAudioBufferArgs,
    ReaperFunctions, RealTimeAudioThreadScope, MidiInputDeviceId
};

struct MyOnAudioBuffer {
    counter: u64,
    functions: ReaperFunctions<RealTimeAudioThreadScope>,
}

impl MediumOnAudioBuffer for MyOnAudioBuffer {
    fn call(&mut self, args: OnAudioBufferArgs) {
        // Mutate some own state (safe because we are the owner)
        if self.counter % 100 == 0 {
            println!("Audio hook callback counter: {}\n", self.counter);
        }
        self.counter += 1;
        // Read some MIDI events
        self.functions.get_midi_input(MidiInputDeviceId::new(0), |input| {
            for event in input.get_read_buf().enum_items(0) {
                println!("Received MIDI event {:?}", event);
            }   
        });
    }
}

reaper.audio_reg_hardware_hook_add(MyOnAudioBuffer {
    counter: 0,
    functions: reaper.create_real_time_functions()
});

pub fn audio_reg_hardware_hook_remove(
    &mut self,
    handle: NonNull<audio_hook_register_t>
)
[src]

Unregisters an audio hook register.

Trait Implementations

impl Debug for Reaper[src]

impl Default for Reaper[src]

impl Drop for Reaper[src]

Auto Trait Implementations

impl !RefUnwindSafe for Reaper

impl !Send for Reaper

impl !Sync for Reaper

impl Unpin for Reaper

impl !UnwindSafe for Reaper

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.