Bevy Code & Blender addon for a simple workflow to add & edit Bevy components in Blender
Other
592
stars
55
forks
source link
Blenvy for Bevy: the world sometimes does not get a `BlueprintReadyForFinalizing` even when all descendants with `BlueprintInfo` are `BlueprintInstanceReady`, resulting in the world stuck loading forever. #205
#[derive(Debug, Resource, Deref, DerefMut)]
struct LoadTimer(Timer);
impl Default for LoadTimer {
fn default() -> Self {
Self(Timer::from_seconds(10.0, TimerMode::Once))
}
}
/// Needed because `BlueprintReadyForFinalizing` is not inserted on `World` in about 25% of runs on Wasm
/// due to a bug that is probably coming from Blenvy
fn hack_loading(
time: Res<Time>,
mut commands: Commands,
q_loading: Query<
Entity,
(
With<BlueprintSpawning>,
Without<BlueprintReadyForFinalizing>,
Without<BlueprintInstanceReady>,
),
>,
q_children: Query<&Children>,
q_blueprints: Query<Has<BlueprintInstanceReady>, With<BlueprintInfo>>,
mut load_timer: ResMut<LoadTimer>,
) {
if !load_timer.finished() {
load_timer.tick(time.delta());
return;
}
if q_loading.is_empty() {
return;
}
let mut processed = HashSet::new();
let mut ready_map = HashMap::new();
for loading in q_loading.iter() {
if processed.contains(&loading) {
continue;
}
go_through_children(
&mut commands,
&q_children,
&q_blueprints,
loading,
&mut ready_map,
);
processed.insert(loading);
}
}
fn go_through_children(
commands: &mut Commands,
q_children: &Query<&Children>,
q_blueprints: &Query<Has<BlueprintInstanceReady>, With<BlueprintInfo>>,
entity: Entity,
ready_map: &mut HashMap<Entity, bool>,
) -> bool {
if q_blueprints.contains(entity) && !q_children.contains(entity) {
ready_map.insert(entity, false);
return false;
}
match q_children.get(entity) {
Ok(children) => {
let ready = children.iter().all(|child| {
if let Some(ready) = ready_map.get(child) {
*ready
} else {
let ready =
go_through_children(commands, q_children, q_blueprints, *child, ready_map);
ready_map.insert(*child, ready);
ready
}
});
if ready {
ready_map.insert(entity, true);
commands.entity(entity).insert(BlueprintReadyForFinalizing);
}
ready
}
Err(_) => true,
}
}
Due to this only happening on Wasm, where scheduling is single threaded, and only happening sometimes, I am pretty certain this is due to a scheduling ambiguity.
This happens about 25% of the time on Wasm. The following hack brings this down to about 15%:
and the following is a complete workaround:
Due to this only happening on Wasm, where scheduling is single threaded, and only happening sometimes, I am pretty certain this is due to a scheduling ambiguity.