diff --git a/pkg/config/config.yaml b/pkg/config/config.yaml index 1f73955a..d00ff5c1 100644 --- a/pkg/config/config.yaml +++ b/pkg/config/config.yaml @@ -192,6 +192,7 @@ emulator: # Some cores allow binding multiple devices to a single port (DosBox), but typically, # you should bind just one device to one port. # - kbMouseSupport (bool) -- (temp) a flag if the core needs the keyboard and mouse on the client + # - nonBlockingSave (bool) -- write save file in a non-blocking way, needed for huge save files # - vfr (bool) # (experimental) # Enable variable frame rate only for cores that can't produce a constant frame rate. @@ -271,6 +272,7 @@ emulator: roms: [ "zip", "cue" ] folder: dos kbMouseSupport: true + nonBlockingSave: true hid: 0: [ 257, 513 ] 1: [ 257, 513 ] diff --git a/pkg/config/emulator.go b/pkg/config/emulator.go index ddb08ba5..2a25f740 100644 --- a/pkg/config/emulator.go +++ b/pkg/config/emulator.go @@ -50,6 +50,7 @@ type LibretroCoreConfig struct { IsGlAllowed bool KbMouseSupport bool Lib string + NonBlockingSave bool Options map[string]string Options4rom map[string]map[string]string // <(^_^)> Roms []string diff --git a/pkg/worker/caged/libretro/frontend.go b/pkg/worker/caged/libretro/frontend.go index 91b92c1b..a8465488 100644 --- a/pkg/worker/caged/libretro/frontend.go +++ b/pkg/worker/caged/libretro/frontend.go @@ -158,6 +158,7 @@ func (f *Frontend) LoadCore(emu string) { scale = conf.Scale f.log.Debug().Msgf("Scale: x%v", scale) } + f.storage.SetNonBlocking(conf.NonBlockingSave) f.scale = scale f.nano.CoreLoad(meta) f.mu.Unlock() diff --git a/pkg/worker/caged/libretro/storage.go b/pkg/worker/caged/libretro/storage.go index e7c488a0..fc1a5a76 100644 --- a/pkg/worker/caged/libretro/storage.go +++ b/pkg/worker/caged/libretro/storage.go @@ -13,6 +13,7 @@ type ( GetSavePath() string GetSRAMPath() string SetMainSaveName(name string) + SetNonBlocking(v bool) Load(path string) ([]byte, error) Save(path string, data []byte) error } @@ -24,17 +25,26 @@ type ( // needed for Google Cloud save/restore which // doesn't support multiple files MainSave string + NonBlock bool } ZipStorage struct { Storage } ) -func (s *StateStorage) SetMainSaveName(name string) { s.MainSave = name } -func (s *StateStorage) GetSavePath() string { return filepath.Join(s.Path, s.MainSave+".dat") } -func (s *StateStorage) GetSRAMPath() string { return filepath.Join(s.Path, s.MainSave+".srm") } -func (s *StateStorage) Load(path string) ([]byte, error) { return os.ReadFile(path) } -func (s *StateStorage) Save(path string, dat []byte) error { return os.WriteFile(path, dat, 0644) } +func (s *StateStorage) SetMainSaveName(name string) { s.MainSave = name } +func (s *StateStorage) SetNonBlocking(v bool) { s.NonBlock = v } +func (s *StateStorage) GetSavePath() string { return filepath.Join(s.Path, s.MainSave+".dat") } +func (s *StateStorage) GetSRAMPath() string { return filepath.Join(s.Path, s.MainSave+".srm") } +func (s *StateStorage) Load(path string) ([]byte, error) { return os.ReadFile(path) } +func (s *StateStorage) Save(path string, dat []byte) error { + if s.NonBlock { + go func() { _ = os.WriteFile(path, dat, 0644) }() + return nil + } + + return os.WriteFile(path, dat, 0644) +} func (z *ZipStorage) GetSavePath() string { return z.Storage.GetSavePath() + zip.Ext } func (z *ZipStorage) GetSRAMPath() string { return z.Storage.GetSRAMPath() + zip.Ext }