rrplug/
lib.rs

1//! # rrplug
2//! framework for working with [R2Northstar](https://northstar.tf/)'s plugin system.
3//!
4//! this crate provides convenient abstractions with compile time checks while not limiting unsafe access to any parts of plugin sys or the titanfall 2 engine.
5//!
6//! ## rrplug template
7//!
8//! plugins v4 removed some dependencies on external files so now templates are redundant but a [template](https://github.com/catornot/rrplug-template) still exists
9//!
10//! ## cross compiling plugins
11//!
12//! To compile a plugin from a host machine that's not using windows, you need to install the required target.
13//!
14//! ```bash
15//! rustup target add x86_64-pc-windows-gnu
16//! ```
17//!
18//! Then create a cargo config to always compile your project for windows.
19//!
20//! ```bash
21//! mkdir .cargo
22//! echo "[build]\ntarget = \"x86_64-pc-windows-gnu\"" > .cargo/config.toml
23//! ```
24
25#![deny(
26    unsafe_op_in_unsafe_fn,
27    clippy::correctness,
28    clippy::missing_const_for_fn
29)]
30#![warn(missing_docs)]
31#![allow(clippy::missing_safety_doc)] // toggle theese two for release/dev
32
33#[allow(missing_docs)]
34pub mod bindings;
35pub mod errors;
36pub mod high;
37pub mod interfaces;
38pub mod low;
39pub mod macros;
40pub mod mid;
41#[doc(hidden)]
42pub mod nslog;
43pub mod plugin;
44pub mod prelude;
45
46pub use rrplug_proc::{as_interface, completion, concommand, convar, sqfunction};
47
48#[doc(hidden)]
49/// used by some macros
50pub mod exports {
51    pub use log;
52    pub use once_cell::sync::OnceCell;
53    pub use windows;
54}
55
56#[doc(hidden)]
57/// used by [`rrplug::entry`]
58pub mod rrplug {
59    pub use super::*;
60}
61
62#[cfg(test)]
63mod test {
64    use crate as rrplug;
65    use rrplug::prelude::*;
66    use rrplug::{
67        high::squirrel_traits::{GetFromSQObject, GetFromSquirrelVm, PushToSquirrelVm, SQVMName},
68        mid::squirrel::{SQFuncInfo, SQFunctionContext},
69    };
70    use rrplug_proc::*;
71
72    #[convar]
73    fn test_convar(_old_string: String, _old_float: f32) -> () {}
74
75    #[convar]
76    fn test_convar_noargs() -> () {}
77
78    /// test doc
79    #[concommand]
80    fn test_concommand(command: CCommandResult) {
81        log::info!("test {:?}", command.get_args());
82    }
83
84    #[concommand]
85    fn test_concommand_noargs() {}
86
87    /// test doc
88    #[sqfunction(VM = "Server", ExportName = "test")]
89    fn test_sqfunction(
90        test1: String,
91        test2: i32,
92        test3: TestEnum,
93        mut test4: SquirrelFn<String>,
94    ) -> Result<Vec<TestStruct>, String> {
95        test4
96            .call(sqvm, sq_functions, test1.clone())
97            .map_err(|err| err.to_string())?;
98
99        Ok(vec![TestStruct {
100            a: test1,
101            b: test2,
102            c: test3,
103        }])
104    }
105
106    #[derive(PushToSquirrelVm, GetFromSquirrelVm, GetFromSQObject, SQVMName)]
107    #[repr(i32)]
108    enum TestEnum {
109        Wow,
110        Owo,
111    }
112
113    #[derive(PushToSquirrelVm, GetFromSquirrelVm, SQVMName, GetFromSQObject)]
114    struct TestStruct {
115        a: String,
116        b: i32,
117        c: TestEnum,
118    }
119
120    #[test]
121    fn test_test_sqfunction() {
122        let sqfuncdef = SQFuncInfo {
123            cpp_func_name: stringify!(test_sqfunction),
124            sq_func_name: "test",
125            types: "string test1, int test2, int test3, void functionref(string) test4".into(),
126            return_type: <Vec<TestStruct> as SQVMName>::get_sqvm_name(),
127            vm: SQFunctionContext::SERVER,
128            function: Some(sq_func_test_sqfunction),
129        };
130        assert_eq!(test_sqfunction(), sqfuncdef);
131    }
132}