Skip to content

feat: Use the Handles, Luke! #427

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 43 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
f266228
feature: Use the Handles, Luke!
shanecelis Jun 27, 2025
31cf3fc
refactor: Make it work.
shanecelis Jul 14, 2025
41eb1fd
bug: Fix assignment; tests pass now.
shanecelis Jul 15, 2025
2ae1ec0
feature: Warn on lua script with no "mlua".
shanecelis Jul 15, 2025
6b66808
feature: Add run-script example and reload.lua.
shanecelis Jul 15, 2025
10a4a95
chore: Fix log.
shanecelis Jul 15, 2025
3b0e3b1
bug: Fix reloading.
shanecelis Jul 16, 2025
44dc750
refactor: Rename ContextKey::script_id to script.
shanecelis Jul 16, 2025
eaf4487
doc: Update add_context_initializer parameters.
shanecelis Jul 16, 2025
777ea93
chore: Add allows to inhibit a few warnings.
shanecelis Jul 17, 2025
4d140fc
feature: Add remove_context_on_script_removal.
shanecelis Jul 17, 2025
6202585
doc: Add migration guide.
shanecelis Jul 17, 2025
b8b0ef5
refactor: Deprecate enable_context_sharing().
shanecelis Jul 17, 2025
e949664
chore: Listen to Clippy.
shanecelis Jul 19, 2025
3f239b1
chore: Fix Clippy problems and failing test.
shanecelis Jul 20, 2025
2fd5e4e
fix leftover clippy warnings
makspll Jul 20, 2025
c73b99b
cargo fmt
makspll Jul 20, 2025
f251eae
bug: Limit global access block.
shanecelis Jul 21, 2025
08bb88f
partial: Start of ScriptEvent.
shanecelis Jul 21, 2025
d73e8d6
feature: Add sync_assets and sync_components.
shanecelis Jul 21, 2025
0146acc
refactor: Demote ScriptQueue to Local. Use ScriptEvent.
shanecelis Jul 22, 2025
ff71035
feature: Add sync_{assets, components}.
shanecelis Jul 22, 2025
19a5048
refactor: Clean up warnings.
shanecelis Jul 22, 2025
ebb1cfe
feature: Add ContextKeySelector idea.
shanecelis Jul 22, 2025
6a14068
doc: Note problem on ContextRule::Custom.
shanecelis Jul 22, 2025
f57ad06
refactor: Completely rework ScriptContext.
shanecelis Jul 23, 2025
6291fe4
refactor: Rename module 'key' to 'context_key'.
shanecelis Jul 23, 2025
c195d0e
test: Only one test failing in core now.
shanecelis Jul 23, 2025
7035ebd
refactor: All tests pass.
shanecelis Jul 23, 2025
9e939e3
refactor: Only store weak script handles as keys.
shanecelis Jul 23, 2025
8e01ece
doc: Update book for changes.
shanecelis Jul 24, 2025
b682bd6
chore: Fix Clippy warning.
shanecelis Jul 25, 2025
21d29a4
style: Run cargo fmt.
shanecelis Jul 25, 2025
436c507
WIP
makspll Aug 1, 2025
3f7ef1e
improvements to testing, remove domain for now, give scripts script h…
makspll Aug 4, 2025
7f9a0c9
add lifecycle test
makspll Aug 7, 2025
85d1781
fix lifecycle for static scripts
makspll Aug 8, 2025
9aa34c3
fix tests
makspll Aug 9, 2025
f33c6bc
more scenario tests
makspll Aug 9, 2025
46d578b
update docs
makspll Aug 9, 2025
ad8bbc8
fix docs
makspll Aug 9, 2025
6aa4be1
fix benches
makspll Aug 9, 2025
de70d12
new clippy issues
makspll Aug 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions assets/reload.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
-- reload.lua
--
-- An example of the script reload feature. Exercise with this command:
-- ```sh
-- cargo run --features lua54,bevy/file_watcher,bevy/multi_threaded --example run-script -- reload.lua
-- ```
function on_script_loaded()
world.info("Hello world")
end

function on_script_unloaded()
world.info("Goodbye world")
return "house"
end

