@@ -548,10 +548,11 @@ use crate::{
548
548
} ;
549
549
pub use livesplit_auto_splitting:: { settings, wasi_path} ;
550
550
use livesplit_auto_splitting:: {
551
- AutoSplitter , Config , CreationError , InterruptHandle , Timer as AutoSplitTimer , TimerState ,
551
+ AutoSplitter , CompiledAutoSplitter , Config , CreationError , InterruptHandle ,
552
+ Timer as AutoSplitTimer , TimerState ,
552
553
} ;
553
554
use snafu:: Snafu ;
554
- use std:: { fmt, fs, io, path:: PathBuf , thread, time:: Duration } ;
555
+ use std:: { cell :: RefCell , fmt, fs, io, path:: PathBuf , thread, time:: Duration } ;
555
556
use tokio:: {
556
557
runtime,
557
558
sync:: watch,
@@ -587,6 +588,7 @@ pub struct Runtime<T> {
587
588
interrupt_receiver : watch:: Receiver < Option < InterruptHandle > > ,
588
589
auto_splitter : watch:: Sender < Option < AutoSplitter < Timer < T > > > > ,
589
590
runtime : livesplit_auto_splitting:: Runtime ,
591
+ compiled_auto_splitter : RefCell < Option < CompiledAutoSplitter > > ,
590
592
}
591
593
592
594
impl < T > Drop for Runtime < T > {
@@ -641,17 +643,30 @@ impl<T: event::Sink + TimerQuery + Send + 'static> Runtime<T> {
641
643
auto_splitter : sender,
642
644
// TODO: unwrap?
643
645
runtime : livesplit_auto_splitting:: Runtime :: new ( Config :: default ( ) ) . unwrap ( ) ,
646
+ compiled_auto_splitter : RefCell :: new ( None ) ,
644
647
}
645
648
}
646
649
647
650
/// Attempts to load a wasm file containing an auto splitter module.
648
651
pub fn load ( & self , path : PathBuf , timer : T ) -> Result < ( ) , Error > {
649
652
let data = fs:: read ( path) . map_err ( |e| Error :: ReadFileFailed { source : e } ) ?;
650
653
651
- let auto_splitter = self
654
+ let compiled_auto_splitter = self
652
655
. runtime
653
656
. compile ( & data)
654
- . map_err ( |e| Error :: LoadFailed { source : e } ) ?
657
+ . map_err ( |e| Error :: LoadFailed { source : e } ) ?;
658
+ self . instantiate ( & compiled_auto_splitter, timer) ?;
659
+ * self . compiled_auto_splitter . borrow_mut ( ) = Some ( compiled_auto_splitter) ;
660
+ Ok ( ( ) )
661
+ }
662
+
663
+ /// Instantiates the compiled auto splitter.
664
+ fn instantiate (
665
+ & self ,
666
+ compiled_auto_splitter : & CompiledAutoSplitter ,
667
+ timer : T ,
668
+ ) -> Result < ( ) , Error > {
669
+ let auto_splitter = compiled_auto_splitter
655
670
. instantiate ( Timer ( timer) , None , None )
656
671
. map_err ( |e| Error :: LoadFailed { source : e } ) ?;
657
672
@@ -669,6 +684,15 @@ impl<T: event::Sink + TimerQuery + Send + 'static> Runtime<T> {
669
684
. map_err ( |_| Error :: ThreadStopped )
670
685
}
671
686
687
+ /// Reloads the auto splitter without re-compiling.
688
+ pub fn reload ( & self , timer : T ) -> Result < ( ) , Error > {
689
+ self . unload ( ) ?;
690
+ if let Some ( compiled_auto_splitter) = self . compiled_auto_splitter . borrow ( ) . as_ref ( ) {
691
+ self . instantiate ( compiled_auto_splitter, timer) ?;
692
+ }
693
+ Ok ( ( ) )
694
+ }
695
+
672
696
/// Accesses a copy of the currently stored settings. The auto splitter can
673
697
/// change these at any time. If you intend to make modifications to the
674
698
/// settings, you need to set them again via
0 commit comments