Skip to content

Commit

Permalink
Document this mess
Browse files Browse the repository at this point in the history
  • Loading branch information
p3lim committed Feb 9, 2024
1 parent d9071d4 commit c12fd06
Show file tree
Hide file tree
Showing 12 changed files with 367 additions and 80 deletions.
38 changes: 38 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Generate docs
on: push

permissions:
contents: write

jobs:
docs:
runs-on: ubuntu-latest
steps:
- name: Clone project
uses: actions/checkout@v3

- name: Create docs directory
# lua-doc-parser should really handle this
run: |
mkdir .docs
- name: Parse and generate docs
uses: p3lim/lua-doc-parser@v2
with:
output: .docs

- name: Inject docs into readme
run: |
ex README.md << EOF
/DOCSTART/+1,/DOCEND/-1 d
-1 r .docs/*.md
wq
EOF
- name: Push docs
run: |
git config user.name 'GitHub Actions'
git config user.email [email protected]
git add README.md
git diff --quiet HEAD || git commit -m 'ci: update documentation'
git push
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@ Yes, the name is a pun.
Yes, you can use this if you want.
No, you should not depend on it being stable.

## Documentation

List of what this brings to the addon loading it.

In each example `namespace` refers to the 2nd value of the addon vararg, e.g:
```lua
local _, namespace = ...
```

<!-- DOCSTART -->

<!-- DOCEND -->

## Legal

This repository is dedicated to the [public domain](https://en.wikipedia.org/wiki/Public-domain_software).
11 changes: 8 additions & 3 deletions modules/defer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,14 @@ local function deferMethod(object, method, ...)
end
end

-- defer execution until after combat, or immediately if not in combat
-- usage: addon:Defer(callback, arg1[, ...])
-- addon:Defer(object, 'method'[, arg1[, ...]])
--[[ namespace:Defer(_callback_[, _..._])
Defers a function `callback` (with optional arguments) until after combat ends.
Immediately triggers if player is not in combat.
--]]
--[[ namespace:Defer(_object_, _method_[, _..._])
Defers a method `method` on `object` (with optional arguments) until after combat ends.
Immediately triggers if player is not in combat.
--]]
function addon:Defer(...)
if type(select(1, ...)) == 'table' then
assert(type(select(2, ...)) == 'string', 'arg2 must be the name of a method')
Expand Down
137 changes: 104 additions & 33 deletions modules/event.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
local addonName, addon = ...

--[[ namespace.eventMixin
A multi-purpose [event](https://warcraft.wiki.gg/wiki/Events)-[mixin](https://en.wikipedia.org/wiki/Mixin).
These methods are also available as methods directly on `namespace`.
--]]

local eventHandler = CreateFrame('Frame')
local callbacks = {}

Expand Down Expand Up @@ -37,6 +43,10 @@ local function IsUnitValid(unit)
end

local eventMixin = {}
--[[ namespace.eventMixin:RegisterEvent(_event_, _callback_)
Registers a [frame `event`](https://warcraft.wiki.gg/wiki/Events) with the `callback` function.
If the callback returns positive it will be unregistered.
--]]
function eventMixin:RegisterEvent(event, callback)
assert(IsEventValid(event), 'arg1 must be an event')
assert(type(callback) == 'function', 'arg2 must be a function')
Expand All @@ -55,6 +65,9 @@ function eventMixin:RegisterEvent(event, callback)
end
end

--[[ namespace.eventMixin:UnregisterEvent(_event_, _callback_)
Unregisters a [frame `event`](https://warcraft.wiki.gg/wiki/Events) from the `callback` function.
--]]
function eventMixin:UnregisterEvent(event, callback)
assert(IsEventValid(event), 'arg1 must be an event')
assert(type(callback) == 'function', 'arg2 must be a function')
Expand All @@ -73,6 +86,9 @@ function eventMixin:UnregisterEvent(event, callback)
end
end

--[[ namespace.eventMixin:IsEventRegistered(_event_, _callback_)
Checks if the [frame `event`](https://warcraft.wiki.gg/wiki/Events) is registered with the `callback` function.
--]]
function eventMixin:IsEventRegistered(event, callback)
assert(IsEventValid(event), 'arg1 must be an event')
assert(type(callback) == 'function', 'arg2 must be a function')
Expand All @@ -86,6 +102,10 @@ function eventMixin:IsEventRegistered(event, callback)
end
end

--[[ namespace.eventMixin:TriggerEvent(_event_[, _..._])
Manually trigger the `event` (with optional arguments) on all registered callbacks.
If the callback returns positive it will be unregistered.
--]]
function eventMixin:TriggerEvent(event, ...)
if callbacks[event] then
for _, data in next, callbacks[event] do
Expand Down Expand Up @@ -120,6 +140,10 @@ local function getUnitEventHandler(unit)
end

local unitEventCallbacks = {}
--[[ namespace.eventMixin:RegisterUnitEvent(_event_, _unit_[, _unitN,..._], _callback_)
Registers a [`unit`](https://warcraft.wiki.gg/wiki/UnitId)-specific [frame `event`](https://warcraft.wiki.gg/wiki/Events) with the `callback` function.
If the callback returns positive it will be unregistered for that unit.
--]]
function eventMixin:RegisterUnitEvent(event, ...)
assert(IsEventValid(event), 'arg1 must be an event')
local callback = select(select('#', ...), ...)
Expand Down Expand Up @@ -152,6 +176,9 @@ function eventMixin:RegisterUnitEvent(event, ...)
end
end

--[[ namespace.eventMixin:UnregisterUnitEvent(_event_, _unit_[, _unitN,..._], _callback_)
Unregisters a [`unit`](https://warcraft.wiki.gg/wiki/UnitId)-specific [frame `event`](https://warcraft.wiki.gg/wiki/Events) from the `callback` function.
--]]
function eventMixin:UnregisterUnitEvent(event, ...)
assert(IsEventValid(event), 'arg1 must be an event')
local callback = select(select('#', ...), ...)
Expand All @@ -177,6 +204,9 @@ function eventMixin:UnregisterUnitEvent(event, ...)
end
end

--[[ namespace.eventMixin:IsUnitEventRegistered(_event_, _unit_[, _unitN,..._], _callback_)
Checks if the [`unit`](https://warcraft.wiki.gg/wiki/UnitId)-specific [frame `event`](https://warcraft.wiki.gg/wiki/Events) is registered with the `callback` function.
--]]
function eventMixin:IsUnitEventRegistered(event, ...)
assert(IsEventValid(event), 'arg1 must be an event')
local callback = select(select('#', ...), ...)
Expand All @@ -197,6 +227,10 @@ function eventMixin:IsUnitEventRegistered(event, ...)
end
end

--[[ namespace.eventMixin:TriggerEvent(_event_, _unit_[, _unitN,..._][, _..._])
Manually trigger the [`unit`](https://warcraft.wiki.gg/wiki/UnitId)-specific `event` (with optional arguments) on all registered callbacks.
If the callback returns positive it will be unregistered.
--]]
function eventMixin:TriggerUnitEvent(event, unit, ...)
if unitEventCallbacks[unit] and unitEventCallbacks[unit][event] then
for _, data in next, unitEventCallbacks[unit][event] do
Expand All @@ -213,25 +247,10 @@ end

-- special handling for combat events
local combatEventCallbacks = {}
do
local function internalTrigger(_, event, _, ...)
if combatEventCallbacks[event] then
for _, data in next, combatEventCallbacks[event] do
local successful, ret = pcall(data.callback, data.owner, ...)
if not successful then
error(ret)
elseif ret then
eventMixin.UnregisterCombatEvent(data.owner, event, data.callback)
end
end
end
end

function eventMixin:TriggerCombatEvent()
internalTrigger(CombatLogGetCurrentEventInfo())
end
end

--[[ namespace.eventMixin:RegisterCombatEvent(_subEvent_, _callback_)
Registers a [combat `subEvent`](https://warcraft.wiki.gg/wiki/COMBAT_LOG_EVENT) with the `callback` function.
If the callback returns positive it will be unregistered.
--]]
function eventMixin:RegisterCombatEvent(event, callback)
assert(type(event) == 'string', 'arg1 must be a string')
assert(type(callback) == 'function', 'arg2 must be a function')
Expand All @@ -250,6 +269,9 @@ function eventMixin:RegisterCombatEvent(event, callback)
end
end

--[[ namespace.eventMixin:UnregisterCombatEvent(_subEvent_, _callback_)
Unregisters a [combat `subEvent`](https://warcraft.wiki.gg/wiki/COMBAT_LOG_EVENT) from the `callback` function.
--]]
function eventMixin:UnregisterCombatEvent(event, callback)
assert(type(event) == 'string', 'arg1 must be a string')
assert(type(callback) == 'function', 'arg2 must be a function')
Expand All @@ -264,26 +286,48 @@ function eventMixin:UnregisterCombatEvent(event, callback)
end
end

--[[ namespace.eventMixin:TriggerCombatEvent(_subEvent_)
Manually trigger the [combat `subEvent`](https://warcraft.wiki.gg/wiki/COMBAT_LOG_EVENT) on all registered callbacks.
If the callback returns positive it will be unregistered.
* Note: this is pretty useless on it's own, and should only ever be triggered by the event system.
--]]
do
local function internalTrigger(_, event, _, ...)
if combatEventCallbacks[event] then
for _, data in next, combatEventCallbacks[event] do
local successful, ret = pcall(data.callback, data.owner, ...)
if not successful then
error(ret)
elseif ret then
eventMixin.UnregisterCombatEvent(data.owner, event, data.callback)
end
end
end
end

function eventMixin:TriggerCombatEvent()
internalTrigger(CombatLogGetCurrentEventInfo())
end
end

-- expose mixin
addon.eventMixin = eventMixin

-- anonymous event registration
addon = setmetatable(addon, {
__index = function(t, key)
if IsEventValid(key) then
-- addon:EVENT_NAME([arg1[, ...]])
return function(_, ...)
eventMixin.TriggerEvent(t, key, ...)
end
else
-- default table behaviour
return rawget(t, key)
end
end,
__newindex = function(t, key, value)
if key == 'OnLoad' then
-- addon:OnLoad() = function() end
-- shorthand for ADDON_LOADED
--[[ namespace:OnLoad()
Shorthand for the [`ADDON_LOADED`](https://warcraft.wiki.gg/wiki/ADDON_LOADED) for the addon.
Usage:
```lua
function namespace:OnLoad()
-- I'm loaded!
end
```
--]]
addon:RegisterEvent('ADDON_LOADED', function(self, name)
if name == addonName then
local successful, ret = pcall(value, self)
Expand All @@ -295,13 +339,40 @@ addon = setmetatable(addon, {
end
end)
elseif IsEventValid(key) then
-- addon:EVENT_NAME(...) = function() end
--[[ namespace:_event_
Registers a to an anonymous function.
Usage:
```lua
function namespace:BAG_UPDATE(bagID)
-- do something
end
```
--]]
eventMixin.RegisterEvent(t, key, value)
else
-- default table behaviour
rawset(t, key, value)
end
end,
__index = function(t, key)
if IsEventValid(key) then
--[[ namespace:_event_([_..._])
Manually trigger all registered anonymous `event` callbacks, with optional arguments.
Usage:
```lua
namespace:BAG_UPDATE(1) -- triggers the above example
```
--]]
return function(_, ...)
eventMixin.TriggerEvent(t, key, ...)
end
else
-- default table behaviour
return rawget(t, key)
end
end,
})

-- mixin to namespace
Expand Down
10 changes: 10 additions & 0 deletions modules/input.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
local addonName, addon = ...

--[[ namespace:RegisterSlash(_command_[, _commandN,..._], _callback_)
Registers chat slash `command`(s) with a `callback` function.
Usage:
```lua
namespace:RegisterSlash('/hello', '/hi', function(input)
print('Hi')
end)
```
--]]
function addon:RegisterSlash(...)
local name = addonName .. 'Slash' .. math.random()
local failed
Expand Down
13 changes: 13 additions & 0 deletions modules/load.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ local _, addon = ...
local IsAddOnLoaded = C_AddOns and C_AddOns.IsAddOnLoaded or IsAddOnLoaded

local addonCallbacks = {}
--[[ namespace:HookAddOn(_addonName_, _callback_)
Registers a hook for when an addon with the name `addonName` loads with a `callback` function.
--]]
function addon:HookAddOn(addonName, callback)
if IsAddOnLoaded(addonName) then
callback(self)
Expand All @@ -23,6 +26,16 @@ function addon:ADDON_LOADED(addonName)
end

function addon:PLAYER_LOGIN()
--[[ namespace:OnLogin()
Shorthand for the [`PLAYER_LOGIN`](https://warcraft.wiki.gg/wiki/PLAYER_LOGIN).
Usage:
```lua
function namespace:OnLogin()
-- player has logged in!
end
```
--]]
if addon.OnLogin then
addon:OnLogin()
end
Expand Down
22 changes: 19 additions & 3 deletions modules/locale.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,25 @@ local _, addon = ...
local localizations = {}
local locale = GetLocale()

-- usage:
-- set: addon.L('deDE')['New string'] = 'Neue Saite'
-- get: addon.L['New string']
--[[ namespace.L(_locale_)[`string`]
Sets a localization `string` for the given `locale`.
Usage:
```lua
local L = namespace.L('deDE')
L['New string'] = 'Neue saite'
```
--]]
--[[ namespace.L[`string`]
Reads a localized `string` for the active locale.
If a localized string for the active locale is not available the `string` will be read back.
Usage:
```lua
print(namespace.L['New string']) --> "Neue saite" on german clients, "New string" on all others
print(namespace.L['Unknown']) --> "Unknown" on all clients since there are no localizations
```
--]]
addon.L = setmetatable({}, {
__index = function(_, key)
local localeTable = localizations[locale]
Expand Down
Loading

0 comments on commit c12fd06

Please sign in to comment.