Updated library handling

pull/13/head
4n0n 1 year ago
parent d5b0ccf42b
commit f5367327e6
  1. 2
      .gitignore
  2. 2
      scripts/ExampleModule.lua
  3. 21
      scripts/Libraries/ExampleDependency.lua
  4. 15
      scripts/Libraries/ExampleDependencyError.lua
  5. 27
      scripts/Libraries/ExampleLibrary.lua
  6. 115
      src/Library/Library.lua
  7. 86
      src/_bastion.lua

2
.gitignore vendored

@ -12,6 +12,8 @@ scripts/Libraries/*
!scripts/.gitkeep !scripts/.gitkeep
!scripts/ExampleModule.lua !scripts/ExampleModule.lua
!scripts/Libraries/ExampleLibrary.lua !scripts/Libraries/ExampleLibrary.lua
!scripts/Libraries/ExampleDependency.lua
!scripts/Libraries/ExampleDependencyError.lua
## ignore vscode settings ## ignore vscode settings
.vscode/* .vscode/*

@ -4,7 +4,7 @@ local Player = Bastion.UnitManager:Get('player')
local FlashHeal = Bastion.SpellBook:GetSpell(2061) local FlashHeal = Bastion.SpellBook:GetSpell(2061)
local AdvancedMath = Bastion:GetLibrary('AdvancedMath') local AdvancedMath = Bastion:Import('AdvancedMath')
print(AdvancedMath:Add(1, 2)) print(AdvancedMath:Add(1, 2))

@ -0,0 +1,21 @@
local Tinkr, Bastion = ...
local Player = Bastion.UnitManager:Get('player')
Bastion:RegisterLibrary(Bastion.Library:New({
name = 'Dependable',
exports = {
default = function()
local Dependable = {}
Dependable.__index = Dependable
function Dependable:Test(a)
print(a)
end
return Dependable
end,
Test = 5
}
}))

@ -0,0 +1,15 @@
local Tinkr, Bastion = ...
Bastion:RegisterLibrary(Bastion.Library:New({
name = 'Circular',
exports = {
default = function(self)
-- Return default first, and then the remaining exports
local Math, OtherExports = self:Import('AdvancedMath')
print(Math:Add(1, 2))
return 'Circular'
end
}
}))

@ -1,14 +1,25 @@
local Tinkr, Bastion = ... local Tinkr, Bastion = ...
local ExampleModule = Bastion.Module:New('ExampleModule') Bastion:RegisterLibrary(Bastion.Library:New({
local Player = Bastion.UnitManager:Get('player') name = 'AdvancedMath',
exports = {
default = function(self) -- Function exports are called when the library is loaded
-- Return default first, and then the remaining exports
local Dependable, OtherExports = self:Import('Dependable')
local AdvancedMath = {} local CircularDependency = self:Import('Circular') -- Causes a circular dependency error
AdvancedMath.__index = AdvancedMath Dependable:Test(OtherExports.Test)
function AdvancedMath:Add(a, b) local AdvancedMath = {}
return a + b
end
Bastion:RegisterLibrary('AdvancedMath', AdvancedMath) AdvancedMath.__index = AdvancedMath
function AdvancedMath:Add(a, b)
return a + b
end
return AdvancedMath
end
}
}))

@ -0,0 +1,115 @@
local Tinkr, Bastion = ...
---@class Library
---@field name string
---@field dependencies table
---@field exports table
---@field resolved table
local Library = {
name = nil,
dependencies = {},
exports = {
default = function()
return nil
end
},
resolved = nil
}
Library.__index = Library
---@param name string
---@param library table
---@return Library
function Library:New(library)
local self = {
name = library.name or nil,
dependencies = {},
exports = library.exports or {
default = function()
return nil
end
},
resolved = nil
}
self = setmetatable(self, Library)
return self
end
function Library:ResolveExport(export)
if type(export) == 'function' then
return export(self)
end
return export
end
function Library:Resolve()
if not self.exports then
error("Library " .. self.name .. " has no exports")
end
if self.resolved then
if self.exports.default then
return self.resolved[1], self.resolved[2]
end
return unpack(self.resolved)
end
if self.exports.default then
-- return default first if it exists
local default = self.exports.default
local remaining = {}
for k, v in pairs(self.exports) do
if k ~= 'default' then
remaining[k] = self:ResolveExport(v)
end
end
self.resolved = {self:ResolveExport(default), remaining}
return self.resolved[1], self.resolved[2]
end
self.resolved = {}
for k, v in pairs(self.exports) do
self.resolved[k] = self:ResolveExport(v)
end
return unpack(self.resolved)
end
function Library:DependsOn(other)
for _, dependency in pairs(self.dependencies) do
if dependency == other then
return true
end
end
return false
end
---@param library string
function Library:Import(library)
local lib = Bastion:GetLibrary(library)
if not lib then
error("Library " .. library .. " does not exist")
end
if not table.contains(self.dependencies, library) then
table.insert(self.dependencies, library)
end
if lib:DependsOn(self.name) then
error("Circular dependency detected between " .. self.name .. " and " .. library)
end
return lib:Resolve()
end
return Library

@ -14,6 +14,8 @@ end
Bastion.ClassMagic = Bastion.require("ClassMagic") Bastion.ClassMagic = Bastion.require("ClassMagic")
---@type List ---@type List
Bastion.List = Bastion.require("List") Bastion.List = Bastion.require("List")
---@type Library
Bastion.Library = Bastion.require("Library")
---@type NotificationsList, Notification ---@type NotificationsList, Notification
Bastion.NotificationsList, Bastion.Notification = Bastion.require("NotificationsList") Bastion.NotificationsList, Bastion.Notification = Bastion.require("NotificationsList")
---@type Vector3 ---@type Vector3
@ -134,15 +136,6 @@ Bastion.EventManager:RegisterWoWEvent("COMBAT_LOG_EVENT_UNFILTERED", function()
end end
end) end)
function Bastion:RegisterLibrary(name, payload)
LIBRARIES[name] = payload
-- Bastion:Print("Registered Library", name)
end
function Bastion:GetLibrary(name)
return LIBRARIES[name]
end
Bastion.Ticker = C_Timer.NewTicker(0.1, function() Bastion.Ticker = C_Timer.NewTicker(0.1, function()
if not Bastion.CombatTimer:IsRunning() and UnitAffectingCombat("player") then if not Bastion.CombatTimer:IsRunning() and UnitAffectingCombat("player") then
Bastion.CombatTimer:Start() Bastion.CombatTimer:Start()
@ -288,6 +281,81 @@ local function Load(dir)
end end
end end
---@param library Library
function Bastion:RegisterLibrary(library)
LIBRARIES[library.name] = library
print("Registered library", library.name)
end
function Bastion:CheckLibraryDependencies()
for k, v in pairs(LIBRARIES) do
if v.dependencies then
for i = 1, #v.dependencies do
local dep = v.dependencies[i]
if LIBRARIES[dep] then
if LIBRARIES[dep].dependencies then
for j = 1, #LIBRARIES[dep].dependencies do
if LIBRARIES[dep].dependencies[j] == v.name then
Bastion:Print("Circular dependency detected between " .. v.name .. " and " .. dep)
return false
end
end
end
else
Bastion:Print("Library " .. v.name .. " depends on " .. dep .. " but it's not registered")
return false
end
end
end
end
return true
end
function Bastion:Import(library)
local lib = self:GetLibrary(library)
if not lib then
error("Library " .. library .. " not found")
end
return lib:Resolve()
end
function Bastion:GetLibrary(name)
if not LIBRARIES[name] then
error("Library " .. name .. " not found")
end
local library = LIBRARIES[name]
-- if library.dependencies then
-- for i = 1, #library.dependencies do
-- local dep = library.dependencies[i]
-- if LIBRARIES[dep] then
-- if LIBRARIES[dep].dependencies then
-- for j = 1, #LIBRARIES[dep].dependencies do
-- if LIBRARIES[dep].dependencies[j] == library.name then
-- Bastion:Print("Circular dependency detected between " .. library.name .. " and " .. dep)
-- return false
-- end
-- end
-- end
-- else
-- Bastion:Print("Library " .. v.name .. " depends on " .. dep .. " but it's not registered")
-- return false
-- end
-- end
-- end
return library
end
Load("scripts/bastion/scripts/Libraries/") Load("scripts/bastion/scripts/Libraries/")
-- if not Bastion:CheckLibraryDependencies() then
-- return
-- end
Load("scripts/bastion/scripts/Modules/") Load("scripts/bastion/scripts/Modules/")
Load("scripts/bastion/scripts/") Load("scripts/bastion/scripts/")

Loading…
Cancel
Save