GameCore.lua 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. local src = script.Parent
  2. local compileSubmodules = require(src:WaitForChild("compileSubmodules"))
  3. local callOnAll = require(src:WaitForChild("callOnAll"))
  4. local GameCore = {}
  5. local errors = {
  6. invalidArgument = "Invalid argument: [%s]. expected: [%s].",
  7. alreadyDefined = "Module [%s] has already been defined!"
  8. }
  9. local function instanceModule(class, core)
  10. return setmetatable({
  11. core = core
  12. },{__index = class, __tostring = getmetatable(class).__tostring})
  13. end
  14. function GameCore.new()
  15. local core = setmetatable({
  16. _moduleClasses = {},
  17. _modules = {},
  18. _debugprints = false,
  19. }, {__index = GameCore})
  20. return core
  21. end
  22. function GameCore:registerModule(moduleClass, script)
  23. local moduleClassType = typeof(moduleClass)
  24. if moduleClassType == "table" then
  25. assert(moduleClass.__gamemodule,
  26. errors.invalidArgument:format(
  27. tostring(moduleClass),
  28. "GameModule class"
  29. ),
  30. 2
  31. )
  32. local className = moduleClass.name
  33. assert(self._moduleClasses[className] == nil, errors.alreadyDefined:format(className))
  34. self._moduleClasses[className] = moduleClass
  35. elseif moduleClassType == "Instance" then
  36. assert(moduleClass:IsA("ModuleScript"),
  37. errors.invalidArgument:format(
  38. moduleClass:GetFullName(),
  39. "ModuleScript"
  40. ),
  41. 2
  42. )
  43. local requiredModuleClass = require(moduleClass)
  44. self:registerModule(requiredModuleClass) -- register the class
  45. else
  46. error(errors.invalidArgument:format(
  47. tostring(moduleClass),
  48. "GameModule class or ModuleScipt of GameModule class"),
  49. 2
  50. )
  51. end
  52. end
  53. function GameCore:registerChildrenAsModules(root)
  54. assert(root and typeof(root) == "Instance" and root:IsA("Folder"),
  55. errors.invalidArgument:format(tostring(root), "Folder")
  56. )
  57. for instance, module in pairs(compileSubmodules(root,true)) do
  58. if self._debugprints then
  59. print("Loading module:", instance)
  60. end
  61. self:registerModule(module)
  62. end
  63. end
  64. function GameCore:instanceAllModules()
  65. -- instance modules
  66. for name, class in pairs(self._moduleClasses) do
  67. self._modules[name] = instanceModule(class, self)
  68. self._modules[name]:create()
  69. end
  70. end
  71. function GameCore:getModule(name)
  72. if not self._modules[name] then
  73. warn(("No such module %s"):format(tostring(name)))
  74. end
  75. return self._modules[name]
  76. end
  77. function GameCore:callOnModules(methodName)
  78. callOnAll(self._modules, methodName, {}, function(key, module)
  79. if self._debugprints then
  80. print(("Calling [%s] on [%s]"):format(tostring(methodName), tostring(module)))
  81. end
  82. end)
  83. end
  84. function GameCore:load()
  85. self:instanceAllModules()
  86. self:callOnModules("preInit")
  87. self:callOnModules("init")
  88. self:callOnModules("postInit")
  89. end
  90. return GameCore