Skip to content

Commit 416ee4d

Browse files
authored
refactor: remove StaticScripts resource (#473)
1 parent 419e31a commit 416ee4d

File tree

11 files changed

+64
-137
lines changed

11 files changed

+64
-137
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ bevy = { workspace = true, features = [
211211
"bevy_asset",
212212
"bevy_core_pipeline",
213213
"bevy_sprite",
214+
"x11",
214215
] }
215216
bevy_platform = { workspace = true }
216217
clap = { workspace = true, features = ["derive"] }

crates/bevy_mod_scripting_core/src/asset.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use ::{
1212
// },
1313
bevy_reflect::Reflect,
1414
};
15-
use bevy_asset::AssetServer;
15+
use bevy_asset::{AssetServer, Handle};
1616
use bevy_ecs::{
1717
entity::Entity,
1818
event::{EventReader, EventWriter},
@@ -23,11 +23,11 @@ use bevy_ecs::{
2323
use serde::{Deserialize, Serialize};
2424

2525
use crate::{
26-
IntoScriptPluginParams, LanguageExtensions, ScriptComponent, ScriptingSystemSet, StaticScripts,
26+
IntoScriptPluginParams, LanguageExtensions, ScriptComponent, ScriptingSystemSet,
2727
commands::{CreateOrUpdateScript, DeleteScript},
2828
error::ScriptError,
2929
event::ScriptEvent,
30-
script::{ContextKey, DisplayProxy, ScriptAttachment},
30+
script::{ContextKey, DisplayProxy, ScriptAttachment, ScriptContext},
3131
};
3232

3333
/// Represents a scripting language. Languages which compile into another language should use the target language as their language.
@@ -215,10 +215,10 @@ fn sync_assets(
215215
fn handle_script_events<P: IntoScriptPluginParams>(
216216
mut events: EventReader<ScriptEvent>,
217217
script_assets: Res<Assets<ScriptAsset>>,
218-
static_scripts: Res<StaticScripts>,
219218
scripts: Query<(Entity, &ScriptComponent)>,
220219
asset_server: Res<AssetServer>,
221220
mut script_queue: Local<ScriptQueue>,
221+
script_contexts: Res<ScriptContext<P>>,
222222
mut commands: Commands,
223223
world_id: WorldId,
224224
) {
@@ -233,6 +233,7 @@ fn handle_script_events<P: IntoScriptPluginParams>(
233233
// We need to reload the script for any context it's
234234
// associated with. That could be static scripts, script
235235
// components.
236+
236237
for (entity, script_component) in &scripts {
237238
if let Some(handle) =
238239
script_component.0.iter().find(|handle| handle.id() == *id)
@@ -247,13 +248,17 @@ fn handle_script_events<P: IntoScriptPluginParams>(
247248
}
248249
}
249250

250-
if let Some(handle) = static_scripts.scripts.iter().find(|s| s.id() == *id) {
251-
commands.queue(
252-
CreateOrUpdateScript::<P>::new(ScriptAttachment::StaticScript(
253-
handle.clone(),
254-
))
255-
.with_responses(P::readonly_configuration(world_id).emit_responses),
256-
);
251+
let handle = Handle::Weak(*id);
252+
let attachment = ScriptAttachment::StaticScript(handle.clone());
253+
for (resident, _) in script_contexts
254+
.residents(&attachment)
255+
.filter(|(r, _)| r.script() == handle && r.is_static())
256+
{
257+
// if the script does not have any associated entity it's static.
258+
commands
259+
.queue(CreateOrUpdateScript::<P>::new(resident).with_responses(
260+
P::readonly_configuration(world_id).emit_responses,
261+
));
257262
}
258263
}
259264
}

crates/bevy_mod_scripting_core/src/commands.rs

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::{
1414
},
1515
extractors::{HandlerContext, with_handler_system_state},
1616
handler::{handle_script_errors, send_callback_response},
17-
script::{DisplayProxy, ScriptAttachment, StaticScripts},
17+
script::{DisplayProxy, ScriptAttachment},
1818
};
1919
use bevy_ecs::{system::Command, world::World};
2020
use bevy_log::{error, info, trace};
@@ -56,7 +56,20 @@ impl<P: IntoScriptPluginParams> Command for DeleteScript<P> {
5656
// we demote to weak from here on out, so as not to hold the asset hostage
5757
self.context_key = self.context_key.into_weak();
5858

59-
// first apply unload callback
59+
// first check the script exists, if it does not it could have been deleted by another command
60+
{
61+
let script_contexts = world.get_resource_or_init::<ScriptContext<P>>();
62+
if !script_contexts.contains(&self.context_key) {
63+
debug!(
64+
"{}: No context found for {}, not deleting.",
65+
P::LANGUAGE,
66+
self.context_key
67+
);
68+
return;
69+
}
70+
}
71+
72+
// apply unload callback
6073
Command::apply(
6174
RunScriptCallback::<P>::new(
6275
self.context_key.clone(),
@@ -66,23 +79,6 @@ impl<P: IntoScriptPluginParams> Command for DeleteScript<P> {
6679
),
6780
world,
6881
);
69-
match &self.context_key {
70-
ScriptAttachment::EntityScript(_, _) => {
71-
// nothing special needs to be done, just the context removal
72-
}
73-
ScriptAttachment::StaticScript(script) => {
74-
// remove the static script
75-
let mut scripts = world.get_resource_or_init::<StaticScripts>();
76-
if scripts.remove(script.id()) {
77-
debug!("Deleted static script {}", script.display());
78-
} else {
79-
warn!(
80-
"Attempted to delete static script {}, but it was not found",
81-
script.display()
82-
);
83-
}
84-
}
85-
}
8682

8783
let mut script_contexts = world.get_resource_or_init::<ScriptContext<P>>();
8884
let residents_count = script_contexts.residents_len(&self.context_key);
@@ -225,10 +221,6 @@ impl<P: IntoScriptPluginParams> CreateOrUpdateScript<P> {
225221
) -> Result<(), ScriptError> {
226222
// we demote to weak from here on out, so as not to hold the asset hostage
227223
let attachment = attachment.clone().into_weak();
228-
if let ScriptAttachment::StaticScript(id) = &attachment {
229-
// add to static scripts
230-
handler_ctxt.static_scripts.insert(id.clone());
231-
}
232224

233225
let script_id = attachment.script();
234226

crates/bevy_mod_scripting_core/src/config.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ pub trait GetPluginThreadConfig<P: IntoScriptPluginParams + ?Sized> {
4646
fn readonly_configuration(world: WorldId) -> ScriptingPluginConfiguration<P>;
4747

4848
/// Set the configuration or overwrites it if already set.
49-
fn set_thread_config(world: WorldId, config: ScriptingPluginConfiguration<P>);
49+
fn set_world_local_config(world: WorldId, config: ScriptingPluginConfiguration<P>);
5050
}
5151

5252
#[macro_export]
@@ -76,7 +76,7 @@ macro_rules! make_plugin_config_static {
7676
)
7777
}
7878

79-
fn set_thread_config(
79+
fn set_world_local_config(
8080
world: bevy_ecs::world::WorldId,
8181
config: ScriptingPluginConfiguration<$ty>,
8282
) {

crates/bevy_mod_scripting_core/src/extractors.rs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use crate::{
2424
error::{InteropError, ScriptError},
2525
event::{CallbackLabel, IntoCallbackLabel},
2626
handler::ScriptingHandler,
27-
script::{ScriptAttachment, ScriptContext, StaticScripts},
27+
script::{ScriptAttachment, ScriptContext},
2828
};
2929

3030
/// Executes `system_state.get_mut` followed by `system_state.apply` after running the given closure, makes sure state is correctly handled in the context of an exclusive system.
@@ -47,8 +47,6 @@ pub fn with_handler_system_state<
4747

4848
/// Context for systems which handle events for scripts
4949
pub struct HandlerContext<P: IntoScriptPluginParams> {
50-
/// List of static scripts
51-
pub(crate) static_scripts: StaticScripts,
5250
/// Script context
5351
pub(crate) script_context: ScriptContext<P>,
5452
}
@@ -58,7 +56,6 @@ impl<P: IntoScriptPluginParams> HandlerContext<P> {
5856
/// Every call to this function must be paired with a call to [`Self::release`].
5957
pub fn yoink(world: &mut World) -> Self {
6058
Self {
61-
static_scripts: world.remove_resource().unwrap_or_default(),
6259
script_context: world.remove_resource().unwrap_or_default(),
6360
}
6461
}
@@ -67,15 +64,9 @@ impl<P: IntoScriptPluginParams> HandlerContext<P> {
6764
/// Only call this if you have previously yoinked the handler context from the world.
6865
pub fn release(self, world: &mut World) {
6966
// insert the handler context back into the world
70-
world.insert_resource(self.static_scripts);
7167
world.insert_resource(self.script_context);
7268
}
7369

74-
/// Get the static scripts
75-
pub fn static_scripts(&mut self) -> &mut StaticScripts {
76-
&mut self.static_scripts
77-
}
78-
7970
/// Get the static scripts
8071
pub fn script_context(&mut self) -> &mut ScriptContext<P> {
8172
&mut self.script_context

crates/bevy_mod_scripting_core/src/lib.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use context::{Context, ContextInitializer, ContextPreHandlingInitializer};
3333
use event::{ScriptCallbackEvent, ScriptCallbackResponseEvent, ScriptEvent};
3434
use handler::HandlerFn;
3535
use runtime::{Runtime, RuntimeInitializer};
36-
use script::{ContextPolicy, ScriptComponent, ScriptContext, StaticScripts};
36+
use script::{ContextPolicy, ScriptComponent, ScriptContext};
3737
use std::ops::{Deref, DerefMut};
3838

3939
pub mod asset;
@@ -165,7 +165,7 @@ impl<P: IntoScriptPluginParams> Plugin for ScriptingPlugin<P> {
165165
runtime: Box::leak(Box::new(runtime)),
166166
};
167167

168-
P::set_thread_config(app.world().id(), config);
168+
P::set_world_local_config(app.world().id(), config);
169169

170170
app.insert_resource(ScriptContext::<P>::new(self.context_policy.clone()));
171171

@@ -294,7 +294,6 @@ impl Plugin for BMSScriptingInfrastructurePlugin {
294294
.add_event::<ScriptCallbackEvent>()
295295
.add_event::<ScriptCallbackResponseEvent>()
296296
.init_resource::<AppReflectAllocator>()
297-
.init_resource::<StaticScripts>()
298297
.init_asset::<ScriptAsset>()
299298
.init_resource::<AppScriptFunctionRegistry>()
300299
.insert_resource(AppScheduleRegistry::new());

crates/bevy_mod_scripting_core/src/script/context_key.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,16 @@ impl ScriptAttachment {
6060
}
6161
}
6262
}
63+
64+
/// Returns true if the attachment is a static script.
65+
pub fn is_static(&self) -> bool {
66+
matches!(self, ScriptAttachment::StaticScript(_))
67+
}
68+
69+
/// Returns true if the attachment is an entity script.
70+
pub fn is_entity_script(&self) -> bool {
71+
matches!(self, ScriptAttachment::EntityScript(_, _))
72+
}
6373
}
6474

6575
impl From<ScriptAttachment> for ContextKey {

crates/bevy_mod_scripting_core/src/script/mod.rs

Lines changed: 0 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -125,88 +125,12 @@ impl ScriptComponent {
125125
}
126126
}
127127

128-
/// A collection of scripts, not associated with any entity.
129-
///
130-
/// Useful for `global` or `static` scripts which operate over a larger scope than a single entity.
131-
#[derive(Default, Resource)]
132-
pub struct StaticScripts {
133-
pub(crate) scripts: HashSet<Handle<ScriptAsset>>,
134-
}
135-
136-
#[profiling::all_functions]
137-
impl StaticScripts {
138-
/// Inserts a static script into the collection
139-
pub fn insert<S: Into<Handle<ScriptAsset>>>(&mut self, script: S) {
140-
self.scripts.insert(script.into());
141-
}
142-
143-
/// Removes a static script from the collection, returning `true` if the script was in the collection, `false` otherwise
144-
pub fn remove(&mut self, script_id: impl Into<ScriptId>) -> bool {
145-
let script_id = script_id.into();
146-
self.scripts
147-
.extract_if(|handle| handle.id() == script_id)
148-
.next()
149-
.is_some()
150-
}
151-
152-
/// Checks if a static script is in the collection
153-
/// Returns `true` if the script is in the collection, `false` otherwise
154-
pub fn contains(&self, script_id: impl Into<ScriptId>) -> bool {
155-
let script_id = script_id.into();
156-
self.scripts.iter().any(|handle| handle.id() == script_id)
157-
}
158-
159-
/// Returns an iterator over the static scripts
160-
pub fn values(&self) -> impl Iterator<Item = &Handle<ScriptAsset>> {
161-
self.scripts.iter()
162-
}
163-
}
164-
165128
#[cfg(test)]
166129
mod tests {
167130
use bevy_ecs::{event::Events, world::World};
168131

169132
use super::*;
170133

171-
#[test]
172-
fn static_scripts_insert() {
173-
let mut static_scripts = StaticScripts::default();
174-
let script1 = Handle::default();
175-
static_scripts.insert(script1.clone());
176-
assert_eq!(static_scripts.scripts.len(), 1);
177-
assert!(static_scripts.scripts.contains(&script1));
178-
}
179-
180-
#[test]
181-
fn static_scripts_remove() {
182-
let mut static_scripts = StaticScripts::default();
183-
let script1 = Handle::default();
184-
static_scripts.insert(script1.clone());
185-
assert_eq!(static_scripts.scripts.len(), 1);
186-
assert!(static_scripts.scripts.contains(&script1));
187-
assert!(static_scripts.remove(&script1));
188-
assert_eq!(static_scripts.scripts.len(), 0);
189-
assert!(!static_scripts.scripts.contains(&script1));
190-
}
191-
192-
fn scriptid_from_u128(uuid: u128) -> ScriptId {
193-
ScriptId::from(uuid::Builder::from_random_bytes(uuid.to_le_bytes()).into_uuid())
194-
}
195-
196-
fn handle_from_u128(uuid: u128) -> Handle<ScriptAsset> {
197-
Handle::Weak(scriptid_from_u128(uuid))
198-
}
199-
200-
#[test]
201-
fn static_scripts_contains() {
202-
let mut static_scripts = StaticScripts::default();
203-
let script1 = handle_from_u128(0);
204-
let script2 = handle_from_u128(1);
205-
static_scripts.insert(script1.clone());
206-
assert!(static_scripts.contains(&script1));
207-
assert!(!static_scripts.contains(&script2));
208-
}
209-
210134
#[test]
211135
fn test_component_add() {
212136
let mut world = World::new();

crates/languages/bevy_mod_scripting_lua/src/lib.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,14 +279,23 @@ mod test {
279279
let mut old_ctxt = lua.clone();
280280
let handle = Handle::Weak(AssetId::from(AssetIndex::from_bits(0)));
281281
let context_key = ScriptAttachment::EntityScript(Entity::from_raw(1), handle);
282-
282+
let world_id = WorldId::new().unwrap();
283+
LuaScriptingPlugin::set_world_local_config(
284+
world_id,
285+
ScriptingPluginConfiguration {
286+
pre_handling_callbacks: &[],
287+
context_initialization_callbacks: &[],
288+
emit_responses: false,
289+
runtime: &(),
290+
},
291+
);
283292
lua_context_load(
284293
&context_key,
285294
"function hello_world_from_first_load()
286295
287296
end"
288297
.as_bytes(),
289-
WorldId::new().unwrap(),
298+
world_id,
290299
)
291300
.unwrap();
292301

@@ -297,7 +306,7 @@ mod test {
297306
end"
298307
.as_bytes(),
299308
&mut old_ctxt,
300-
WorldId::new().unwrap(),
309+
world_id,
301310
)
302311
.unwrap();
303312

0 commit comments

Comments
 (0)