changeset 411:03d5cb669298

Add config file and command line parameters.
author Jeremy Thurgood <firxen@gmail.com>
date Sat, 21 Nov 2009 11:18:08 +0000
parents e83ec14163f2
children 1e24eedbf40f
files config.ini gamelib/config.py gamelib/engine.py gamelib/main.py gamelib/sound.py
diffstat 5 files changed, 69 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config.ini	Sat Nov 21 11:18:08 2009 +0000
@@ -0,0 +1,2 @@
+[Options]
+sound = on
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gamelib/config.py	Sat Nov 21 11:18:08 2009 +0000
@@ -0,0 +1,54 @@
+# level.py
+
+from ConfigParser import RawConfigParser
+from optparse import OptionParser
+
+class Config(object):
+    """Container for various global configuration knobs and levers."""
+
+    valid_options = {
+        'sound': {'type': 'boolean', 'default': 'true'},
+        'level_name': {'type': 'string', 'default': 'two_weeks'},
+        }
+
+    config_filename = 'config.ini'
+
+    def configure(self, params=None):
+        self._config = RawConfigParser(dict(
+                [(k, v['default']) for k, v in self.valid_options.items() if 'default' in v]
+            ))
+        self._config.add_section('Options')
+        self._set_up_params(params)
+        self._config.read(self.config_filename)
+        self._process_params()
+
+    def _set_up_params(self, params):
+        parser = OptionParser()
+        parser.add_option("-c", "--config", metavar="FILE", dest="config_filename",
+                          help="read configuration from FILE")
+        parser.add_option("-l", "--level", metavar="LEVEL", dest="level_name",
+                          help="select level LEVEL")
+        parser.add_option("--sound", action="store_const", const="on", dest="sound",
+                          help="enable sound")
+        parser.add_option("--no-sound", action="store_const", const="off", dest="sound",
+                          help="disable sound")
+        (self._opts, _) = parser.parse_args(params or [])
+        self.config_filename = self._opts.config_filename or self.config_filename
+
+    def _process_params(self):
+        for name in self.valid_options:
+            opt = getattr(self._opts, name)
+            if opt is not None:
+                self._config.set('Options', name, opt)
+
+    def __getattr__(self, name):
+        if name not in self.valid_options:
+            raise AttributeError(name)
+        get_methods = {
+            'string': lambda n: self._config.get('Options', n),
+            'boolean': lambda n: self._config.getboolean('Options', n),
+            }
+        return get_methods[self.valid_options[name].get('type', 'string')](name)
+
+# Here's a global variable. Don't try this at home, kids!
+config = Config()
--- a/gamelib/engine.py	Sat Nov 21 11:04:16 2009 +0000
+++ b/gamelib/engine.py	Sat Nov 21 11:18:08 2009 +0000
@@ -148,8 +148,6 @@
             return NightState(self.game)
         elif e.type is KEYDOWN and e.key == K_ESCAPE:
             self.dialog = check_exit()
-        elif e.type is ANIM_ID:
-            self.game.gameboard.run_animations()
         elif e.type is KEYDOWN and e.key == K_n:
             return pygame.event.post(START_NIGHT)
         elif events_equal(e, GO_MAIN_MENU):
@@ -212,8 +210,6 @@
             pygame.time.set_timer(MOVE_FOX_ID, 4*self.cycle_time)
         elif e.type is KEYDOWN and e.key == K_ESCAPE:
             self.dialog = check_exit()
-        elif e.type is ANIM_ID:
-            self.game.gameboard.run_animations()
         elif e.type is MOVE_FOX_ID:
             # ensure no timers trigger while we're running
             pygame.time.set_timer(ANIM_ID, 0)
--- a/gamelib/main.py	Sat Nov 21 11:04:16 2009 +0000
+++ b/gamelib/main.py	Sat Nov 21 11:18:08 2009 +0000
@@ -6,6 +6,8 @@
 package.
 '''
 
+import sys
+
 import pygame
 from pgu import gui
 from pygame.locals import SWSURFACE
@@ -13,8 +15,8 @@
 #from engine import Engine, MainMenuState
 from sound import init_sound
 import constants
+from config import config
 import data
-import sys
 
 def create_main_app(screen):
     """Create an app with a background widget."""
@@ -26,6 +28,7 @@
 
 def main():
     """Main script."""
+    config.configure(sys.argv[1:])
     init_sound()
     screen = pygame.display.set_mode(constants.SCREEN, SWSURFACE)
     pygame.display.set_icon(pygame.image.load(
@@ -34,12 +37,7 @@
 
     from engine import Engine, MainMenuState
 
-    if len(sys.argv) > 1:
-        level_name = sys.argv[1]
-    else:
-        level_name = 'two_weeks'
-
-    engine = Engine(main_app, level_name)
+    engine = Engine(main_app, config.level_name)
     try:
         engine.run(MainMenuState(engine), screen)
     except KeyboardInterrupt:
--- a/gamelib/sound.py	Sat Nov 21 11:04:16 2009 +0000
+++ b/gamelib/sound.py	Sat Nov 21 11:18:08 2009 +0000
@@ -1,8 +1,10 @@
 import os
-import pygame
 import sys
 
+import pygame
+
 import data
+from config import config
 import constants
 
 SOUND_INITIALIZED = False
@@ -10,6 +12,8 @@
 def init_sound():
     """initialize the sound system"""
     global SOUND_INITIALIZED
+    if not config.sound:
+        return
     try:
         pygame.mixer.init(constants.FREQ, constants.BITSIZE, constants.CHANNELS, constants.BUFFER)
         SOUND_INITIALIZED = True
@@ -20,7 +24,7 @@
 
 def play_sound(filename):
     """plays the sound with the given filename from the data sounds directory"""
-    if not SOUND_INITIALIZED:
+    if not (SOUND_INITIALIZED and config.sound):
         return
     file_path = data.filepath("sounds", filename)
     sound = SOUND_CACHE.get(file_path, None)
@@ -35,7 +39,7 @@
 def stop_background_music():
     """stops any playing background music"""
     global CURRENT_MUSIC_FILE
-    if not SOUND_INITIALIZED:
+    if not (SOUND_INITIALIZED and config.sound):
         return
     CURRENT_MUSIC_FILE = None
     # TODO: fadeout in a background thread
@@ -44,7 +48,7 @@
 def background_music(filename):
     """plays the background music with the given filename from the data sounds directory"""
     global CURRENT_MUSIC_FILE
-    if not SOUND_INITIALIZED:
+    if not (SOUND_INITIALIZED and config.sound):
         return
     file_path = data.filepath("sounds", filename)
     if CURRENT_MUSIC_FILE == file_path: