Legend of the Gold Box... A game written for the LOWREZJAM 2018 game jam
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 satır
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)