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.

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)