function on_script_reloaded(value)
if value then
world.info("I'm back. Thanks for the "..value.." keys!")
else
world.info('I have not saved any state before unloading')
end
end
32 changes: 16 additions & 16 deletions assets/tests/add_system/added_systems_run_in_parallel.lua
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@

function on_test()
local post_update_schedule = world.get_schedule_by_name("PostUpdate")

local test_system = post_update_schedule:get_system_by_name("on_test_post_update")


local script_attachment = ScriptAttachment.new_entity_script(entity, script_asset)

local system_a = world.add_system(
post_update_schedule,
system_builder("custom_system_a", script_id)
:after(test_system)
system_builder("custom_system_a", script_attachment)
:after(test_system)
)

local system_b = world.add_system(
post_update_schedule,
system_builder("custom_system_b", script_id)
:after(test_system)
)
system_builder("custom_system_b", script_attachment)
:after(test_system)
)

-- generate a schedule graph and verify it's what we expect
local dot_graph = post_update_schedule:render_dot()

local expected_dot_graph = [[
digraph {
node_0 [label="bevy_mod_scripting_core::bindings::allocator::garbage_collector"];
node_1 [label="on_test_post_update"];
node_2 [label="script_integration_test_harness::dummy_before_post_update_system"];
node_3 [label="script_integration_test_harness::dummy_post_update_system"];
node_1 [label="script_integration_test_harness::dummy_before_post_update_system"];
node_2 [label="script_integration_test_harness::dummy_post_update_system"];
node_3 [label="on_test_post_update"];
node_4 [label="custom_system_a"];
node_5 [label="custom_system_b"];
node_6 [label="SystemSet GarbageCollection"];
Expand All @@ -33,11 +34,10 @@ digraph {
node_0 -> node_6 [color=red, label="child of", arrowhead=diamond];
node_4 -> node_7 [color=red, label="child of", arrowhead=diamond];
node_5 -> node_8 [color=red, label="child of", arrowhead=diamond];
node_1 -> node_4 [color=blue, label="runs before", arrowhead=normal];
node_1 -> node_5 [color=blue, label="runs before", arrowhead=normal];
node_2 -> node_3 [color=blue, label="runs before", arrowhead=normal];
node_1 -> node_2 [color=blue, label="runs before", arrowhead=normal];
node_3 -> node_4 [color=blue, label="runs before", arrowhead=normal];
node_3 -> node_5 [color=blue, label="runs before", arrowhead=normal];
}
]]

assert_str_eq(dot_graph, expected_dot_graph, "Expected the schedule graph to match the expected graph")
end
17 changes: 9 additions & 8 deletions assets/tests/add_system/added_systems_run_in_parallel.rhai
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
fn on_test() {
let post_update_schedule = world.get_schedule_by_name.call("PostUpdate");

let script_attachment = ScriptAttachment.new_entity_script.call(entity, script_asset);
let test_system = post_update_schedule.get_system_by_name.call("on_test_post_update");

let system_a = world.add_system.call(
post_update_schedule,
system_builder.call("custom_system_a", script_id)
system_builder.call("custom_system_a", script_attachment)
.after.call(test_system)
);

let system_b = world.add_system.call(
post_update_schedule,
system_builder.call("custom_system_b", script_id)
system_builder.call("custom_system_b", script_attachment)
.after.call(test_system)
);

Expand All @@ -21,9 +22,9 @@ fn on_test() {
let expected_dot_graph = `
digraph {
node_0 [label="bevy_mod_scripting_core::bindings::allocator::garbage_collector"];
node_1 [label="on_test_post_update"];
node_2 [label="script_integration_test_harness::dummy_before_post_update_system"];
node_3 [label="script_integration_test_harness::dummy_post_update_system"];
node_1 [label="script_integration_test_harness::dummy_before_post_update_system"];
node_2 [label="script_integration_test_harness::dummy_post_update_system"];
node_3 [label="on_test_post_update"];
node_4 [label="custom_system_a"];
node_5 [label="custom_system_b"];
node_6 [label="SystemSet GarbageCollection"];
Expand All @@ -32,9 +33,9 @@ digraph {
node_0 -> node_6 [color=red, label="child of", arrowhead=diamond];
node_4 -> node_7 [color=red, label="child of", arrowhead=diamond];
node_5 -> node_8 [color=red, label="child of", arrowhead=diamond];
node_1 -> node_4 [color=blue, label="runs before", arrowhead=normal];
node_1 -> node_5 [color=blue, label="runs before", arrowhead=normal];
node_2 -> node_3 [color=blue, label="runs before", arrowhead=normal];
node_1 -> node_2 [color=blue, label="runs before", arrowhead=normal];
node_3 -> node_4 [color=blue, label="runs before", arrowhead=normal];
node_3 -> node_5 [color=blue, label="runs before", arrowhead=normal];
}`;

assert_str_eq.call(dot_graph, expected_dot_graph, "Expected the schedule graph to match the expected graph");
Expand Down
33 changes: 17 additions & 16 deletions assets/tests/add_system/adds_system_in_correct_order.lua
Original file line number Diff line number Diff line change
@@ -1,41 +1,41 @@
-- add two systems, one before and one after the existing `on_test_post_update` callback, then assert all systems have run
-- in the `on_test_last` callback

local runs = {}
local runs = {}

-- runs on `Update`
function on_test()
local post_update_schedule = world.get_schedule_by_name("PostUpdate")

local test_system = post_update_schedule:get_system_by_name("on_test_post_update")

local script_attachment = ScriptAttachment.new_entity_script(entity, script_asset)

local system_after = world.add_system(
post_update_schedule,
system_builder("custom_system_after", script_id)
:after(test_system)
system_builder("custom_system_after", script_attachment)
:after(test_system)
)

local system_before = world.add_system(
post_update_schedule,
system_builder("custom_system_before", script_id)
:before(test_system)
)
system_builder("custom_system_before", script_attachment)
:before(test_system)
)

local script_system_between = world.add_system(
post_update_schedule,
system_builder("custom_system_between", script_id)
:after(test_system)
:before(system_after)
system_builder("custom_system_between", script_attachment)
:after(test_system)
:before(system_after)
)
end


function custom_system_before()
print("custom_system_before")
runs[#runs + 1] = "custom_system_before"
end

-- runs on post_update
-- runs on post_update
function on_test_post_update()
print("on_test_post_update")
runs[#runs + 1] = "on_test_post_update"
Expand All @@ -53,9 +53,10 @@ end

-- runs in the `Last` bevy schedule
function on_test_last()
assert(#runs == 4, "Expected 4 runs, got: " .. #runs)
local string_table = table.concat(runs, ", ")
assert(#runs == 4, "Expected 4 runs, got: " .. tostring(string_table))
assert(runs[1] == "custom_system_before", "Expected custom_system_before to run first, got: " .. runs[1])
assert(runs[2] == "on_test_post_update", "Expected on_test_post_update to run second, got: " .. runs[2])
assert(runs[3] == "custom_system_between", "Expected custom_system_between to run third, got: " .. runs[3])
assert(runs[4] == "custom_system_after", "Expected custom_system_after to run second, got: " .. runs[4])
end
end
7 changes: 4 additions & 3 deletions assets/tests/add_system/adds_system_in_correct_order.rhai
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@ let runs = [];
fn on_test() {
let post_update_schedule = world.get_schedule_by_name.call("PostUpdate");
let test_system = post_update_schedule.get_system_by_name.call("on_test_post_update");
let script_attachment = ScriptAttachment.new_entity_script.call(entity, script_asset);

let builder_after = system_builder.call("custom_system_after", script_id)
let builder_after = system_builder.call("custom_system_after", script_attachment)
.after.call(test_system);
let system_after = world.add_system.call(post_update_schedule, builder_after);

let builder_before = system_builder.call("custom_system_before", script_id)
let builder_before = system_builder.call("custom_system_before", script_attachment)
.before.call(test_system);
let system_before = world.add_system.call(post_update_schedule, builder_before);

let builder_between = system_builder.call("custom_system_between", script_id)
let builder_between = system_builder.call("custom_system_between", script_attachment)
.after.call(test_system)
.before.call(system_after);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@

runs = {}

function on_test()
local post_update_schedule = world.get_schedule_by_name("PostUpdate")

local script_attachment = ScriptAttachment.new_entity_script(entity, script_asset)
world.add_system(
post_update_schedule,
system_builder("my_exclusive_system", script_id):exclusive()
system_builder("my_exclusive_system", script_attachment):exclusive()
)

return true
Expand All @@ -21,12 +20,11 @@ function my_exclusive_system()
assert(res ~= nil, "Expected to get resource but got nil")
end


function on_test_post_update()
return true
end

function on_test_last()
assert(#runs == 1, "Expected 1 runs, got: " .. #runs)
return true
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ let runs = [];

fn on_test() {
let post_update_schedule = world.get_schedule_by_name.call("PostUpdate");

let script_attachment = ScriptAttachment.new_entity_script.call(entity, script_asset);

world.add_system.call(
post_update_schedule,
system_builder.call("my_exclusive_system", script_id).exclusive.call()
system_builder.call("my_exclusive_system", script_attachment).exclusive.call()
);

return true;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@

runs = {}

function on_test()
local post_update_schedule = world.get_schedule_by_name("PostUpdate")

local script_attachment = ScriptAttachment.new_entity_script(entity, script_asset)

world.add_system(
post_update_schedule,
system_builder("my_non_exclusive_system", script_id)
system_builder("my_non_exclusive_system", script_attachment)
)

return true
Expand All @@ -23,12 +23,11 @@ function my_non_exclusive_system()
end, ".*annot claim access to.*")
end


function on_test_post_update()
return true
end

function on_test_last()
assert(#runs == 1, "Expected 1 runs, got: " .. #runs)
return true
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ let runs = [];

fn on_test() {
let post_update_schedule = world.get_schedule_by_name.call("PostUpdate");
world.add_system.call(post_update_schedule, system_builder.call("my_non_exclusive_system", script_id));
let script_attachment = ScriptAttachment.new_entity_script.call(entity, script_asset);
world.add_system.call(post_update_schedule, system_builder.call("my_non_exclusive_system", script_attachment));
return true;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

runs = {}
local ResourceTypeA = world.get_type_by_name("TestResource")
local ResourceTypeB = world.get_type_by_name("TestResourceWithVariousFields")
Expand All @@ -7,7 +6,9 @@ local ComponentB = world.get_type_by_name("CompWithDefaultAndComponentData")

function on_test()
local post_update_schedule = world.get_schedule_by_name("PostUpdate")



local script_attachment = ScriptAttachment.new_entity_script(entity, script_asset)
local entity = world.spawn()
local entity2 = world.spawn()

Expand All @@ -17,18 +18,19 @@ function on_test()
world.add_default_component(entity2, ComponentA)
world.add_default_component(entity2, ComponentB)


world.add_system(
post_update_schedule,
system_builder("my_parameterised_system", script_id)
:resource(ResourceTypeA)
:query(world.query():component(ComponentA):component(ComponentB))
:resource(ResourceTypeB)
system_builder("my_parameterised_system", script_attachment)
:resource(ResourceTypeA)
:query(world.query():component(ComponentA):component(ComponentB))
:resource(ResourceTypeB)
)

return true
end

function my_parameterised_system(resourceA,query,resourceB)
function my_parameterised_system(resourceA, query, resourceB)
print("my_parameterised_system")
runs[#runs + 1] = "my_non_exclusive_system"

Expand All @@ -39,7 +41,7 @@ function my_parameterised_system(resourceA,query,resourceB)
assert(#resourceA.bytes == 6, "Expected 6 bytes, got: " .. #resourceA.bytes)
assert(resourceB.string == "Initial Value", "Expected 'Initial Value', got: " .. resourceB.string)
assert(#query == 2, "Expected 3 results, got: " .. #query)
for i,result in pairs(query) do
for i, result in pairs(query) do
components = result:components()
assert(#components == 2, "Expected 2 components, got " .. #components)
local componentA = components[1]
Expand All @@ -49,12 +51,11 @@ function my_parameterised_system(resourceA,query,resourceB)
end
end


function on_test_post_update()
return true
end

function on_test_last()
assert(#runs == 1, "Expected 1 runs, got: " .. #runs)
return true
end
end
Loading
Loading