bi-directional timeline updates...

This commit is contained in:
Lee-Orr
2024-03-07 18:27:13 -05:00
parent d0e26bdaa2
commit 86f471de3c
3 changed files with 74 additions and 14 deletions
+1 -1
View File
@@ -61,7 +61,7 @@ fn draw_camera_keyframes(
gizmos.line(origin, origin + z_axis, Color::BLUE);
}
let seek_time = **r_seek_time;
let seek_time = r_seek_time.time;
let keyframes_sorted = q_cam_keyframes
.iter()
.sorted_by(|(a, _), (b, _)| a.partial_cmp(&b.0).unwrap())
-3
View File
@@ -36,9 +36,6 @@ impl Plugin for AnimPlugin {
camera::CameraAnimPlugin,
timeline_animation::TimelinePlugin,
));
#[cfg(feature = "wasm")]
app.add_systems(Update, wasm::update_global_seek_time);
}
}
+73 -10
View File
@@ -5,6 +5,7 @@ use bevy::{
},
prelude::*,
};
use serde::{Deserialize, Serialize};
use space_editor::space_prefab::editor_registry::EditorRegistryExt;
pub struct TimelinePlugin;
@@ -14,15 +15,38 @@ impl Plugin for TimelinePlugin {
app.register_type::<TimedAnimationClip>()
.editor_registry::<TimedAnimationClip>()
.register_type::<AnimationTarget>()
.editor_registry::<AnimationTarget>();
.editor_registry::<AnimationTarget>()
.add_event::<TimelineEvent>();
app.insert_resource(GlobalSeekTime(0.));
app.insert_resource(GlobalSeekTime {
time: 0.,
playing: false,
});
#[cfg(feature = "wasm")]
app.add_systems(
Update,
(
wasm::update_global_seek_time,
wasm::notify_seek_time_changes.map(bevy::utils::error),
),
);
}
}
#[derive(Resource, Clone, Copy, Debug, Default, Deref, DerefMut, Reflect)]
#[derive(Event, Clone, Copy, Debug)]
pub enum TimelineEvent {
Play,
Pause,
Seek(f32),
}
#[derive(Resource, Clone, Copy, Debug, Default, Reflect, Serialize, Deserialize)]
#[reflect(Resource)]
pub struct GlobalSeekTime(pub f32);
pub struct GlobalSeekTime {
pub time: f32,
pub playing: bool,
}
#[derive(Component, Clone, Debug, Reflect, PartialEq)]
#[reflect(Component, MapEntities)]
@@ -83,23 +107,62 @@ pub struct AnimationTarget;
#[cfg(feature = "wasm")]
mod wasm {
use bevy::prelude::*;
use bevy::{prelude::*, window::PrimaryWindow};
use wasm_bindgen::prelude::*;
use crate::wasm::{StaticBuffer, WasmMessageBuffer};
use super::GlobalSeekTime;
use super::{GlobalSeekTime, TimelineEvent};
static SEEK_TIME: WasmMessageBuffer<f32> = WasmMessageBuffer::new();
static SEEK_TIME: WasmMessageBuffer<TimelineEvent> = WasmMessageBuffer::new();
#[wasm_bindgen(js_name = seekTime)]
pub fn seek_time(timestamp: f32) {
SEEK_TIME.write_message(timestamp);
SEEK_TIME.write_message(TimelineEvent::Seek(timestamp));
}
pub(super) fn update_global_seek_time(mut r_seek_time: ResMut<GlobalSeekTime>) {
#[wasm_bindgen(js_name = play)]
pub fn play() {
SEEK_TIME.write_message(TimelineEvent::Play);
}
#[wasm_bindgen(js_name = pause)]
pub fn pause() {
SEEK_TIME.write_message(TimelineEvent::Pause);
}
pub(super) fn update_global_seek_time(mut e_timeline_event: EventWriter<TimelineEvent>) {
if let Some(timestamp) = SEEK_TIME.take_message() {
**r_seek_time = timestamp;
e_timeline_event.send(timestamp);
}
}
#[wasm_bindgen(typescript_custom_section)]
const SEEK_TIME_CHANGED_EVENT: &str = r#"
export interface SeekTimeChanged extends CustomEvent {
type: "seek-time-changed";
detail: number;
}
declare global {
export interface GlobalEventHandlersEventMap {
"seek-time-changed": CameraKeyframesEvent;
}
}
"#;
pub(super) fn notify_seek_time_changes(
r_global_seek_time: Res<GlobalSeekTime>,
q_window: Query<&Window, With<PrimaryWindow>>,
) -> Result<(), String> {
let Ok(window) = q_window.get_single() else {
return Ok(());
};
crate::wasm::dispatch_to_js(
window,
"seek-time-changed",
&serde_json::to_value(r_global_seek_time.as_ref()).map_err(|e| format!("{e}"))?,
)
}
}