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.

204 lines
6.8KB

  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, saver_fn=None):
  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, "saver":saver_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 load(self, rtype, src, params={}):
  109. global _RESOURCES
  110. if rtype not in _RESOURCES:
  111. raise ResourceError("Unknown resource type '{}'.".format(rtype))
  112. loader = _RESOURCES[rtype]["loader"]
  113. filename = join_path(_RESOURCES[rtype]["path"], src)
  114. try:
  115. return loader(filename, params)
  116. except Exception as e:
  117. raise e
  118. def save(self, rtype, dst, data):
  119. global _RESOURCES
  120. if rtype not in _RESOURCES:
  121. raise ResourceError("Unknown resource type '{}'.".format(rtype))
  122. if _RESOURCES[rtype]["saver"] is None:
  123. raise ResourceError("Resource type '{}' has no defined saving function.".format(rtype))
  124. saver = _RESOURCES[rtype]["saver"]
  125. filename = join_path(_RESOURCES[rtype]["path"], dst)
  126. try:
  127. saver(filename, data)
  128. except Exception as e:
  129. raise e
  130. def lock(self, rtype, src, lock=True):
  131. d = self._getResourceDict(rtype, src)
  132. if d is None:
  133. raise ResourceError("No '{}' resource '{}' stored.".format(rtype, src))
  134. d["locked"]=lock
  135. return self
  136. def is_locked(self, rtype, src):
  137. d = self._getResourceDict(rtype, src)
  138. if d is not None and d["src"] == src:
  139. return d["locked"]
  140. return False
  141. def clear_resource_type(self, rtype, ignore_lock=False):
  142. global _RESOURCES
  143. if rtype in _RESOURCES:
  144. for r in _RESOURCES[rtype]["r"]:
  145. if r["locked"] == False or ignore_lock == True:
  146. r["instance"] = None
  147. return self
  148. def clear_resources(self, ignore_lock=False):
  149. global _RESOURCES
  150. for key in _RESOURCES:
  151. self.clear_resource_type(key, ignore_lock)
  152. return self
  153. def remove_resource_type(self, rtype):
  154. global _RESOURCES
  155. if rtype not in _RESOURCES:
  156. raise ResourceError("Unknown resource type '{}'.".format(rtype))
  157. _RESOURCES[rtype]["r"] = []
  158. return self
  159. def remove_resources(self):
  160. global _RESOURCES
  161. for key in _RESOURCES:
  162. _RESOURCES[key]["r"] = []
  163. return self
  164. # ---------------------------------------------------------------
  165. # Defining the built-in loaders located in resourceLoaders.py
  166. # ---------------------------------------------------------------
  167. define_resource_type("graphic", "graphics/", load_image)
  168. define_resource_type("audio", "audio/", load_audio)
  169. define_resource_type("json", "data/json/", load_JSON)
  170. define_resource_type("maps", "data/maps/", load_JSON)
  171. define_resource_type("user_maps", "maps/", load_JSON, save_JSON)
  172. define_resource_type("font", "fonts/", load_font)