From cecfc223d1fb0c841825395523f8221bc5e36f41 Mon Sep 17 00:00:00 2001 From: jabu Date: Sat, 13 May 2023 13:59:07 -0500 Subject: [PATCH] fix some events getting missed, add SpineSet::OnEvent, add changelog --- changelog.md | 13 ++++ examples/events.rs | 2 +- src/lib.rs | 145 +++++++++++++++++++++++---------------------- 3 files changed, 89 insertions(+), 71 deletions(-) create mode 100644 changelog.md diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..f5d9a89 --- /dev/null +++ b/changelog.md @@ -0,0 +1,13 @@ +# 0.6.0 +- Improved premultiplied alpha support by pre-processing premultiplied textures. +- Support Spine texture runtime settings +- Add `SpineSet::OnEvent` +- Fix some events getting missed + +# 0.5.0 +- Update to Bevy 0.10 +- Add lots of docs +- Improve asset loading +- Allow Spines to be spawned in one frame +- Add Atlas handle to `SpineTextureCreateEvent` +- No longer force textures to Nearest diff --git a/examples/events.rs b/examples/events.rs index ba6d4f6..610e4cb 100644 --- a/examples/events.rs +++ b/examples/events.rs @@ -10,7 +10,7 @@ fn main() { .add_plugin(SpinePlugin) .add_startup_system(setup) .add_system(on_spawn.in_set(SpineSet::OnReady)) - .add_system(on_spine_event) + .add_system(on_spine_event.in_set(SpineSet::OnEvent)) .add_system(footstep_update) .run(); } diff --git a/src/lib.rs b/src/lib.rs index 1d934b8..60bd114 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -73,10 +73,13 @@ pub enum SpineSystem { /// Helper sets for interacting with Spine systems. #[derive(Debug, Hash, PartialEq, Eq, Clone, Copy, SystemSet)] pub enum SpineSet { - /// A helper Set which systems can be added into, occuring after [`SpineSystem::Ready`] but - /// before [`SpineSystem::Update`], so that entities can configure a newly spawned skeleton - /// before they are updated for the first time. + /// A helper Set occuring after [`SpineSystem::Ready`] but before [`SpineSystem::Update`], so + /// that systems can configure a newly spawned skeleton before they are updated for the first + /// time. OnReady, + /// A helper Set occuring after [`SpineSystem::Update`] but before [`SpineSystem::Render`], so + /// that systems can handle events immediately after the skeleton updates but before it renders. + OnEvent, } /// Add Spine support to Bevy! @@ -105,6 +108,7 @@ impl Plugin for SpinePlugin { .add_plugin(Material2dPlugin::::default()) .add_plugin(Material2dPlugin::::default()) .add_plugin(SpineSyncPlugin::first()) + .init_resource::() .insert_resource(SpineTextures::init()) .insert_resource(SpineReadyEvents::default()) .add_event::() @@ -133,9 +137,14 @@ impl Plugin for SpinePlugin { .add_system( spine_update .in_set(SpineSystem::Update) - .after(SpineSet::OnReady), + .after(SpineSet::OnReady) + .before(SpineSet::OnEvent), + ) + .add_system( + spine_render + .in_set(SpineSystem::Render) + .after(SpineSet::OnEvent), ) - .add_system(spine_render.in_set(SpineSystem::Render)) .add_system( apply_system_buffers .in_set(SpineSystem::SpawnFlush) @@ -163,6 +172,9 @@ impl Plugin for SpinePlugin { } } +#[derive(Resource, Default)] +struct SpineEventQueue(Arc>>); + /// A live Spine [`SkeletonController`] [`Component`], ready to be manipulated. /// /// This component does not exist on [`SpineBundle`] initially, since Spine assets may not yet be @@ -501,6 +513,7 @@ fn spine_spawn( mut meshes: ResMut>, mut ready_events: ResMut, mut skeleton_data_assets: ResMut>, + spine_event_queue: Res, ) { for (mut spine_loader, entity, data_handle, crossfades) in skeleton_query.iter_mut() { if let SpineLoader::Loading { with_children } = spine_loader.as_ref() { @@ -525,6 +538,61 @@ fn spine_spawn( .with_cull_direction(CullDirection::CounterClockwise) .with_premultiplied_alpha(skeleton_data_asset.premultiplied_alpha), ); + let events = spine_event_queue.0.clone(); + controller.animation_state.set_listener( + move |_animation_state, event_type, track_entry, spine_event| { + match event_type { + EventType::Start => { + let mut events = events.lock().unwrap(); + events.push_back(SpineEvent::Start { + entity, + animation: track_entry.animation().name().to_owned(), + }); + } + EventType::Interrupt => { + let mut events = events.lock().unwrap(); + events.push_back(SpineEvent::Interrupt { + entity, + animation: track_entry.animation().name().to_owned(), + }); + } + EventType::End => { + let mut events = events.lock().unwrap(); + events.push_back(SpineEvent::End { + entity, + animation: track_entry.animation().name().to_owned(), + }); + } + EventType::Complete => { + let mut events = events.lock().unwrap(); + events.push_back(SpineEvent::Complete { + entity, + animation: track_entry.animation().name().to_owned(), + }); + } + EventType::Dispose => { + let mut events = events.lock().unwrap(); + events.push_back(SpineEvent::Dispose { entity }); + } + EventType::Event => { + if let Some(spine_event) = spine_event { + let mut events = events.lock().unwrap(); + events.push_back(SpineEvent::Event { + entity, + name: spine_event.data().name().to_owned(), + int: spine_event.int_value(), + float: spine_event.float_value(), + string: spine_event.string_value().to_owned(), + audio_path: spine_event.data().audio_path().to_owned(), + volume: spine_event.volume(), + balance: spine_event.balance(), + }); + } + } + _ => {} + } + }, + ); controller.skeleton.set_to_setup_pose(); let mut bones = HashMap::new(); if let Some(mut entity_commands) = commands.get_entity(entity) { @@ -622,80 +690,17 @@ fn spine_ready( } } -#[derive(Default)] -struct SpineUpdateLocal { - events: Arc>>, -} - fn spine_update( mut spine_query: Query<(Entity, &mut Spine)>, - mut spine_ready_events: EventReader, mut spine_events: EventWriter, time: Res