from weakref import WeakSet
import bge

__all__ = ['MaterialManager']

class MaterialManager(object):
    Scenes = WeakSet()
    Registry = []

    def __init__(self):
        raise NotImplemented()

    @classmethod
    def RegisterEvents(cls):
        scenes = bge.logic.getSceneList()
        for scene in scenes:
            if scene not in cls.Scenes:
                scene.pre_draw_setup.append(cls.pre_draw_setup)
                scene.pre_draw.append(cls.pre_draw)
                scene.post_draw.append(cls.post_draw)
                cls.Scenes.add(scene)

    @classmethod
    def Register(cls, process):
        cls.Registry.append(process)
        return process

    @classmethod
    def RunDispatchers(cls, dispatch):
        for process in list(cls.Registry):
            if process.invalid:
                cls.Registry.remove(process)
            else:
                try: dispatch(process)
                except Exception as e:
                    cls.Registry.remove(process)
                    process.error(e)

    @classmethod
    def pre_draw_setup(cls):
        cls.RegisterEvents()
        cls.RunDispatchers(lambda process: process.pre_draw_setup_dispatch())

    @classmethod
    def pre_draw(cls):
        cls.RunDispatchers(lambda process: process.pre_draw_dispatch())

    @classmethod
    def post_draw(cls):
        cls.RunDispatchers(lambda process: process.post_draw_dispatch())
