Legend of the Gold Box... A game written for the LOWREZJAM 2018 game jam
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

177 行
5.7KB

  1. import os, sys
  2. import logging
  3. import json
  4. import weakref
  5. import pygame
  6. from .resourceLoaders import *
  7. class ResourceError(Exception):
  8. pass
  9. _GAME_PATH=calculate_real_path(os.path.dirname(sys.argv[0]))
  10. def _BuildLogger():
  11. logger = logging.getLogger(__name__)
  12. logger.setLevel(logging.DEBUG)
  13. log_format = logging.Formatter("[%(levelname)s : %(asctime)s] %(message)s")
  14. log_handler = logging.FileHandler(join_path(_GAME_PATH, "logs/gbe.log"))
  15. log_handler.setFormatter(log_format)
  16. logger.addHandler(log_handler)
  17. return logger
  18. _l = _BuildLogger()
  19. _RESOURCES={}
  20. def define_resource_type(rtype, sub_path, loader_fn):
  21. global _RESOURCES, _GAME_PATH, join_path
  22. if rtype in _RESOURCES:
  23. _l.error("Resource '{}' already defined.".format(rtype))
  24. return
  25. fullpath = join_path(_GAME_PATH, sub_path)
  26. if not os.path.isdir(fullpath):
  27. _l.warning("'{}' is not a valid directory.".format(sub_path))
  28. if not callable(loader_fn):
  29. raise ResourceError("Expected a callable as the resource loader.")
  30. _RESOURCES[rtype]={"r":[], "loader":loader_fn, "path":fullpath}
  31. _l.info("Added resource type '{}' with search path '{}'.".format(rtype, sub_path))
  32. def configure(conf):
  33. global _RESOURCES, join_path
  34. if not isinstance(conf, dict):
  35. raise TypeError("Expected a dictionary.")
  36. for key in conf:
  37. if key in _RESOURCES:
  38. fullpath = join_path(_GAME_PATH, conf[key])
  39. if not os.path.isdir(fullpath):
  40. _l.warning("'{}' is not a valid directory.".format(conf[key]))
  41. _RESOURCES[key]["path"] = fullpath
  42. _RESOURCES[key]["r"] = [] # Completely drop old list.
  43. class ResourceManager:
  44. def __init__(self):
  45. pass
  46. @property
  47. def game_path(self):
  48. global _GAME_PATH
  49. return _GAME_PATH
  50. @property
  51. def resource_types(self):
  52. global _RESOURCES
  53. rtypes = []
  54. for key in _RESOURCES:
  55. rtypes.append(key)
  56. return rtypes
  57. def _getResourceDict(self, rtype, src):
  58. global _RESOURCES
  59. if rtype in _RESOURCES:
  60. for r in _RESOURCES[rtype]["r"]:
  61. if r["src"] == src:
  62. return r
  63. return None
  64. def is_valid(self, rtype, src):
  65. global _RESOURCES
  66. if rtype in _RESOURCES:
  67. return file_exists(join_path(_RESOURCES[rtype]["path"], src))
  68. return false
  69. def has(self, rtype, src):
  70. return (self._getResourceDict(rtype, src) is not None)
  71. def store(self, rtype, src):
  72. global _RESOURCES
  73. if rtype not in _RESOURCES:
  74. raise ResourceError("Unknown resource type '{}'.".format(rtype))
  75. if self._getResourceDict(rtype, src) == None:
  76. _RESOURCES[rtype]["r"].append({"src":src, "instance":None, "locked":False})
  77. return self
  78. def remove(self, rtype, src):
  79. global _RESOURCES
  80. d = self._getResourceDict(rtype, src)
  81. if d is None:
  82. raise ResourceError("No '{}' resource '{}' stored.".format(rtype, src))
  83. _RESOURCES[rtype]["r"].remove(d)
  84. return self
  85. def clear(self, rtype, src, ignore_lock=False):
  86. d = self._getResourceDict(rtype, src)
  87. if d is None:
  88. raise ResourceError("No '{}' resource '{}' stored.".format(rtype, src))
  89. if d["locked"] == False or ignore_lock == True:
  90. d["instance"] = None
  91. return self
  92. def get(self, rtype, src, params={}):
  93. global _RESOURCES
  94. if rtype not in _RESOURCES:
  95. raise ResourceError("Unknown resource type '{}'.".format(rtype))
  96. d = self._getResourceDict(rtype, src)
  97. if d is None:
  98. raise ResourceError("No '{}' resource '{}' stored.".format(rtype, src))
  99. if d["instance"] is None:
  100. loader = _RESOURCES[rtype]["loader"]
  101. filename = join_path(_RESOURCES[rtype]["path"], src)
  102. try:
  103. d["instance"] = loader(filename, params)
  104. except Exception as 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)