1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#![doc(html_root_url = "https://docs.rs/reaper-low/0.1.0")]

//! This crate contains the low-level API of [reaper-rs](https://github.com/helgoboss/reaper-rs).
//!
//! It is not recommended to use this API directly because it just exposes the raw REAPER C++
//! functions, types and constants one to one in Rust. If you want idiomatic Rust, type safety and
//! convenience, please use the [medium-level] or [high-level] API instead.
//!
//! At times it can still be useful to access the low-level API, mostly as fallback if the function
//! that you are looking for has not yet been lifted to the medium-level API. To get started, best
//! navigate to the [`Reaper`] struct, which contains all exposed functions.
//!
//! # Example
//!
//! ```no_run
//! # let reaper = reaper_low::Reaper::default();
//! use c_str_macro::c_str;
//! use std::ptr::null_mut;
//!
//! unsafe {
//!     reaper.ShowConsoleMsg(c_str!("Hello world from reaper-rs low-level API!").as_ptr());
//!     let track = reaper.GetTrack(null_mut(), 0);
//!     reaper.DeleteTrack(track);
//! }
//! ```
//!
//! # Design
//!
//! ## Goal
//!
//! The ultimate goal of the low-level API is to be on par with the REAPER C++ API, meaning
//! that everything which is possible with the REAPER C++ API is also possible with the *reaper-rs*
//! low-level API. Improvements regarding safety, convenience or style are not in its scope. It
//! should serve as a base for more idiomatic APIs built on top of it.
//!
//! ## Generated code
//!
//! Most parts of the low-level API are auto-generated from `reaper_plugin_functions.h` using a
//! combination of [bindgen](https://docs.rs/bindgen) and custom build script.
//!
//! ## C++ glue code
//!
//! There's some code which is not auto-generated, most notably the code to "restore" functionality
//! which "got lost in translation". The problem is that some parts of the REAPER C++ API not just
//! use C but also C++ features, in particular virtual base classes. Rust can't call virtual
//! functions or implement them.
//!
//! The solution is to take a detour via C++ glue code:
//!
//! - Rust calling a C++ virtual function provided by REAPER:
//!     - Implement a method on the raw struct in Rust which calls a function written in C which in
//!       turn calls the C++ virtual function (Rust function → C function → C++ virtual function)
//!     - Example: `midi.rs` & `midi.cpp`
//!
//! - REAPER calling a C++ virtual function provided by Rust:
//!     - Implement the virtual base class in C++, let each function delegate to a corresponding
//!       free Rust function which in turn calls a method of a trait object (REAPER → C++ virtual
//!       function → Rust function)
//!     - Example: `control_surface.cpp` & `control_surface.rs`
//!
//! [medium-level]: /reaper_medium/index.html
//! [high-level]: /reaper_high/index.html
//! [`Reaper`]: struct.Reaper.html
mod bindings;

pub mod raw;

mod control_surface;
pub use control_surface::*;

mod util;
pub use util::*;

mod reaper_plugin_context;
pub use reaper_plugin_context::*;

mod reaper;
pub use reaper::*;

mod reaper_impl;
pub use reaper_impl::*;

mod midi;
pub use midi::*;