Browse Source

Added resource loaders and Manager

master
Bryan Miller 6 years ago
parent
commit
b269e5ff5f
4 changed files with 213 additions and 0 deletions
  1. +2
    -0
      game/__init__.py
  2. +1
    -0
      game/gbe/__init__.py
  3. +158
    -0
      game/gbe/resource.py
  4. +52
    -0
      game/gbe/resourceLoaders.py

+ 2
- 0
game/__init__.py View File

@@ -31,6 +31,8 @@ def start():
t = gbe.time.Time()
t.reset()

resources = gbe.resource.Manager()

gbe.events.Events.listen("QUIT", _OnQuit)
gbe.events.Events.listen("KEYDOWN", _OnKeyEvent)
gbe.events.Events.listen("KEYUP", _OnKeyEvent)

+ 1
- 0
game/gbe/__init__.py View File

@@ -8,3 +8,4 @@ from . import time
from . import display
from . import events
from . import nodes
from . import resource

+ 158
- 0
game/gbe/resource.py View File

@@ -0,0 +1,158 @@


import os, sys
import json
import weakref
import pygame
from .resourceLoaders import *


class ResourceError(Exception):
pass

_GAME_PATH=calculate_real_path(os.path.dirname(sys.argv[0]))

_RESOURCES={}

def define_resource_type(rtype, sub_path, loader_fn):
global _RESOURCES, _GAME_PATH, join_path
if rtype in _RESOURCES:
raise ResourceError("Resource '{}' already defined.".format(rtype))
fullpath = join_path(_GAME_PATH, sub_path)
if not os.path.isdir(fullpath):
print("'{}' | '{}'".format(_GAME_PATH, fullpath))
raise ResourceError("'{}' is not a valid directory.".format(sub_path))
if not callable(loader_fn):
raise ResourceError("Expected a callable as the resource loader.")
_RESOURCES[rtype]={"r":[], "loader":loader_fn, "path":fullpath}


def configure(conf):
global _RESOURCES, join_path
if not isinstance(conf, dict):
raise TypeError("Expected a dictionary.")
for key in conf:
if key in _RESOURCES:
fullpath = join_path(_GAME_PATH, conf[key])
if not os.path.isdir(fullpath):
raise ResourceError("'{}' is not a valid directory.".format(conf[key]))
_RESOURCES[key]["path"] = fullpath
_RESOURCES[key]["r"] = [] # Completely drop old list.

class Manager:
def __init__(self):
pass

@property
def game_path(self):
global _GAME_PATH
return _GAME_PATH

@property
def resource_types(self):
global _RESOURCES
rtypes = []
for key in _RESOURCES:
rtypes.append(key)
return rtypes

def _getResourceDict(self, rtype, src):
global _RESOURCES
if rtype in _RESOURCES:
for r in _RESOURCES[rtype]["r"]:
if r["src"] == src:
return r
return None

def has(self, rtype, src):
return (self._getResourceDict(rtype, src) is not None)

def store(self, rtype, src):
global _RESOURCES
if type not in _RESOURCES:
raise ResourceError("Unknown resource type '{}'.".format(rtype))
if self._getResourceDict(rtype, src) == None:
_RESOURCES[rtype]["r"].append({"src":src, "instance":None, "locked":False})
return self

def remove(self, rtype, src):
global _RESOURCES
d = self._getResourceDict(rtype, src)
if d is None:
raise ResourceError("No '{}' resource '{}' stored.".format(rtype, src))
_RESOURCES[rtype]["r"].remove(d)
return self

def clear(self, rtype, src, ignore_lock):
d = self._getResourceDict(rtype, src)
if d is None:
raise ResourceError("No '{}' resource '{}' stored.".format(rtype, src))
if d["locked"] == False or ignore_lock == True:
d["instance"] = None
return self

def get(self, rtype, src):
global _RESOURCES
if rtype not in _RESOURCES:
raise ResourceError("Unknown resource type '{}'.".format(rtype))
d = self._getResourceDict(rtype, src)
if d is None:
raise ResourceError("No '{}' resource '{}' stored.".format(rtype, src))
if d["instance"] is None:
loader = _RESOURCES[rtype]["loader"]
filename = join_path(self.data_path, src)
try:
d["instance"] = loader(filename)
except Exception as e:
raise e
return weakref.ref(d["instance"])

def lock(self, rtype, src, lock=True):
d = self._getResourceDict(rtype, src)
if d is None:
raise ResourceError("No '{}' resource '{}' stored.".format(rtype, src))
d["locked"]=lock
return self

def is_locked(self, rtype, src):
d = self._getResourceDict(rtype, src)
if d is not None and d["src"] == src:
return d["locked"]
return False

def clear_resource_type(self, rtype, ignore_lock=False):
global _RESOURCES
if rtype in _RESOURCES:
for r in _RESOURCES[rtype]["r"]:
if r["locked"] == False or ignore_lock == True:
r["instance"] = None
return self

def clear_resources(self, ignore_lock=False):
global _RESOURCES
for key in _RESOURCES:
self.clear_resource_type(key, ignore_lock)
return self

def remove_resource_type(self, rtype):
global _RESOURCES
if rtype not in _RESOURCES:
raise ResourceError("Unknown resource type '{}'.".format(rtype))
_RESOURCES[rtype]["r"] = []
return self

def remove_resources(self):
global _RESOURCES
for key in _RESOURCES:
_RESOURCES[key]["r"] = []
return self


# ---------------------------------------------------------------
# Defining the built-in loaders located in resourceLoaders.py
# ---------------------------------------------------------------
define_resource_type("graphic", "graphics/", load_image)
define_resource_type("audio", "audio/", load_audio)
define_resource_type("json", "data/json/", load_JSON)



+ 52
- 0
game/gbe/resourceLoaders.py View File

@@ -0,0 +1,52 @@
import os
import pygame


class LoadError(Exception):
pass

def calculate_real_path(path):
path = os.path.expandvars(os.path.expanduser(path))
path = os.path.realpath(path)
path = os.path.abspath(path)
return os.path.normcase(os.path.normpath(path))
def join_path(lpath, rpath):
return os.path.normcase(os.path.normpath(os.path.join(lpath, rpath)))





def load_image(filename):
if not os.path.isfile(filename):
raise LoadError("Failed to load '{}'. Path missing or invalid.".format(filename))
with open(filename) as f:
try:
i = pygame.image.load(f, filename)
return i.convert_alpha()
except pygame.error as e:
raise LoadError("Pygame/SDL Exception: {}".format(e.message))


def load_audio(filename):
if not os.path.isfile(filename):
raise LoadError("Failed to load '{}'. Path missing or invalid.".format(filename))
try:
return pygame.mixer.Sound(filename)
except pygame.error as e:
raise LoadError("Pygame Exception: {}".format(e.message))



def load_JSON(filename):
if not os.path.isfile(filename):
raise LoaderError("File '{}' is missing or not a file.".format(filename))
data = None
try:
with open(filename) as f:
data = json.load(f)
return data
except Exception as e:
raise e



Loading…
Cancel
Save