changeset 33:d9b65cf72db4

Prettier resource loading module
author Stefano Rivera <stefano@rivera.za.net>
date Sun, 01 Sep 2013 16:44:04 +0200
parents 0e49648f8d74
children 2995723e8ccf
files data/__init__.py nagslang/data.py nagslang/resources.py nagslang/widgets/text.py
diffstat 3 files changed, 76 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- a/nagslang/data.py	Sun Sep 01 16:39:13 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-'''Simple data loader module.
-
-Loads data files from the "data" directory shipped with a game.
-'''
-
-import os
-
-import pygame
-
-data_py = os.path.abspath(os.path.dirname(__file__))
-data_dir = os.path.normpath(os.path.join(data_py, '..', 'data'))
-
-
-def filepath(filename):
-    '''Determine the path to a file in the data directory.
-    '''
-    # Allow using / as separator in filenames
-    filename = os.path.join(*filename.split('/'))
-    return os.path.join(data_dir, filename)
-
-
-def load(filename, mode='rb'):
-    '''Open a file in the data directory.
-
-    "mode" is passed as the second arg to open().
-    '''
-    return open(os.path.join(data_dir, filename), mode)
-
-
-IMAGES = {}
-MUTATED_IMAGES = {}
-
-
-def load_image(filename, mutators=()):
-    if filename not in IMAGES:
-        image = pygame.image.load(filepath(filename))
-        image = image.convert_alpha(pygame.display.get_surface())
-        IMAGES[filename] = image
-
-    key = (filename, mutators)
-    if key not in MUTATED_IMAGES:
-        image = IMAGES[filename]
-        for mutator in mutators:
-            image = mutator(image)
-        MUTATED_IMAGES[key] = image
-
-    return MUTATED_IMAGES[key]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nagslang/resources.py	Sun Sep 01 16:44:04 2013 +0200
@@ -0,0 +1,74 @@
+import os
+
+from pkg_resources import resource_filename
+import pygame
+
+
+class ResourceNotFound(Exception):
+    pass
+
+
+class Resources(object):
+    CONVERT_ALPHA = True
+
+    def __init__(self, resource_module, language=None):
+        self.resource_module = resource_module
+        self.lang_dialect = language
+        self.language = language.split('_', 1)[0] if language else None
+        self._cache = {}
+
+    def get_resource_path(self, *path_fragments):
+        for mod, full_path_fragments in self.lang_locations(path_fragments):
+            path = resource_filename(mod, os.path.join(*full_path_fragments))
+            if os.path.exists(path):
+                return path
+        raise ResourceNotFound(os.path.join(*path_fragments))
+
+    def lang_locations(self, path_fragments):
+        '''
+        For each resource module, yield:
+        * (<module>, (<lang>_<dialect>, <path>))
+        * (<module>, (<lang>, <path>))
+        * (<module>, (<path>, ))
+        '''
+        for module in (self.resource_module,):
+            if self.lang_dialect:
+                yield (module, (self.lang_dialect,) + path_fragments)
+            if self.language != self.lang_dialect:
+                yield (module, (self.language,) + path_fragments)
+            yield (module, path_fragments)
+
+    def get_image(self, *name_fragments, **kw):
+        transforms = kw.get('transforms', ())
+        basedir = kw.get('basedir', 'images')
+
+        path = (basedir,) + name_fragments
+
+        if path not in self._cache:
+            fn = self.get_resource_path(basedir, *path)
+            image = pygame.image.load(fn)
+            if self.CONVERT_ALPHA:
+                image = image.convert_alpha(pygame.display.get_surface())
+            self._cache[path] = image
+
+        key = (path, transforms)
+        if key not in self._cache:
+            image = self._cache[path]
+            for mutator in transforms:
+                image = mutator(image)
+            self._cache[key] = image
+
+        return self._cache[key]
+
+    def get_font(self, file_name, font_size):
+        basedir = 'fonts'
+        key = (basedir, file_name, font_size)
+
+        if key not in self._cache:
+            fn = self.get_resource_path(basedir, file_name)
+            self._cache[key] = pygame.font.Font(fn, font_size)
+
+        return self._cache[key]
+
+
+resources = Resources('data')
--- a/nagslang/widgets/text.py	Sun Sep 01 16:39:13 2013 +0200
+++ b/nagslang/widgets/text.py	Sun Sep 01 16:44:04 2013 +0200
@@ -1,14 +1,10 @@
-import pygame
-
 from nagslang.constants import FONT, FONT_SIZE
-from nagslang.data import filepath
 from nagslang.widgets.base import Widget
 from nagslang.utils import convert_colour
+from nagslang.resources import resources
 
 
 class TextWidget(Widget):
-    fonts = {}
-
     def __init__(self, pos, text, size=None, fontname=None, fontsize=None,
                  colour=None):
         super(TextWidget, self).__init__(pos, size)
@@ -21,11 +17,7 @@
         self.prepare()
 
     def prepare(self):
-        font = (self.fontname, self.fontsize)
-        if font not in TextWidget.fonts:
-            fn = filepath('fonts/' + self.fontname)
-            TextWidget.fonts[font] = pygame.font.Font(fn, self.fontsize)
-        self.font = TextWidget.fonts[font]
+        self.font = resources.get_font(self.fontname, self.fontsize)
         self.surface = self.font.render(self.text, True, self.colour)
         self.text_rect = self.surface.get_rect()
         if not self.size: