view mamba/habitats/levelmenu.py @ 411:5b090546a3c8

Turns out we *can* cache level objects safely.
author Jeremy Thurgood <firxen@gmail.com>
date Sat, 17 Sep 2011 14:43:51 +0200
parents 7f6a28456fda
children f1ba457772ae
line wrap: on
line source

"""Level menu."""

from pygame.locals import KEYDOWN

from mamba.constants import ESCAPE_KEYS
from mamba.engine import Habitat, NewHabitatEvent, HabitatSetupEvent
from mamba.gamestate import done_levels
from mamba.data import get_official_levels
from mamba.level import Level
from mamba.widgets.base import GridContainer
from mamba.widgets.levelbutton import LevelButton


OFFICIAL_LEVELS = []
LEVEL_CACHE = {}


class LevelMenu(Habitat):

    WIDTH = 5

    def __init__(self):
        super(LevelMenu, self).__init__()
        self.level_buttons = {}
        self.container.add(GridContainer(width=self.WIDTH))
        self.container.add_callback(KEYDOWN, self.keydown_event)

    def on_enter(self):
        super(LevelMenu, self).on_enter()
        self._setup_levels()

    def dispatch(self, ev):
        if HabitatSetupEvent.matches(ev):
            self._setup_levels(ev)
            return
        super(LevelMenu, self).dispatch(ev)

    def _setup_levels(self, ev=None):
        if ev is not None:
            self.setup_levels()
        else:
            HabitatSetupEvent.post()

    def setup_level(self, i, name):
        level = self.get_level(name)
        button = LevelButton((20 + 120 * (i % self.WIDTH),
                              20 + 120 * (i // self.WIDTH)),
                             level)
        button.add_callback('clicked', self.level_selected, name)
        button.done = level.unique_name() in done_levels
        self.container.add(button)
        self.level_buttons[name] = button

    def setup_levels(self):
        for i, name in enumerate(self.list_levels()):
            self.setup_level(i, name)

    def list_levels(self):
        raise NotImplementedError()

    def get_level(self, name):
        raise NotImplementedError()

    def level_selected(self, ev, widget, name):
        from mamba.habitats.level import LevelHabitat
        NewHabitatEvent.post(LevelHabitat(widget.level, self.go_menu))
        return True

    @classmethod
    def go_menu(cls):
        NewHabitatEvent.post(cls())

    def keydown_event(self, ev, widget):
        if ev.key in ESCAPE_KEYS:
            return self.return_to_mainmenu(ev, widget)

    def return_to_mainmenu(self, ev, widget):
        from mamba.habitats.mainmenu import MainMenu
        NewHabitatEvent.post(MainMenu())
        return True


class OfficialLevelMenu(LevelMenu):

    level_namespace = 'official'

    def list_levels(self):
        if not OFFICIAL_LEVELS:
            OFFICIAL_LEVELS.extend(get_official_levels())
        return OFFICIAL_LEVELS[:]

    def get_level(self, name):
        if name not in LEVEL_CACHE:
            LEVEL_CACHE[name] = Level(name, self.level_namespace)
        return LEVEL_CACHE[name]