reaper_low/lib.rs
1#![doc(html_root_url = "https://docs.rs/reaper-low/0.1.0")]
2
3//! This crate contains the low-level API of [reaper-rs](https://github.com/helgoboss/reaper-rs).
4//!
5//! It is not recommended to use this API directly because it just exposes the raw REAPER C++
6//! functions, types and constants one to one in Rust. If you want idiomatic Rust, type safety and
7//! convenience, please use the [medium-level] or [high-level] API instead.
8//!
9//! At times it can still be useful to access the low-level API, mostly as fallback if the function
10//! that you are looking for has not yet been lifted to the medium-level API. To get started, best
11//! navigate to the [`Reaper`] struct, which contains all exposed functions.
12//!
13//! # Example
14//!
15//! ```no_run
16//! # let reaper = reaper_low::Reaper::default();
17//! use c_str_macro::c_str;
18//! use std::ptr::null_mut;
19//!
20//! unsafe {
21//! reaper.ShowConsoleMsg(c_str!("Hello world from reaper-rs low-level API!").as_ptr());
22//! let track = reaper.GetTrack(null_mut(), 0);
23//! reaper.DeleteTrack(track);
24//! }
25//! ```
26//!
27//! # Design
28//!
29//! ## Goal
30//!
31//! The ultimate goal of the low-level API is to be on par with the REAPER C++ API, meaning
32//! that everything which is possible with the REAPER C++ API is also possible with the *reaper-rs*
33//! low-level API. Improvements regarding safety, convenience or style are not in its scope. It
34//! should serve as a base for more idiomatic APIs built on top of it.
35//!
36//! ## Generated code
37//!
38//! Most parts of the low-level API are auto-generated from `reaper_plugin_functions.h` using a
39//! combination of [bindgen](https://docs.rs/bindgen) and custom build script.
40//!
41//! ## C++ glue code
42//!
43//! There's some code which is not auto-generated, most notably the code to "restore" functionality
44//! which "got lost in translation". The problem is that some parts of the REAPER C++ API not just
45//! use C but also C++ features, in particular virtual base classes. Rust can't call virtual
46//! functions or implement them.
47//!
48//! The solution is to take a detour via C++ glue code:
49//!
50//! - Rust calling a C++ virtual function provided by REAPER:
51//! - Implement a method on the raw struct in Rust which calls a function written in C which in
52//! turn calls the C++ virtual function (Rust function → C function → C++ virtual function)
53//! - Example: `midi.rs` & `midi.cpp`
54//!
55//! - REAPER calling a C++ virtual function provided by Rust:
56//! - Implement the virtual base class in C++, let each function delegate to a corresponding
57//! free Rust function which in turn calls a method of a trait object (REAPER → C++ virtual
58//! function → Rust function)
59//! - Example: `control_surface.cpp` & `control_surface.rs`
60//!
61//! [medium-level]: /reaper_medium/index.html
62//! [high-level]: /reaper_high/index.html
63//! [`Reaper`]: struct.Reaper.html
64mod bindings;
65
66pub mod raw;
67
68mod control_surface;
69pub use control_surface::*;
70
71mod util;
72pub use util::*;
73
74mod reaper_plugin_context;
75pub use reaper_plugin_context::*;
76
77mod reaper;
78pub use reaper::*;
79
80mod reaper_impl;
81pub use reaper_impl::*;
82
83mod midi;
84pub use midi::*;