diff --git a/pixlib_parser/src/runner/classes/animation.rs b/pixlib_parser/src/runner/classes/animation.rs index 60321e1..3712072 100644 --- a/pixlib_parser/src/runner/classes/animation.rs +++ b/pixlib_parser/src/runner/classes/animation.rs @@ -214,16 +214,25 @@ impl Animation { pub fn get_frame_position(&self) -> anyhow::Result<(isize, isize)> { let context = RunnerContext::new_minimal(&self.parent.parent.runner, &self.parent); + self.state + .borrow_mut() + .use_and_drop_mut(|s| s.load_if_needed(context.clone()))?; self.state.borrow().get_frame_position(context) } pub fn get_frame_size(&self) -> anyhow::Result<(usize, usize)> { let context = RunnerContext::new_minimal(&self.parent.parent.runner, &self.parent); + self.state + .borrow_mut() + .use_and_drop_mut(|s| s.load_if_needed(context.clone()))?; self.state.borrow().get_frame_size(context) } pub fn get_center_frame_position(&self) -> anyhow::Result<(isize, isize)> { let context = RunnerContext::new_minimal(&self.parent.parent.runner, &self.parent); + self.state + .borrow_mut() + .use_and_drop_mut(|s| s.load_if_needed(context.clone()))?; self.state.borrow().get_center_frame_position(context) } @@ -245,6 +254,9 @@ impl Animation { ) -> anyhow::Result> { // eprintln!("[ANIMO: {}] is_visible: {}", self.parent.name, self.is_visible); let context = RunnerContext::new_minimal(&self.parent.parent.runner, &self.parent); + self.state + .borrow_mut() + .use_and_drop_mut(|s| s.load_if_needed(context.clone()))?; let state = self.state.borrow(); if !state.is_visible { return Ok(None); @@ -295,6 +307,16 @@ impl Animation { let context = RunnerContext::new_minimal(&self.parent.parent.runner, &self.parent); self.state.borrow_mut().stop(context, emit_on_finished) } + + pub fn pause(&self) -> anyhow::Result<()> { + let context = RunnerContext::new_minimal(&self.parent.parent.runner, &self.parent); + self.state.borrow_mut().pause(context) + } + + pub fn resume(&self) -> anyhow::Result<()> { + let context = RunnerContext::new_minimal(&self.parent.parent.runner, &self.parent); + self.state.borrow_mut().resume(context) + } } impl CnvType for Animation { @@ -1261,10 +1283,7 @@ impl AnimationState { pub fn play(&mut self, context: RunnerContext, sequence_name: &str) -> anyhow::Result<()> { // PLAY (STRING) - if let AnimationFileData::NotLoaded(ref filename) = *self.file_data { - let filename = filename.clone(); - self.load(context.clone(), &filename)?; - }; + self.load_if_needed(context.clone())?; let AnimationFileData::Loaded(ref loaded_data) = *self.file_data.clone() else { return Err( RunnerError::NoAnimationDataLoaded(context.current_object.name.clone()).into(), @@ -1460,10 +1479,7 @@ impl AnimationState { pub fn stop(&mut self, context: RunnerContext, emit_on_finished: bool) -> anyhow::Result<()> { // STOP ([BOOL]) - if let AnimationFileData::NotLoaded(ref filename) = *self.file_data { - let filename = filename.clone(); - self.load(context.clone(), &filename)?; - }; + self.load_if_needed(context.clone())?; let AnimationFileData::Loaded(ref loaded_data) = *self.file_data.clone() else { return Err( RunnerError::NoAnimationDataLoaded(context.current_object.name.clone()).into(), @@ -1750,4 +1766,12 @@ impl AnimationState { }); Ok(()) } + + fn load_if_needed(&mut self, context: RunnerContext) -> anyhow::Result<()> { + if let AnimationFileData::NotLoaded(ref filename) = *self.file_data { + let filename = filename.clone(); + self.load(context, &filename)?; + }; + Ok(()) + } } diff --git a/pixlib_parser/src/runner/classes/array.rs b/pixlib_parser/src/runner/classes/array.rs index 9aed581..061f72f 100644 --- a/pixlib_parser/src/runner/classes/array.rs +++ b/pixlib_parser/src/runner/classes/array.rs @@ -121,7 +121,9 @@ impl CnvType for Array { CallableIdentifier::Method("FILL") => self.state.borrow_mut().fill().map(|_| None), CallableIdentifier::Method("FIND") => self.state.borrow().find().map(|_| None), CallableIdentifier::Method("FINDALL") => self.state.borrow().find_all().map(|_| None), - CallableIdentifier::Method("GET") => self.state.borrow().get().map(|_| None), + CallableIdentifier::Method("GET") => { + self.state.borrow().get(arguments[0].to_int() as usize) + } CallableIdentifier::Method("GETMARKERPOS") => { self.state.borrow().get_marker_pos().map(|_| None) } @@ -347,9 +349,9 @@ impl ArrayState { todo!() } - pub fn get(&self) -> anyhow::Result> { + pub fn get(&self, index: usize) -> anyhow::Result> { // GET - todo!() + Ok(self.values.get(index).cloned()) } pub fn get_marker_pos(&self) -> anyhow::Result { diff --git a/pixlib_parser/src/runner/classes/button.rs b/pixlib_parser/src/runner/classes/button.rs index 7aea5ce..4f692d5 100644 --- a/pixlib_parser/src/runner/classes/button.rs +++ b/pixlib_parser/src/runner/classes/button.rs @@ -523,7 +523,7 @@ impl ButtonState { fn set_interaction( &mut self, context: RunnerContext, - interaction: Interaction, + mut interaction: Interaction, ) -> anyhow::Result<()> { // println!( // "{}.set_interaction({:?})", @@ -537,6 +537,12 @@ impl ButtonState { }; let prev_interaction = self.current_interaction; self.current_interaction = interaction; + if interaction == Interaction::Pressing && self.graphics_on_click.is_none() { + interaction = Interaction::Hovering; + } + if interaction == Interaction::Hovering && self.graphics_on_hover.is_none() { + interaction = Interaction::None; + } if let Some(normal_obj) = self .graphics_normal .as_ref() @@ -550,9 +556,10 @@ impl ButtonState { } } else if let CnvContent::Animation(ref normal_animation) = &normal_obj.content { if interaction == Interaction::None { - normal_animation.play("PLAY") + normal_animation.show()?; + normal_animation.resume() } else { - normal_animation.stop(false)?; + normal_animation.pause()?; normal_animation.hide() } } else { @@ -591,9 +598,10 @@ impl ButtonState { } } else if let CnvContent::Animation(ref on_hover_animation) = &on_hover_obj.content { if interaction == Interaction::Hovering { - on_hover_animation.play("PLAY") + on_hover_animation.show()?; + on_hover_animation.resume() } else { - on_hover_animation.stop(false)?; + on_hover_animation.pause()?; on_hover_animation.hide() } } else { @@ -632,9 +640,10 @@ impl ButtonState { } } else if let CnvContent::Animation(ref on_click_animation) = &on_click_obj.content { if interaction == Interaction::Pressing { - on_click_animation.play("PLAY") + on_click_animation.show()?; + on_click_animation.resume() } else { - on_click_animation.stop(false)?; + on_click_animation.pause()?; on_click_animation.hide() } } else { diff --git a/pixlib_parser/src/runner/classes/episode.rs b/pixlib_parser/src/runner/classes/episode.rs index 7ac6201..6e59be4 100644 --- a/pixlib_parser/src/runner/classes/episode.rs +++ b/pixlib_parser/src/runner/classes/episode.rs @@ -22,7 +22,9 @@ pub struct EpisodeProperties { } #[derive(Debug, Clone, Default)] -pub struct EpisodeState {} +pub struct EpisodeState { + previous_scene_name: Option, +} #[derive(Debug, Clone)] pub struct EpisodeEventHandlers {} @@ -55,7 +57,9 @@ impl Episode { pub fn from_initial_properties(parent: Arc, props: EpisodeProperties) -> Self { let mut episode = Self { parent, - state: RefCell::new(EpisodeState {}), + state: RefCell::new(EpisodeState { + ..Default::default() + }), event_handlers: EpisodeEventHandlers {}, author: props.author.unwrap_or_default(), creation_time: props.creation_time, @@ -104,7 +108,9 @@ impl CnvType for Episode { ) -> anyhow::Result> { // println!("Calling method: {:?} of object: {:?}", name, self); match name { - CallableIdentifier::Method("BACK") => self.state.borrow_mut().back().map(|_| None), + CallableIdentifier::Method("BACK") => { + self.state.borrow_mut().back(context).map(|_| None) + } CallableIdentifier::Method("GETCURRENTSCENE") => { self.state.borrow().get_current_scene().map(|_| None) } @@ -179,9 +185,16 @@ impl CnvType for Episode { } impl EpisodeState { - pub fn back(&mut self) -> anyhow::Result<()> { + pub fn back(&mut self, context: RunnerContext) -> anyhow::Result<()> { // BACK - todo!() + let current_scene_name = context.runner.get_current_scene().map(|s| s.name.clone()); + let goto_name = self + .previous_scene_name + .take() + .or(current_scene_name.clone()) + .unwrap(); + self.previous_scene_name = current_scene_name; + context.runner.change_scene(&goto_name) } pub fn get_current_scene(&self) -> anyhow::Result<()> { @@ -196,6 +209,7 @@ impl EpisodeState { pub fn go_to(&mut self, context: RunnerContext, scene_name: &str) -> anyhow::Result<()> { // GOTO + self.previous_scene_name = context.runner.get_current_scene().map(|s| s.name.clone()); context.runner.change_scene(scene_name) } diff --git a/pixlib_parser/src/runner/classes/image.rs b/pixlib_parser/src/runner/classes/image.rs index 9640fb6..470baf0 100644 --- a/pixlib_parser/src/runner/classes/image.rs +++ b/pixlib_parser/src/runner/classes/image.rs @@ -150,16 +150,26 @@ impl Image { // custom pub fn get_position(&self) -> anyhow::Result<(isize, isize)> { + let context = RunnerContext::new_minimal(&self.parent.parent.runner, &self.parent); + self.state + .borrow_mut() + .use_and_drop_mut(|s| s.load_if_needed(context))?; self.state.borrow().get_position() } pub fn get_size(&self) -> anyhow::Result<(usize, usize)> { let context = RunnerContext::new_minimal(&self.parent.parent.runner, &self.parent); + self.state + .borrow_mut() + .use_and_drop_mut(|s| s.load_if_needed(context.clone()))?; self.state.borrow().get_size(context) } pub fn get_center_position(&self) -> anyhow::Result<(isize, isize)> { let context = RunnerContext::new_minimal(&self.parent.parent.runner, &self.parent); + self.state + .borrow_mut() + .use_and_drop_mut(|s| s.load_if_needed(context.clone()))?; self.state.borrow().get_center_position(context) } @@ -172,6 +182,10 @@ impl Image { } pub fn get_image_to_show(&self) -> anyhow::Result> { + let context = RunnerContext::new_minimal(&self.parent.parent.runner, &self.parent); + self.state + .borrow_mut() + .use_and_drop_mut(|s| s.load_if_needed(context))?; let state = self.state.borrow(); if !state.is_visible { return Ok(None); @@ -512,10 +526,7 @@ impl Initable for Image { fn initialize(&self, context: RunnerContext) -> anyhow::Result<()> { let mut state = self.state.borrow_mut(); if self.should_preload { - if let ImageFileData::NotLoaded(filename) = &state.file_data { - let filename = filename.clone(); - state.load(context.clone(), &filename)?; - }; + state.load_if_needed(context.clone())?; } context .runner @@ -876,4 +887,12 @@ impl ImageState { position.1 + (size.1 / 2) as isize, )) } + + pub fn load_if_needed(&mut self, context: RunnerContext) -> anyhow::Result<()> { + if let ImageFileData::NotLoaded(filename) = &self.file_data { + let filename = filename.clone(); + self.load(context, &filename)?; + }; + Ok(()) + } }