Trait reaper_low::IReaperControlSurface
source · [−]pub trait IReaperControlSurface: Debug + Downcast {
Show 21 methods
fn GetTypeString(&self) -> *const c_char { ... }
fn GetDescString(&self) -> *const c_char { ... }
fn GetConfigString(&self) -> *const c_char { ... }
fn CloseNoReset(&self) { ... }
fn Run(&mut self) { ... }
fn SetTrackListChange(&self) { ... }
fn SetSurfaceVolume(&self, _trackid: *mut MediaTrack, _volume: f64) { ... }
fn SetSurfacePan(&self, _trackid: *mut MediaTrack, _pan: f64) { ... }
fn SetSurfaceMute(&self, _trackid: *mut MediaTrack, _mute: bool) { ... }
fn SetSurfaceSelected(&self, _trackid: *mut MediaTrack, _selected: bool) { ... }
fn SetSurfaceSolo(&self, _trackid: *mut MediaTrack, _solo: bool) { ... }
fn SetSurfaceRecArm(&self, _trackid: *mut MediaTrack, _recarm: bool) { ... }
fn SetPlayState(&self, _play: bool, _pause: bool, _rec: bool) { ... }
fn SetRepeatState(&self, _rep: bool) { ... }
fn SetTrackTitle(&self, _trackid: *mut MediaTrack, _title: *const c_char) { ... }
fn GetTouchState(&self, _trackid: *mut MediaTrack, _isPan: c_int) -> bool { ... }
fn SetAutoMode(&self, _mode: c_int) { ... }
fn ResetCachedVolPanStates(&self) { ... }
fn OnTrackSelection(&self, _trackid: *mut MediaTrack) { ... }
fn IsKeyDown(&self, _key: c_int) -> bool { ... }
fn Extended(
&self,
_call: c_int,
_parm1: *mut c_void,
_parm2: *mut c_void,
_parm3: *mut c_void
) -> c_int { ... }
}
Expand description
This is the Rust analog to the C++ virtual base class IReaperControlSurface
.
An implementation of this trait can be passed to create_cpp_to_rust_control_surface()
. After
registering the returned C++ counterpart, REAPER will start invoking the callback methods.
Design
Why do most methods here don’t take &mut self
as parameter?
Short answer: Because we follow the spirit of Rust here, which is to fail fast and thereby prevent undefined behavior.
Long answer: Taking self
as &mut
in control surface methods would give us a dangerous
illusion of safety (safety as defined by Rust). It would tell Rust developers “It’s safe here to
mutate the state of my control surface struct”. But in reality it’s not safe. Not because of
multi-threading (ControlSurfaces methods are invoked by REAPER’s main thread only) but because
of reentrancy. That can happen quite easily, just think of this scenario: A track is changed,
REAPER notifies us about it by calling a ControlSurface method, thereby causing another change
in REAPER which in turn synchronously notifies our ControlSurface again while our first method
is still running … and there you go: 2 mutable borrows of self
. In a Rust-only world, Rust’s
compiler wouldn’t allow us to do that. But Rust won’t save us here because the call comes from
“outside”. By not having a &mut self
reference, developers are forced to explicitly think
about this scenario. One can use a RefCell
along with borrow_mut()
to still mutate some
control surface state and failing fast whenever reentrancy happens - at runtime, by getting a
panic. This is not as good as failing fast at compile time but still much better than to run
into undefined behavior, which could cause hard-to-find bugs and crash REAPER - that’s the last
thing we want! Panicking is not so bad. We can catch it before it reaches REAPER and therefore
let REAPER continue running. Ideally it’s observed by the developer when he tests his plugin.
Then he can think about how to solve that issue. They might find out that it’s okay and
therefore use some unsafe code to prevent the panic. They might find out that they want to check
for reentrancy by using try_borrow_mut()
. Or they might find out that they want to
avoid this situation by just deferring the event handling to the next main loop cycle.
Provided Methods
fn GetTypeString(&self) -> *const c_char
fn GetDescString(&self) -> *const c_char
fn GetConfigString(&self) -> *const c_char
fn CloseNoReset(&self)
fn Run(&mut self)
fn SetTrackListChange(&self)
fn SetSurfaceVolume(&self, _trackid: *mut MediaTrack, _volume: f64)
fn SetSurfacePan(&self, _trackid: *mut MediaTrack, _pan: f64)
fn SetSurfaceMute(&self, _trackid: *mut MediaTrack, _mute: bool)
fn SetSurfaceSelected(&self, _trackid: *mut MediaTrack, _selected: bool)
fn SetSurfaceSolo(&self, _trackid: *mut MediaTrack, _solo: bool)
fn SetSurfaceRecArm(&self, _trackid: *mut MediaTrack, _recarm: bool)
fn SetPlayState(&self, _play: bool, _pause: bool, _rec: bool)
fn SetRepeatState(&self, _rep: bool)
fn SetTrackTitle(&self, _trackid: *mut MediaTrack, _title: *const c_char)
fn GetTouchState(&self, _trackid: *mut MediaTrack, _isPan: c_int) -> bool
fn SetAutoMode(&self, _mode: c_int)
fn ResetCachedVolPanStates(&self)
fn OnTrackSelection(&self, _trackid: *mut MediaTrack)
fn IsKeyDown(&self, _key: c_int) -> bool
fn Extended(
&self,
_call: c_int,
_parm1: *mut c_void,
_parm2: *mut c_void,
_parm3: *mut c_void
) -> c_int
Implementations
sourceimpl dyn IReaperControlSurface
impl dyn IReaperControlSurface
sourcepub fn is<__T: IReaperControlSurface>(&self) -> bool
pub fn is<__T: IReaperControlSurface>(&self) -> bool
Returns true if the trait object wraps an object of type __T
.
sourcepub fn downcast<__T: IReaperControlSurface>(
self: Box<Self>
) -> Result<Box<__T>, Box<Self>>
pub fn downcast<__T: IReaperControlSurface>(
self: Box<Self>
) -> Result<Box<__T>, Box<Self>>
Returns a boxed object from a boxed trait object if the underlying object is of type
__T
. Returns the original boxed trait if it isn’t.
sourcepub fn downcast_rc<__T: IReaperControlSurface>(
self: Rc<Self>
) -> Result<Rc<__T>, Rc<Self>>
pub fn downcast_rc<__T: IReaperControlSurface>(
self: Rc<Self>
) -> Result<Rc<__T>, Rc<Self>>
Returns an Rc
-ed object from an Rc
-ed trait object if the underlying object is of
type __T
. Returns the original Rc
-ed trait if it isn’t.
sourcepub fn downcast_ref<__T: IReaperControlSurface>(&self) -> Option<&__T>
pub fn downcast_ref<__T: IReaperControlSurface>(&self) -> Option<&__T>
Returns a reference to the object within the trait object if it is of type __T
, or
None
if it isn’t.
sourcepub fn downcast_mut<__T: IReaperControlSurface>(&mut self) -> Option<&mut __T>
pub fn downcast_mut<__T: IReaperControlSurface>(&mut self) -> Option<&mut __T>
Returns a mutable reference to the object within the trait object if it is of type
__T
, or None
if it isn’t.