1
0
mirror of https://github.com/gryf/fs-uae-wrapper.git synced 2025-12-19 04:20:23 +01:00

Added savestate wrapper module

This commit is contained in:
2017-01-07 09:31:59 +01:00
parent ae6e00ea1c
commit c5ce27e637
3 changed files with 178 additions and 10 deletions

View File

@@ -106,6 +106,7 @@ Currently, three wrapper modules are available:
- plain - plain
- cd32 - cd32
- archive - archive
- savestate
plain plain
----- -----
@@ -139,7 +140,6 @@ Let's see some sample config for a game, which is saved as
``ChaosEngine.fs-uae``: ``ChaosEngine.fs-uae``:
.. code:: ini .. code:: ini
:number-lines:
[config] [config]
wrapper = cd32 wrapper = cd32
@@ -165,8 +165,7 @@ Next, the invocation of the wrapper would be as follows:
Now, there several thing will happen: Now, there several thing will happen:
- Config file will be read, and wrapper module will be find (because we already - Config file will be read, and wrapper module will be found
put it on line 2)
- New temporary directory will be created - New temporary directory will be created
- Archive with game assists will be extracted in that directory - Archive with game assists will be extracted in that directory
- Configuration file will be copied into that directory, and renamed to - Configuration file will be copied into that directory, and renamed to
@@ -204,7 +203,6 @@ Options used:
Example configuration: Example configuration:
.. code:: ini .. code:: ini
:number-lines:
[config] [config]
wrapper = archive wrapper = archive
@@ -215,6 +213,13 @@ Example configuration:
wrapper_save_state = 1 wrapper_save_state = 1
... ...
This module is quite useful in two use cases. First is a usual work with
Workbench, where there is a need to keep changes of filesystem. Second is the
opposite - if there is a need to test some software, but not necessary keep it
in a Workbench, than it will act as a temporary copy of the system, so that
next time fs-uae will be run, there will be no files of tested software
cluttering around.
And execution is as usual: And execution is as usual:
.. code:: shell-session .. code:: shell-session
@@ -234,12 +239,53 @@ This module will do several steps (similar as with ``cd32`` wrapper):
- optionally create new archive under the same name as the original one and - optionally create new archive under the same name as the original one and
replace it with original one. replace it with original one.
This module is quite useful in two use cases. First is a usual work with savestate
Workbench, where there is a need to keep changes of filesystem. Second is the ---------
opposite - if there is a need to test some software, but not necessary keep it
in a Workbench, than it will act as a temporary copy of the system, so that Options used:
next time fs-uae will be run, there will be no files of tested software
cluttering around. * ``wrapper`` (required) with ``archive`` as an value
* ``wrapper_archiver`` (conditionally required) archiver to use for storage
save state
* ``wrapper_gui_msg`` (optional) if set to "1", will display a graphical
message during extracting files
* ``wrapper_save_state`` (optional) if set to "1", will archive save state
directory, defined as ``$CONFIG/[save-state-dir-name]`` using provided
``wrapper_archiver`` archiver. If this option is enabled,
``wrapper_archiver`` will be required.
This module is primarily used to run emulator with read only media attached
(like images of floppies or uncompressed CD-ROMs) and its purpose is to
preserve save state which will be created as an archive alongside with original
configuration file in selected archive format.
Example configuration:
.. code:: ini
:number-lines:
[config]
wrapper = savestate
wrapper_archiver = 7z
wrapper_gui_msg = 1
wrapper_save_state = 1
...
And execution is as usual:
.. code:: shell-session
$ fs-uae-wrapper Sanity-Arte.fs-uae
The steps would be as follows:
- create temporary directory
- extract save state (if ``wrapper_save_state`` is set to ``1`` and archive
with save exists)
- copy configuration under name ``Config.fs-uae``
- run the fs-uae emulator
- optionally create archive with save state (if save state directory place is
*not* a global one)
License License
======= =======

View File

@@ -0,0 +1,50 @@
"""
Wrapper module with preserved save state in archive file.
"""
from fs_uae_wrapper import base
class SaveState(base.Base):
"""
Preserve save state.
"""
def run(self):
"""
Main function which accepts configuration file for FS-UAE
It will do as follows:
- set needed full path for asset files
- copy configuration
- optionally extract save state archive
- run the emulation
- optionally make archive save state
"""
if not super(SaveState, self).run():
return False
self._load_save()
if not self._copy_conf():
return False
kick_opts = self._kickstart_option()
if kick_opts:
self.fsuae_options.update(kick_opts)
if not self._run_emulator(self.fsuae_options.list()):
return False
if self._get_saves_dir():
if not self._save_save():
return False
return True
def run(config_file, fsuae_options, configuration):
"""Run fs-uae with provided config file and options"""
runner = SaveState(config_file, fsuae_options, configuration)
try:
return runner.run()
finally:
runner.clean()

72
tests/test_savestate.py Normal file
View File

@@ -0,0 +1,72 @@
import os
import shutil
from tempfile import mkdtemp
from unittest import TestCase
try:
from unittest import mock
except ImportError:
import mock
from fs_uae_wrapper import savestate
from fs_uae_wrapper import utils
class TestArchive(TestCase):
def setUp(self):
self.dirname = mkdtemp()
self.curdir = os.path.abspath(os.curdir)
os.chdir(self.dirname)
def tearDown(self):
os.chdir(self.curdir)
try:
shutil.rmtree(self.dirname)
except OSError:
pass
@mock.patch('tempfile.mkdtemp')
@mock.patch('fs_uae_wrapper.path.which')
@mock.patch('fs_uae_wrapper.base.Base._save_save')
@mock.patch('fs_uae_wrapper.base.Base._get_saves_dir')
@mock.patch('fs_uae_wrapper.base.Base._run_emulator')
@mock.patch('fs_uae_wrapper.base.Base._kickstart_option')
@mock.patch('fs_uae_wrapper.base.Base._copy_conf')
@mock.patch('fs_uae_wrapper.base.Base._load_save')
def test_run(self, load_save, copy_conf, kick_option, run_emulator,
get_save_dir, save_state, which, mkdtemp):
copy_conf.return_value = False
kick_option.return_value = False
run_emulator.return_value = False
get_save_dir.return_value = False
save_state.return_value = False
which.return_value = 'rar'
arch = savestate.SaveState('Config.fs-uae', utils.CmdOption(), {})
self.assertFalse(arch.run())
arch.all_options = {'wrapper': 'archive',
'wrapper_save_state': '1',
'wrapper_archiver': 'rar'}
self.assertFalse(arch.run())
self.assertFalse(arch.run())
copy_conf.return_value = True
self.assertFalse(arch.run())
kick_option.return_value = {'foo': 'bar'}
self.assertFalse(arch.run())
self.assertDictEqual(arch.fsuae_options, {'foo': 'bar'})
run_emulator.return_value = True
self.assertTrue(arch.run())
get_save_dir.return_value = True
self.assertFalse(arch.run())
save_state.return_value = True
self.assertTrue(arch.run())