Skip to content

Commit e7f003f

Browse files
committed
WIP script systems
1 parent 3374206 commit e7f003f

File tree

26 files changed

+1096
-100
lines changed

26 files changed

+1096
-100
lines changed

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ features = ["lua54", "rhai"]
2323
default = ["core_functions", "bevy_bindings"]
2424

2525
## lua
26-
lua = ["bevy_mod_scripting_lua"]
26+
lua = ["bevy_mod_scripting_lua", "bevy_mod_scripting_functions/lua_bindings"]
2727
# one of these must be selected
2828
lua51 = ["bevy_mod_scripting_lua/lua51", "lua"]
2929
lua52 = ["bevy_mod_scripting_lua/lua52", "lua"]
@@ -45,7 +45,7 @@ mlua_async = ["bevy_mod_scripting_lua?/mlua_async"]
4545

4646

4747
## rhai
48-
rhai = ["bevy_mod_scripting_rhai"]
48+
rhai = ["bevy_mod_scripting_rhai", "bevy_mod_scripting_functions/rhai_bindings"]
4949

5050
## rune
5151
# rune = ["bevy_mod_scripting_rune"]
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
local post_update_schedule = world.get_schedule_by_name("PostUpdate")
2+
3+
local system = world.add_system(
4+
post_update_schedule,
5+
system_builder("custom_system", script_id)
6+
)
7+
8+
local retrieved_system = post_update_schedule:get_system_by_name("custom_system")
9+
assert(retrieved_system:path() == "custom_system", "System path is not correct got: ".. retrieved_system:path())
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
-- add system to PostUpdate, attach it to a `custom_system` callback, and assert it has run after the test
2+
local post_update_schedule = world.get_schedule_by_name("PostUpdate")
3+
4+
5+
6+
7+
local system = world.add_system(
8+
post_update_schedule,
9+
system_builder("custom_system", script_id))
10+
11+
local system_after = world.add_system(
12+
post_update_schedule,
13+
system_builder("custom_system_after", script_id)
14+
:after(system)
15+
)
16+
17+
local system_before = world.add_system(
18+
post_update_schedule,
19+
system_builder("custom_system_before", script_id)
20+
:before(system)
21+
)
22+
23+
24+
25+
26+
local runs = {}
27+
28+
function custom_system()
29+
print("custom_system")
30+
runs[#runs + 1] = "custom_system"
31+
end
32+
33+
function custom_system_before()
34+
print("custom_system_before")
35+
runs[#runs + 1] = "custom_system_before"
36+
end
37+
38+
function custom_system_after()
39+
print("custom_system_after")
40+
runs[#runs + 1] = "custom_system_after"
41+
end
42+
43+
-- runs in the `Last` bevy schedule
44+
function on_test_last()
45+
assert(#runs == 3, "Expected 3 runs, got: " .. #runs)
46+
assert(runs[1] == "custom_system_before", "Expected custom_system_before to run first, got: " .. runs[1])
47+
assert(runs[2] == "custom_system", "Expected custom_system to run second, got: " .. runs[2])
48+
assert(runs[3] == "custom_system_after", "Expected custom_system_after to run third, got: " .. runs[3])
49+
end
50+
51+
assert(system:identifier() == "script_system_custom_system", "System identifier is not correct got: ".. system:identifier())
52+
assert(system_before:identifier() == "script_system_custom_system_before", "System identifier is not correct got: ".. system_before:identifier())
53+
assert(system_after:identifier() == "script_system_custom_system_after", "System identifier is not correct got: ".. system_after:identifier())
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
assert(world.get_schedule_by_name("Update") ~= nil, "Schedule not found under short identifier")
2+
assert(world.get_schedule_by_name("bevy_app::main_schedule::Update") ~= nil, "Schedule not found under long identifier")
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
assert(type_of(world.get_schedule_by_name.call("Update")) != "()", "Schedule not found under short identifier");
2+
assert(type_of(world.get_schedule_by_name.call("bevy_app::main_schedule::Update")) != "()", "Schedule not found under long identifier");
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
local schedule = world.get_schedule_by_name("Startup")
2+
local systems = schedule:systems()
3+
4+
-- contains event_handler system
5+
assert(#systems == 1, "Schedule does not contain all systems")
6+
7+
assert(schedule:get_system_by_name("dummy_startup_system"):identifier() == "dummy_startup_system", "System identifier was wrong")
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
let schedule = world.get_schedule_by_name.call("Startup");
2+
let systems = schedule.systems.call();
3+
4+
assert(systems.len() == 1, "Schedule does not contain all systems");
5+
assert(schedule.get_system_by_name.call("dummy_startup_system").identifier.call() == "dummy_startup_system", "System identifier was wrong");

crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Implementations of the [`ScriptFunction`] and [`ScriptFunctionMut`] traits for functions with up to 13 arguments.
22
33
use super::{from::FromScript, into::IntoScript, namespace::Namespace};
4+
use crate::asset::Language;
45
use crate::bindings::function::arg_meta::ArgMeta;
56
use crate::docgen::info::{FunctionInfo, GetFunctionInfo};
67
use crate::{
@@ -38,24 +39,30 @@ pub trait ScriptFunctionMut<'env, Marker> {
3839

3940
/// The caller context when calling a script function.
4041
/// Functions can choose to react to caller preferences such as converting 1-indexed numbers to 0-indexed numbers
41-
#[derive(Clone, Copy, Debug, Reflect, Default)]
42+
#[derive(Clone, Debug, Reflect)]
4243
#[reflect(opaque)]
4344
pub struct FunctionCallContext {
44-
/// Whether the caller uses 1-indexing on all indexes and expects 0-indexing conversions to be performed.
45-
pub convert_to_0_indexed: bool,
45+
language: Language,
4646
}
4747
impl FunctionCallContext {
4848
/// Create a new FunctionCallContext with the given 1-indexing conversion preference
49-
pub fn new(convert_to_0_indexed: bool) -> Self {
50-
Self {
51-
convert_to_0_indexed,
52-
}
49+
pub const fn new(language: Language) -> Self {
50+
Self { language }
5351
}
5452

5553
/// Tries to access the world, returning an error if the world is not available
5654
pub fn world<'l>(&self) -> Result<WorldGuard<'l>, InteropError> {
5755
ThreadWorldContainer.try_get_world()
5856
}
57+
/// Whether the caller uses 1-indexing on all indexes and expects 0-indexing conversions to be performed.
58+
pub fn convert_to_0_indexed(&self) -> bool {
59+
matches!(&self.language, Language::Lua)
60+
}
61+
62+
/// Gets the scripting language of the caller
63+
pub fn language(&self) -> Language {
64+
self.language.clone()
65+
}
5966
}
6067

6168
#[derive(Clone, Reflect)]
@@ -589,7 +596,7 @@ macro_rules! impl_script_function {
589596
let received_args_len = args.len();
590597
let expected_arg_count = count!($($param )*);
591598

592-
$( let $context = caller_context; )?
599+
$( let $context = caller_context.clone(); )?
593600
let world = caller_context.world()?;
594601
// Safety: we're not holding any references to the world, the arguments which might have aliased will always be dropped
595602
let ret: Result<ScriptValue, InteropError> = unsafe {
@@ -672,7 +679,10 @@ mod test {
672679

673680
with_local_world(|| {
674681
let out = script_function
675-
.call(vec![ScriptValue::from(1)], FunctionCallContext::default())
682+
.call(
683+
vec![ScriptValue::from(1)],
684+
FunctionCallContext::new(Language::Lua),
685+
)
676686
.unwrap();
677687

678688
assert_eq!(out, ScriptValue::from(1));
@@ -685,8 +695,10 @@ mod test {
685695
let script_function = fn_.into_dynamic_script_function().with_name("my_fn");
686696

687697
with_local_world(|| {
688-
let out =
689-
script_function.call(vec![ScriptValue::from(1)], FunctionCallContext::default());
698+
let out = script_function.call(
699+
vec![ScriptValue::from(1)],
700+
FunctionCallContext::new(Language::Lua),
701+
);
690702

691703
assert!(out.is_err());
692704
assert_eq!(
@@ -709,11 +721,13 @@ mod test {
709721
let script_function = fn_.into_dynamic_script_function().with_name("my_fn");
710722

711723
with_local_world(|| {
712-
let out =
713-
script_function.call(vec![ScriptValue::from(1)], FunctionCallContext::default());
724+
let out = script_function.call(
725+
vec![ScriptValue::from(1)],
726+
FunctionCallContext::new(Language::Lua),
727+
);
714728

715729
assert!(out.is_err());
716-
let world = FunctionCallContext::default().world().unwrap();
730+
let world = FunctionCallContext::new(Language::Lua).world().unwrap();
717731
// assert no access is held
718732
assert!(world.list_accesses().is_empty());
719733
});

crates/bevy_mod_scripting_core/src/bindings/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ pub mod function;
66
pub mod pretty_print;
77
pub mod query;
88
pub mod reference;
9+
pub mod schedule;
910
pub mod script_value;
1011
pub mod world;
1112

0 commit comments

Comments
 (0)