Legend of the Gold Box... A game written for the LOWREZJAM 2018 game jam
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

177 lines
5.7KB

  1. import os, sys
  2. import logging
  3. import weakref
  4. import pygame
  5. from .resourceLoaders import *
  6. class ResourceError(Exception):
  7. pass
  8. _GAME_PATH=calculate_real_path(os.path.dirname(sys.argv[0]))
  9. def _BuildLogger():
  10. logger = logging.getLogger(__name__)
  11. logger.setLevel(logging.DEBUG)
  12. log_format = logging.Formatter("[%(levelname)s : %(asctime)s] %(message)s")
  13. log_handler = logging.FileHandler(join_path(_GAME_PATH, "logs/gbe.log"))
  14. log_handler.setFormatter(log_format)
  15. logger.addHandler(log_handler)
  16. return logger
  17. _l = _BuildLogger()
  18. _RESOURCES={}
  19. def define_resource_type(rtype, sub_path, loader_fn):
  20. global _RESOURCES, _GAME_PATH, join_path
  21. if rtype in _RESOURCES:
  22. _l.error("Resource '{}' already defined.".format(rtype))
  23. return
  24. fullpath = join_path(_GAME_PATH, sub_path)
  25. if not os.path.isdir(fullpath):
  26. _l.warning("'{}' is not a valid directory.".format(sub_path))
  27. if not callable(loader_fn):
  28. raise ResourceError("Expected a callable as the resource loader.")
  29. _RESOURCES[rtype]={"r":[], "loader":loader_fn, "path":fullpath}
  30. _l.info("Added resource type '{}' with search path '{}'.".format(rtype, sub_path))
  31. def configure(conf):
  32. global _RESOURCES, join_path
  33. if not isinstance(conf, dict):
  34. raise TypeError("Expected a dictionary.")
  35. for key in conf:
  36. if key in _RESOURCES:
  37. fullpath = join_path(_GAME_PATH, conf[key])
  38. if not os.path.isdir(fullpath):
  39. _l.warning("'{}' is not a valid directory.".format(conf[key]))
  40. _RESOURCES[key]["path"] = fullpath
  41. _RESOURCES[key]["r"] = [] # Completely drop old list.
  42. class ResourceManager:
  43. def __init__(self):
  44. pass
  45. @property
  46. def game_path(self):
  47. global _GAME_PATH
  48. return _GAME_PATH
  49. @property
  50. def resource_types(self):
  51. global _RESOURCES
  52. rtypes = []
  53. for key in _RESOURCES:
  54. rtypes.append(key)
  55. return rtypes
  56. def _getResourceDict(self, rtype, src):
  57. global _RESOURCES
  58. if rtype in _RESOURCES:
  59. for r in _RESOURCES[rtype]["r"]:
  60. if r["src"] == src:
  61. return r
  62. return None
  63. def is_valid(self, rtype, src):
  64. global _RESOURCES
  65. if rtype in _RESOURCES:
  66. return file_exists(join_path(_RESOURCES[rtype]["path"], src))
  67. return false
  68. def has(self, rtype, src):
  69. return (self._getResourceDict(rtype, src) is not None)
  70. def store(self, rtype, src):
  71. global _RESOURCES
  72. if rtype not in _RESOURCES:
  73. raise ResourceError("Unknown resource type '{}'.".format(rtype))
  74. if self._getResourceDict(rtype, src) == None:
  75. _RESOURCES[rtype]["r"].append({"src":src, "instance":None, "locked":False})
  76. return self
  77. def remove(self, rtype, src):
  78. global _RESOURCES
  79. d = self._getResourceDict(rtype, src)
  80. if d is None:
  81. raise ResourceError("No '{}' resource '{}' stored.".format(rtype, src))
  82. _RESOURCES[rtype]["r"].remove(d)
  83. return self
  84. def clear(self, rtype, src, ignore_lock=False):
  85. d = self._getResourceDict(rtype, src)
  86. if d is None:
  87. raise ResourceError("No '{}' resource '{}' stored.".format(rtype, src))
  88. if d["locked"] == False or ignore_lock == True:
  89. d["instance"] = None
  90. return self
  91. def get(self, rtype, src, params={}):
  92. global _RESOURCES
  93. if rtype not in _RESOURCES:
  94. raise ResourceError("Unknown resource type '{}'.".format(rtype))
  95. d = self._getResourceDict(rtype, src)
  96. if d is None:
  97. raise ResourceError("No '{}' resource '{}' stored.".format(rtype, src))
  98. if d["instance"] is None:
  99. loader = _RESOURCES[rtype]["loader"]
  100. filename = join_path(_RESOURCES[rtype]["path"], src)
  101. try:
  102. d["instance"] = loader(filename, params)
  103. except Exception as e:
  104. raise e
  105. _l.error("{}".format(e))
  106. return None
  107. return weakref.ref(d["instance"])
  108. def lock(self, rtype, src, lock=True):
  109. d = self._getResourceDict(rtype, src)
  110. if d is None:
  111. raise ResourceError("No '{}' resource '{}' stored.".format(rtype, src))
  112. d["locked"]=lock
  113. return self
  114. def is_locked(self, rtype, src):
  115. d = self._getResourceDict(rtype, src)
  116. if d is not None and d["src"] == src:
  117. return d["locked"]
  118. return False
  119. def clear_resource_type(self, rtype, ignore_lock=False):
  120. global _RESOURCES
  121. if rtype in _RESOURCES:
  122. for r in _RESOURCES[rtype]["r"]:
  123. if r["locked"] == False or ignore_lock == True:
  124. r["instance"] = None
  125. return self
  126. def clear_resources(self, ignore_lock=False):
  127. global _RESOURCES
  128. for key in _RESOURCES:
  129. self.clear_resource_type(key, ignore_lock)
  130. return self
  131. def remove_resource_type(self, rtype):
  132. global _RESOURCES
  133. if rtype not in _RESOURCES:
  134. raise ResourceError("Unknown resource type '{}'.".format(rtype))
  135. _RESOURCES[rtype]["r"] = []
  136. return self
  137. def remove_resources(self):
  138. global _RESOURCES
  139. for key in _RESOURCES:
  140. _RESOURCES[key]["r"] = []
  141. return self
  142. # ---------------------------------------------------------------
  143. # Defining the built-in loaders located in resourceLoaders.py
  144. # ---------------------------------------------------------------
  145. define_resource_type("graphic", "graphics/", load_image)
  146. define_resource_type("audio", "audio/", load_audio)
  147. define_resource_type("json", "data/json/", load_JSON)
  148. define_resource_type("font", "fonts/", load_font)