@@ -558,15 +558,16 @@ use crate::{
558558} ;
559559use arc_swap:: ArcSwapOption ;
560560use livesplit_auto_splitting:: {
561- AutoSplitter , Config , CreationError , LogLevel , Timer as AutoSplitTimer , TimerState ,
561+ AutoSplitter , CompiledAutoSplitter , Config , CreationError , LogLevel ,
562+ Timer as AutoSplitTimer , TimerState ,
562563} ;
563564pub use livesplit_auto_splitting:: { settings, wasi_path} ;
564565use snafu:: Snafu ;
565566use std:: {
566567 fmt, fs, io,
567568 path:: PathBuf ,
568569 sync:: {
569- Condvar , Mutex ,
570+ Condvar , Mutex , RwLock ,
570571 mpsc:: { self , Receiver , RecvTimeoutError , Sender } ,
571572 } ,
572573 thread,
@@ -602,6 +603,7 @@ pub struct Runtime<T: event::CommandSink + TimerQuery + Send + 'static> {
602603 shared_state : Arc < SharedState < T > > ,
603604 changed_sender : Sender < ( ) > ,
604605 runtime : livesplit_auto_splitting:: Runtime ,
606+ compiled_auto_splitter : RwLock < Option < CompiledAutoSplitter > > ,
605607}
606608
607609struct SharedState < T > {
@@ -676,18 +678,32 @@ impl<T: event::CommandSink + TimerQuery + Send + 'static> Runtime<T> {
676678 changed_sender,
677679 // TODO: unwrap?
678680 runtime : livesplit_auto_splitting:: Runtime :: new ( Config :: default ( ) ) . unwrap ( ) ,
681+ compiled_auto_splitter : RwLock :: new ( None ) ,
679682 }
680683 }
681684
682685 /// Attempts to load a wasm file containing an auto splitter module.
683686 pub fn load ( & self , path : PathBuf , timer : T ) -> Result < ( ) , Error > {
684687 let data = fs:: read ( path) . map_err ( |e| Error :: ReadFileFailed { source : e } ) ?;
685688
686- let auto_splitter = self
689+ let compiled_auto_splitter = self
687690 . runtime
688691 . compile ( & data)
689- . map_err ( |e| Error :: LoadFailed { source : e } ) ?
690- . instantiate ( Timer ( timer) , None , None )
692+ . map_err ( |e| Error :: LoadFailed { source : e } ) ?;
693+ self . instantiate ( & compiled_auto_splitter, timer) ?;
694+ * self . compiled_auto_splitter . write ( ) . unwrap ( ) = Some ( compiled_auto_splitter) ;
695+ Ok ( ( ) )
696+ }
697+
698+ /// Instantiates the compiled auto splitter.
699+ fn instantiate (
700+ & self ,
701+ compiled_auto_splitter : & CompiledAutoSplitter ,
702+ timer : T ,
703+ ) -> Result < ( ) , Error > {
704+ let settings_map = timer. get_timer ( ) . run ( ) . auto_splitter_settings_map_load ( ) ;
705+ let auto_splitter = compiled_auto_splitter
706+ . instantiate ( Timer ( timer) , settings_map, None )
691707 . map_err ( |e| Error :: LoadFailed { source : e } ) ?;
692708
693709 self . shared_state
@@ -710,6 +726,15 @@ impl<T: event::CommandSink + TimerQuery + Send + 'static> Runtime<T> {
710726 . map_err ( |_| Error :: ThreadStopped )
711727 }
712728
729+ /// Reloads the auto splitter without re-compiling.
730+ pub fn reload ( & self , timer : T ) -> Result < ( ) , Error > {
731+ self . unload ( ) ?;
732+ if let Some ( compiled_auto_splitter) = self . compiled_auto_splitter . read ( ) . unwrap ( ) . as_ref ( ) {
733+ self . instantiate ( compiled_auto_splitter, timer) ?;
734+ }
735+ Ok ( ( ) )
736+ }
737+
713738 /// Accesses a copy of the currently stored settings. The auto splitter can
714739 /// change these at any time. If you intend to make modifications to the
715740 /// settings, you need to set them again via
0 commit comments