example/
example.rs

1use std::sync::{Arc, Mutex};
2
3use bevy::prelude::*;
4use bevy_scripting_rune::{rune, ScriptingRunePlugin};
5
6/// Resource that store the value and handle to the script
7#[derive(Resource, Default)]
8struct MyResource {
9    value: Arc<Mutex<f64>>,
10    script_handle: Handle<bevy_scripting_rune::Script>,
11}
12
13/// Structure used by the script engine
14#[derive(rune::Any, Default)]
15#[rune(item=::example)]
16struct MyStructure {
17    value: Arc<Mutex<f64>>,
18}
19
20impl MyStructure {
21    /// Update value
22    #[rune::function]
23    fn update_value(&mut self, new_value: f64) {
24        *self.value.lock().unwrap() += new_value;
25    }
26    /// Get value
27    #[rune::function]
28    fn get_value(&self) -> f64 {
29        *self.value.lock().unwrap()
30    }
31}
32
33fn setup(
34    asset_server: Res<AssetServer>,
35    mut my_resource: ResMut<MyResource>,
36    mut executor: ResMut<bevy_scripting_rune::Executor>,
37) {
38    // Setup the module
39    let mut module = rune::Module::with_crate("example").unwrap();
40    module.ty::<MyStructure>().unwrap();
41    module.function_meta(MyStructure::update_value).unwrap();
42    module.function_meta(MyStructure::get_value).unwrap();
43
44    // Insert the module in the executor
45    executor.insert_module(module).unwrap();
46
47    // Load script asset
48    my_resource.script_handle = asset_server.load("example.rn");
49}
50
51/// Wait for an event telling that the script was loaded
52fn compile_script(
53    mut ev_asset: EventReader<AssetEvent<bevy_scripting_rune::Script>>,
54    script_assets: Res<Assets<bevy_scripting_rune::Script>>,
55    mut executor: ResMut<bevy_scripting_rune::Executor>,
56    mut next_state: ResMut<NextState<States>>,
57) {
58    for ev in ev_asset.read() {
59        match ev {
60            AssetEvent::LoadedWithDependencies { id } => {
61                // Retrieve the script and compile it
62                let script = script_assets.get(*id).unwrap();
63                executor.load_script(script).unwrap();
64                executor.build().unwrap();
65                // Move to the running state
66                next_state.set(States::Running);
67            }
68            _ => {}
69        }
70    }
71}
72
73fn run(my_resource: ResMut<MyResource>, executor: Res<bevy_scripting_rune::Executor>) {
74    // Call the update_value function from the script
75    executor
76        .call::<()>(
77            "update_value",
78            (
79                MyStructure {
80                    value: my_resource.value.clone(),
81                },
82                4.0,
83            ),
84        )
85        .unwrap();
86    // Display the result
87    println!("my_structure.value = {}", my_resource.value.lock().unwrap());
88}
89
90#[derive(Debug, States, Default, Hash, Eq, PartialEq, Clone)]
91enum States {
92    #[default]
93    Loading,
94    Running,
95}
96
97fn main() {
98    App::new()
99        .add_plugins((DefaultPlugins, ScriptingRunePlugin))
100        .init_state::<States>()
101        .init_resource::<MyResource>()
102        .add_systems(Startup, setup)
103        .add_systems(Update, compile_script.run_if(in_state(States::Loading)))
104        .add_systems(Update, run.run_if(in_state(States::Running)))
105        .run();
106}