diff --git a/crates/bevy_plugin/src/line_provider/text_provider/shared_text_provider.rs b/crates/bevy_plugin/src/line_provider/text_provider/shared_text_provider.rs index cdd92c23..2e169c56 100644 --- a/crates/bevy_plugin/src/line_provider/text_provider/shared_text_provider.rs +++ b/crates/bevy_plugin/src/line_provider/text_provider/shared_text_provider.rs @@ -46,6 +46,10 @@ impl TextProvider for SharedTextProvider { } impl UnderlyingTextProvider for SharedTextProvider { + fn clone_shallow(&self) -> Box { + Box::new(self.clone()) + } + fn accept_line_hints(&mut self, line_ids: &[LineId]) { self.0.write().unwrap().accept_line_hints(line_ids) } diff --git a/crates/bevy_plugin/src/line_provider/text_provider/strings_file_text_provider.rs b/crates/bevy_plugin/src/line_provider/text_provider/strings_file_text_provider.rs index f4c8783d..920c0ee0 100644 --- a/crates/bevy_plugin/src/line_provider/text_provider/strings_file_text_provider.rs +++ b/crates/bevy_plugin/src/line_provider/text_provider/strings_file_text_provider.rs @@ -41,6 +41,10 @@ impl Debug for StringsFileTextProvider { } impl UnderlyingTextProvider for StringsFileTextProvider { + fn clone_shallow(&self) -> Box { + Box::new(self.clone()) + } + fn accept_line_hints(&mut self, _line_ids: &[LineId]) { // no-op } diff --git a/crates/runtime/src/dialogue.rs b/crates/runtime/src/dialogue.rs index 4e9d94bd..7af72b3f 100644 --- a/crates/runtime/src/dialogue.rs +++ b/crates/runtime/src/dialogue.rs @@ -11,7 +11,7 @@ use yarnspinner_core::prelude::*; /// Co-ordinates the execution of Yarn programs. /// /// The main functions of interest are [`Dialogue::continue_`] and [`Dialogue::set_selected_option`]. -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Dialogue { vm: VirtualMachine, language_code: Option, diff --git a/crates/runtime/src/text_provider.rs b/crates/runtime/src/text_provider.rs index af64307f..78cc476a 100644 --- a/crates/runtime/src/text_provider.rs +++ b/crates/runtime/src/text_provider.rs @@ -13,6 +13,10 @@ use yarnspinner_core::prelude::*; /// /// By injecting this, we don't need to expose `Dialogue.ExpandSubstitutions` and `Dialogue.ParseMarkup`, since we can apply them internally. pub trait TextProvider: Debug + Send + Sync { + /// Creates a shallow clone of this text provider, i.e. a clone that + /// shares the same underlying provider and will thus be perfectly in sync + /// with the original instance. + fn clone_shallow(&self) -> Box; /// Passes the [`LineId`]s that this [`TextProvider`] should soon provide text for. These are the [`LineId`]s that are contained in the current node and are not required to be actually reached. fn accept_line_hints(&mut self, line_ids: &[LineId]); /// Returns the text for the given [`LineId`]. Will only be called if [`TextProvider::are_lines_available`] returns `true`. @@ -31,6 +35,12 @@ pub trait TextProvider: Debug + Send + Sync { fn as_any_mut(&mut self) -> &mut dyn Any; } +impl Clone for Box { + fn clone(&self) -> Self { + self.clone_shallow() + } +} + #[allow(missing_docs)] pub type StringTable = HashMap; @@ -73,6 +83,10 @@ impl StringTableTextProvider { } impl TextProvider for StringTableTextProvider { + fn clone_shallow(&self) -> Box { + Box::new(self.clone()) + } + fn accept_line_hints(&mut self, _line_ids: &[LineId]) { // no-op } diff --git a/crates/runtime/src/virtual_machine.rs b/crates/runtime/src/virtual_machine.rs index e847addb..b593e215 100644 --- a/crates/runtime/src/virtual_machine.rs +++ b/crates/runtime/src/virtual_machine.rs @@ -15,7 +15,7 @@ use yarnspinner_core::prelude::*; mod execution_state; mod state; -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct VirtualMachine { pub(crate) library: Library, pub(crate) program: Option, diff --git a/crates/yarnspinner/tests/test_base/text_provider.rs b/crates/yarnspinner/tests/test_base/text_provider.rs index dabc8b18..c2dcb3ff 100644 --- a/crates/yarnspinner/tests/test_base/text_provider.rs +++ b/crates/yarnspinner/tests/test_base/text_provider.rs @@ -22,6 +22,10 @@ impl SharedTextProvider { } impl TextProvider for SharedTextProvider { + fn clone_shallow(&self) -> Box { + Box::new(self.clone()) + } + fn accept_line_hints(&mut self, line_ids: &[LineId]) { self.0.write().unwrap().accept_line_hints(line_ids); }