Ensure color_pos is always -1 when the lights go out, so behaviour is always consistent
[tabakrolletjie.git] / tabakrolletjie / loader.py
1 """ Utilities for loading resource files. """
2
3 import json
4 import os
5
6 import pygame.image
7 import pygame.font
8 import pygame.display
9 import pygame.mixer
10
11 from .constants import DEBUG
12 from .transforms import NullTransform
13
14
15 class Loader(object):
16     """ Load data files from beneath a prefix. """
17
18     NULL_TRANSFORM = NullTransform()
19
20     def __init__(self, prefix):
21         self._prefix = prefix
22         self._cache = {}
23
24     def full_path(self, *parts):
25         path = "/".join(parts)
26         rel_path = os.path.join(*path.split("/"))
27         abs_path = os.path.join(self._prefix, rel_path)
28         if DEBUG:
29             print abs_path
30         return abs_path
31
32     def open_file(self, *parts):
33         return file(self.full_path(*parts), "rb")
34
35     def load_station(self, *parts):
36         with self.open_file("stations", *parts) as f:
37             return json.load(f)
38
39     def load_image(self, *parts, **kwargs):
40         """Return a pygame surface of the requested image."""
41         fn = self.full_path("images", *parts)
42         transform = kwargs.pop("transform", self.NULL_TRANSFORM)
43         img = self._cache.get((fn, transform), None)
44         if img is None:
45             img = pygame.image.load(fn)
46             # We assume pygame.display has been initialised
47             # Fix this if that changes
48             img.convert_alpha(pygame.display.get_surface())
49             img = transform.apply(img)
50             self._cache[(fn, transform)] = img
51         return img
52
53     def load_font(self, *parts, **kwargs):
54         """Return a pygame font of the given size"""
55         size = kwargs.get('size', 12)
56         fn = self.full_path("fonts", *parts)
57         font = pygame.font.Font(fn, size)
58         # Do we need to cache this?
59         return font
60
61     def load_sound(self, *parts):
62         """Return a pygame sound"""
63         fn = self.full_path("sounds", *parts)
64         sound = self._cache.get(fn, None)
65         if not sound:
66             sound = pygame.mixer.Sound(fn)
67             self._cache[fn] = sound
68         return sound
69
70
71 _DATA_PREFIX = os.path.abspath(
72     os.path.join(os.path.dirname(__file__), "..", "data"))
73
74 loader = Loader(_DATA_PREFIX)