Hi, not sure this is the correct place to post, but here goes.
Im wondering if its worth it to make some libraries parametrisized
To explain what i mean by that i've made a small description and some psodo code.
Description:
Take a library that can make GuiWindows.
Lets say the Library would like to supply a way for an addon to close or open all GuiWindows made by that addon.
This can be done in several ways.
Creation and open and close should have an addon parameter, identifying what addon is working with the library.
Use a Factory of Factory scheme with closures
1) Adding an addon parameter
local Lib,minor=LibStub("GuiWindow-1.0",0)
minor=minor or 0
if not lib then return end
local addonSpace={}
setmetatable(addonSpaces,{__mode="v"})
function Lib:Create(addon,x,y,w,h)
if not addonSpace[addon] then addonSpace[addon]={} end
local window
-- TODO: code to create actual window
tinsert(addonSpace[addon],window)
end
function Lib:Hide(addon)
-- code to hide all windows made by addon
for window in ipairs(addonSpace[addon] do
window:Hide()
end
end
function Lib:Show(addon)
-- code to show all windows made by addon
for window in ipairs(addonSpace[addon] do
window:Show()
end
end
Would be used this way
addonName,addonTable=...
local myAddon=LibStub("AceAddon-3.0"):NewAddon(addonName)
local Lib=LibStub:GetLibrary("GuiWindows-1.0",true)
-- creating windows
local aWin1=Lib:Create([B]myAddon[/B],200,200,100,100)
local aWin2=Lib:Create([B]myAddon[/B],200,300,100,100)
local aWin3=Lib:Create([B]myAddon[/B],200,400,100,100)
-- hiding all myAddon windows
Lib:Hide([B]myAddon[/B])
-- showing all myAddon windows
Lib:Show([B]myAddon[/B])
In the library
local Lib,minor=LibStub("GuiWindow-1.0",0)
minor=minor or 0
if not lib then return end
local addonSpace={}
local closures={}
setmetatable(addonSpaces,{__mode="v"})
local function Create(addon,x,y,w,h)
if not addonSpace[addon] then addonSpace[addon]={} end
local window
-- TODO: code to create actual window
tinsert(addonSpace[addon],window)
end
local function Hide(addon)
-- code to hide all windows made by addon
for window in ipairs(addonSpace[addon] do
window:Hide()
end
end
local function Show(addon)
-- code to show all windows made by addon
for window in ipairs(addonSpace[addon] do
window:Show()
end
end
-- Creating table with closures
function Lib:Parametrisize(addon)
if closures[addon] then return closures[addon] end
local closure={
Create=function(x,y,w,h) return Create(addon,x,y,w,h) end,
Hide=function() return Hide(addon) end,
Show=function() return Show(addon) end
}
closures[addon]=closure
return closure
end
Addon using the library
addonName,addonTable=...
local myAddon=LibStub("AceAddon-3.0"):NewAddon(addonName)
local Lib=LibStub:GetLibrary("GuiWindows-1.0",true):Parametrisize(myAddon)
-- Use Lib
-- creating windows
local aWin1=Lib:Create(200,200,100,100)
local aWin2=Lib:Create(200,300,100,100)
local aWin3=Lib:Create(200,400,100,100)
-- hiding all myAddon windows
Lib:Hide()
-- showing all myAddon windows
Lib:Show()
Discussion
Is it worth it?
Note that Parametrisized is just a simple example
It could just as well have been made with multiple arguments
And if it fit the library it could implement more variants of Parametrisized.
An example could be a library that implemented several similar libraries.
Such a library could then supply several functions like Parametrisized where each would supply a different variant of the library.
The overhead of doing it this way is that we get a few extra closure tables (or one for each parametrisized like functions + if per addon is used, like in the example, one for each addon)
Note that it is using closures so the calling overhead is minimal
The benefit is robustness, easier use and that we can supply multiple variants of a library in less code.
Would love to hear what this great coding community thinks, so do post if you have some relevant observations.
First of all... I have not looked into how you put an addon/lib in the version control system that is used here... so I post here instead since its a small Lib
Hi... not sure if this is the right spot or if a similar function already exists in Ace3
If it does I can't see it.
Basically what this Lib do is to check if an "Object" (read table) has as a minimum what the caller is hoping for.
file: Libs/LibInterface-1.0/LibInterface-1.0.lua
-- this code is free to use as long as it follows whatever ace demands
-- disclaimer: use at own risk, I am not responsible for anything that might happen
-- coder Maisha@Draenor-EU aka Michael Lund Rasmussen
assert(LibStub, "LibInterface-1.0 requires LibStub")
local LibInterface, oldminor = LibStub:NewLibrary("LibInterface-1.0", 1)
if not lib then return end
oldminor = oldminor or 0
function LibInterface:HasInterface(obj,...)
local iface
local c=select('#',...)
for i=1,c do
iface=select(i,...)
assert(type(iface)~="table","iface has to be a table")
foreach k,v in pairs(iface) do
if type(obj[k])~=v then
return false
end
end
end
return true
end
function LibInterface:HasNotInterface(obj,...) {
local iface
local c=select('#',...)
for i=1,c do
iface=select(i,...)
assert(type(iface)~="table","iface has to be a table")
-- alternative is to ignore invalid interfaces
-- and put an if statement around the next foreach
-- if type(iface)=="table" then
foreach k,v in pairs(iface) do
if type(obj[k])==v then
return false
end
end
.. end
end
return true
}
LibInterface.embeds = LibInterface.embeds or {} -- what objects embed this lib
local mixins = {"HasInterface","HasNotInterface"}
function LibInterface:Embed(target)
for k, v in pairs(mixins) do
target[v] = self[v]
end
self.embeds[target] = true
return target
end
for target, v in pairs(LibInterface.embeds) do
LibInterface:Embed(target)
end
In a Display Addon using Libdatabroker1.1 we probably have something like this
local IEnterLeave={"OnEnter"="function","OnLeave"="function"}
local IStandard={"text"="string","label"="string","icon"="string"}
local INumberValue={"value"="number"}
local ITextValue={"value"="string"}
for name,dataobj in ldb:DataObjectIterator() do
-- here I use LibInterface to decide
if self:HasInterface(dataobj,IEnterLeave) then
-- set up the handlers
end
if self:HasInterface(dataobj,IStandard) then
if self:HasNotInterface(dataobj,INumberValue,IStringValue) then
--- the standard and no value
--- do that code
else
--- the standard and a value
--- do that code
end
end
end
This idea is basically to be able to check if an object implements some interface.
I know this is not a full interface check but its a start and ...
object parsing between addons, made my diffrent people, are more common now; so it might be helpfull.top have something like this.
Ace3 implements the Embed... this is a kind of IsEmbedded with a little extra in form of attribute checking.
0
The other half of the idea "Similar libraries in one" can be made by having multiple "constructors" in the library.. so i've been way off track.
Thanks for the input.
0
Im wondering if its worth it to make some libraries parametrisized
To explain what i mean by that i've made a small description and some psodo code.
Description:
Take a library that can make GuiWindows.
Lets say the Library would like to supply a way for an addon to close or open all GuiWindows made by that addon.
This can be done in several ways.
1) Adding an addon parameter
Would be used this way
In the library
Addon using the library
Discussion
Is it worth it?
Note that Parametrisized is just a simple example
It could just as well have been made with multiple arguments
And if it fit the library it could implement more variants of Parametrisized.
An example could be a library that implemented several similar libraries.
Such a library could then supply several functions like Parametrisized where each would supply a different variant of the library.
The overhead of doing it this way is that we get a few extra closure tables (or one for each parametrisized like functions + if per addon is used, like in the example, one for each addon)
Note that it is using closures so the calling overhead is minimal
The benefit is robustness, easier use and that we can supply multiple variants of a library in less code.
Would love to hear what this great coding community thinks, so do post if you have some relevant observations.
0
2. Where I find LibInterface usefull is for addons that are not self-contained.
self-contained: The author have access to all the code that will be used by the addon/library, before the addon/library is released.
An exampels of an addon type that is not self-contained is
Bazooka
Fortress
StatBlockCore
Chocolatebar
because none of them can know, at the time they make the addon, that all supplied dataobjects will be declared correctly.
Im sure they all implement some form of validation of the supplied dataObjects and reacts depending on the data supplied.
LibInterface is just a way to examine "objects" (like dataObjects from LibDataBroker) in a structured way.
When I'm done with my new code I'll post some detailed exampels.
0
Make a Display Addon
Make another addon containing the help content you want and make it pass the data to the display addon
That way you would not have to recode the display addon if you need to have more help content addons
This still means hardcoding of the documentation, but thats not much different from hardcoding it in a html file.
0
Hi... not sure if this is the right spot or if a similar function already exists in Ace3
If it does I can't see it.
Basically what this Lib do is to check if an "Object" (read table) has as a minimum what the caller is hoping for.
file: Libs/LibInterface-1.0/LibInterface-1.0.lua
In a Display Addon using Libdatabroker1.1 we probably have something like this
This idea is basically to be able to check if an object implements some interface.
I know this is not a full interface check but its a start and ...
object parsing between addons, made my diffrent people, are more common now; so it might be helpfull.top have something like this.
Ace3 implements the Embed... this is a kind of IsEmbedded with a little extra in form of attribute checking.
Maisha@Draenor-EU aka Michael Lund Rasmussen