Factor out flash light into utils.
[naja.git] / naja / scenes / load_save.py
index 485b032f61179e1e54a145e416c3e52be446761b..cf06865f97e0283c820ccd2c3f67daefd6955a39 100644 (file)
@@ -9,9 +9,11 @@ from datetime import datetime
 import pygame.locals as pgl
 
 from naja.constants import KEYS
-from naja.events import SceneChangeEvent, InvalidateTheWorld
+from naja.events import SceneChangeEvent, InvalidateTheWorld, LoadGameEvent
+from naja.gamestate import GameState
 from naja.options import options
 from naja.scenes.scene import Scene
+from naja.sound import sound
 from naja.widgets.save_slot import SaveSlotWidget
 from naja.widgets.selector import SelectorWidget
 
@@ -26,9 +28,42 @@ def ensure_save_path_exists():
         os.makedirs(location)
 
 
-class SaveGameScene(Scene):
+class SaveGameSlot(object):
+    def __init__(self, slot_num):
+        self.slot_num = slot_num
+
+    def save_path(self):
+        return save_path('slot_%s.json' % (self.slot_num,))
+
+    def get_game_data(self):
+        try:
+            with open(self.save_path(), 'r') as save_file:
+                return json.load(save_file)
+        except IOError:
+            return None
+        except Exception as e:
+            print "Error reading savegame in slot %s: %s" % (self.slot_num, e)
+            return None
+
+    def save(self, state):
+        ensure_save_path_exists()
+        save_data = {
+            'timestamp': datetime.now().ctime(),
+            'data': state.gameboard.export(),
+        }
+        with open(self.save_path(), 'w') as save_file:
+            json.dump(save_data, save_file)
+
+    def load(self):
+        game_data = self.get_game_data()
+        if game_data is None:
+            return
+        return GameState.load(game_data['data'])
+
+
+class LoadSaveGameBase(Scene):
     def __init__(self, state):
-        super(SaveGameScene, self).__init__(state)
+        super(LoadSaveGameBase, self).__init__(state)
         selector = SelectorWidget()
         self.add(selector)
         self.slots = {}
@@ -38,42 +73,56 @@ class SaveGameScene(Scene):
             self.slots[slot_num] = slot
             selector.add(slot)
 
-    def save_path(self, slot_num):
-        return save_path('slot_%s.json' % (slot_num,))
-
-    def get_game_data(self, slot_num):
-        try:
-            with open(self.save_path(slot_num), 'r') as save_file:
-                return json.load(save_file)
-        except IOError:
-            return None
-        except Exception as e:
-            print "Error reading savegame in slot %s: %s" % (slot_num, e)
-            return None
-
     def make_slot_widget(self, slot_num):
-        game_data = self.get_game_data(slot_num)
-        y_offset = 74 * slot_num
+        game_data = SaveGameSlot(slot_num).get_game_data()
+        y_offset = 74 * slot_num + 8
         slot = SaveSlotWidget((100, y_offset), slot_num, game_data)
-        slot.add_callback('click', lambda event: self.save_game(slot_num))
+        slot.add_callback('click', lambda event: self.perform_action(slot_num))
         return slot
 
-    def save_game(self, slot_num):
-        save_data = {
-            'timestamp': datetime.now().ctime(),
-            'data': self.state.gameboard.export(),
-        }
-        try:
-            ensure_save_path_exists()
-            with open(self.save_path(slot_num), 'w') as save_file:
-                json.dump(save_data, save_file)
-        except Exception as e:
-            print "Error saving game in slot %s: %s" % (slot_num, e)
-        self.slots[slot_num].game_data = self.get_game_data(slot_num)
-        InvalidateTheWorld.post()
-
     def handle_scene_event(self, ev):
         if ev.type == pgl.KEYDOWN and ev.key in KEYS.QUIT:
             from naja.scenes.menu import MenuScene
             SceneChangeEvent.post(MenuScene)
             return
+
+    def fail(self):
+        sound.play_sound('error.ogg')
+        InvalidateTheWorld.post()
+
+    def succeed(self):
+        raise NotImplementedError("Success not implemented.")
+
+    def perform_action(self, slot_num):
+        raise NotImplementedError("Nothing to see here.")
+
+
+class SaveGameScene(LoadSaveGameBase):
+    def perform_action(self, slot_num):
+        try:
+            SaveGameSlot(slot_num).save(self.state)
+        except Exception as e:
+            print "Error saving game in slot %s: %s" % (slot_num, e)
+            self.fail()
+        else:
+            self.succeed()
+
+    def succeed(self):
+        from naja.scenes.menu import MenuScene
+        sound.play_sound('chirp.ogg', volume=0.5)
+        SceneChangeEvent.post(MenuScene)
+
+
+class LoadGameScene(LoadSaveGameBase):
+    def perform_action(self, slot_num):
+        state = SaveGameSlot(slot_num).load()
+        if state is not None:
+            LoadGameEvent.post(state)
+            self.succeed()
+        else:
+            self.fail()
+
+    def succeed(self):
+        from naja.scenes.game import GameScene
+        sound.play_sound('chirp.ogg', volume=0.5)
+        SceneChangeEvent.post(GameScene)