Information for Addon Authors
LibFilter-1.0 is meant to be a way to create generic filters that can be used as plugins by other addons. This document describes the API contract that filters must follow.
TYPES
- Filter Strings
- All filters work on strings in the format of WoW item strings, spell strings etc. That is "type:value1:value2:value3:..." Filter should transparently strip off hyperlink formatting "|cXXXXXXXX|H...|h[...]|h|r"
- Filter Type
- This may be any of the standard Blizzard types: "achievement", "item", "enchant", "item", "quest", "spell", or "talent"; or it may be any custom type. See the LibFilter-1.0 library variable FilterType in the source code for some recommended types.
LIBRARY CREATION
A LibFilter filter is a LibStub library that follows the conventions in this document. The library name should begin with "LibFilter-".
As a convience LibFilter can be used to create the library with the NewFilter method, but it is recommended that filters use LibStub directly to avoid having to depend on the LibFilter-1.0 library.
Example:
local MAJOR, MINOR = "LibFilter-myfilter", 1 local filter = LibStub:NewLibrary(MAJOR, MINOR) if not filter then return end
LIBRARY VARIABLES
Filters are required to have some standard variables
key
- filter.key (string) [REQUIRED]
- This is string used to identify the filter. This string should not be localized.
Example:
filter.key = "myfilter"
filtertype
- filter.filtertype (string) [REQUIRED]
- This is the type of strings the filter supports. If a filter supports more than one type of string then this should be set to the main type or "GENERIC". It is important that this string not be localize.
Example:
filter.filtertype = "item"
filtertypes
- filter.filtertypes (table) [OPTIONAL]
- This is a table of filter types supported by the filter. As with filtertype the keys of this table should not be localized.
- Important note: If this table users of this filter may create it and add the filter type in filter.filtertype to it.
Example:
filter.filtertypes = filter.filtertypes or {} filter.filtertypes["item"] = 1 filter.filtertypes["Slot"] = 1
author
- filter.author (string) [OPTIONAL]
- The author of the filter. This is the author of the filter itself even if it is primarily an interface to another addon.
Example:
filter.author = "me"
credits
- filter.credits (string) [OPTIONAL] [LOCALIZED]
- This string should list any credits the author wish to give. If the filter is an interface to a specific addon, the author of that addon should probably be listed here. May be localized, this is also a good spot to put translation credits.
Example:
filter.credits = L["XYZ was written by Someone Else."]
name
- filter.name (string) [OPTIONAL] [LOCALIZED]
- The name of filter localized into the current language. If not set filter.key may be used instead.
Example:
filter.name = L["MyFilter"]
description
- filter.description (string) [OPTIONAL] [LOCALIZED]
- A longer description localized into the current language. If not set filter.name or filter.key may be used instead.
Example:
filter.description = L["This is a sample filter that does nothing"]
LIBRARY METHODS
The following methods may be provided by filters.
NewSettings
- filter:NewSettings([defaults]) [REQUIRED]
- in: defaults (table or nil) - Defaults for the settings
- out: settings (table or nil) - Opaque setting table
- This method creates settings that may be used for effectively an individual instance of this filter. The contents of the settings table should be treated as opaque, but may be stored in a saved variable. This function will never return input table. If the filter needs no settings it may return nil.
- filter:FreeSettings(settings) [REQUIRED]
- in: settings (table or nil) - Settings no longer to be used.
- This function lets the filter know that the settings passed in will no longer be used. It may used this information to determine if it no longer needs collect data etc.
- filter:DescribeSettings(settings) [OPTIONAL]
- in: settings (table or nil) - Settings to be described
- out: description (string or nil) - Localized description of settings
- This function returns a localized single line description of the settings. If it is not present or returns nil, then the filter.name or filter.key should be used in order.
- filter:SettingsOptions(settings,[func]) [OPTIONAL]
- filter:SettingsOptions(settings,[table,method])
- in: settings (table) - Settings to be configured
- in: func (function) - Function to be called when settings are changed
- in: table (table) - Table with a method
- in: method (string) - Method of table to be called when setting changed.
- out: optiontable (table) - AceOption table.
- Returns a AceOption table that can be used to display and change the options for settings. If neither func nor table and method are specified the normal callbacks will be fired if any settings are changed. The callback will be given settings as a parameter.
- If a filter does not have any settings this function will not be defined.
- filter:TestIfMatch(settings,linkorstring) [REQUIRED]
- in: settings (table or nil) - Settings to be used for test
- in: linkorstring (string or nil) - Filter String to be matched
- out: true if match otherwise nil or false
- This function test if the filter with the give settings matches the provided string.
- IMPORTANT NOTE: This function should not assume that the linkorstring parameter has been normalized in any way. It should removed any link formatting and handle missing values as necessary. For strings based on Blizzard types the passed value must work when passed to any normal function expecting that type of string.
- LibStub("LibFilter-1.0"):Decode can be used if necessary to converted a linkorstring into a table of the pieces. Though a filter specific approach is normally better.
- filter:TestIfMatchSplit(settings,...) [OPTIONAL]
- in: settings(table or nil) - Settings to be used for test
- in: ... - linkorstring split along : and hyperlink removed
- out: filter:TestIfMatch(settings,strjoin(":",...))
- If this function is present it should be a optimization for working with strings that have already been split into pieces.
- CAUTION: The first parameter after settings must be the type of string.
- Correct: filter:TestIfMatchSplit(settings,"item",6948)
- Wrong: filter:TestIfMatchSplit(settings,6948)
- filter.RegisterCallback(target,"FilterUpdate",method) [OPTIONAL]
- filter.RegisterCallback(target,"FilterUpdate",func) [OPTIONAL]
- in: target (table) - Some table owned by the caller
- in: method (string) - Name of a method on table.
- in: func (function) - Function to call
- Registers a callback that will be called if the filter should be retested.
- filter.UnregisterCallback(target,"FilterUpdate")
- filter.UnregisterAllCallbacks(target)
- in: target (table) - Some table owned by the caller
- Stops calling a previously registered callback.
Examples
Usage: Create brand new settings
settings = filter:NewSettings()
Usage: Rebless settings restored from saved variables
settings = filter:NewSettings(settings)
Usage: Make a copy of settings
settings_copy = filter:NewSettings(settings_orig)
Implementation: No settings needed
function filter:NewSettings(defaults) return nil end
Implementation: Simple
function filter:NewSettings(defaults) return { option1 = defaults and defaults.option1 or option1default, option2 = defaults and defaults.option2 or option2default, } end
Implementation: With Record keeping
-- Some private record of active settings filter.active_settings = (filter.active_settings or setmetatable({}, {__mode='k'})) local active_settings = filter.active_settings
function filter:NewSettings(defaults) local res = { option1 = defaults and defaults.option1 or option1default, option2 = defaults and defaults.option2 or option2default, } if not next(active_settings) then -- First settings detected start gathering data end active_settings[res] = 1 return res end
FreeSettings
Examples
Implementation: Simple or no settings needed
function filter:FreeSettings(settings) end
Implementation: With record keeping
function filter:FreeSettings(settings) active_settings[settings] = nil if not next(active_settings) then -- Last settings unregistered stop gathering data end end
DescribeSettings
Examples
Usage:
desc = (filter.DescribeSettings and filter:DescribeSettings(settings) or filter.name or filter.key)
Implementation:
function filter:DescribeSettings(settings) return (L["MyFilter option1: %s option2: %s"]:format(settings and settings.option1 or "???",settings and settings.option2 or "???")) end
SettingsOptions
Examples
Usage:
local opttable = filter:Settings(settings,update) ...:Feed...(...,optable,...)
Implementation:
function filter:SettingsOptions(settings,table,method) if not settings then return end
local callback if table then if type(table) == "string" then callback = function() table[func](table,settings) end else callback = function() table(func,settings) end end end if not callback then callback = function() callbacks:Fire("FilterUpdate") end end
local args = { { order = 1, type = "toggle", name = L["option1"], desc = L["option1desc"], get = function() return settings and settings.option1 end, set = function(v) settings.option1 = v callback() end, }, { order = 1, type = "toggle", name = L["option2"], desc = L["option2desc"], get = function() return settings and settings.option2 end, set = function(v) settings.option2 = v callback() end, } } return { type = "group", desc = "myfilter_options", args = args } end
TestIfMatch
Examples
Usage:
if (filter:TestIfMatch(settings,"item:6948:0:0:0:0:0:0:0")) then -- filter matches Hearthstone end
Implementation:
function filter:TestIfMatch(settings,linkorstring) local id = linkorstring and linkorstring:match("(%-?%d+)") if not settings or settings.option1 == "hearthstone" then if id and id == 6948 then return true end end return nil end
TestIfMatchSplit
Examples
Usage:
local match if filter.TestIfMatchSplit then match = filter:TestIfMatchSplit(settings,"Slot",bag,slot) else match = filter:TestIfMatch(settings,strjoin(":","Slot","bag","slot")) end
Implementation:
function filter:TestIfMatchSplit(settings,type,id) if not settings or settings.option1 == "hearthstone" then if id and id == 6948 then return true end end return nil end
RegisterCallback
Examples
Usage:
... if filter.RegisterCallback then filter.RegisterCallback(actor,"FilterUpdate","Rescan") end ... function actor:Rescan() -- Retest filter againsnt whatever end
Implementation:
filter.callbacks = (filter.callbacks or LibStub("CallbackHandler-1.0"):New(filter)) local callbacks = filter.callbacks -- Let our consumers know that they need to retest callbacks:Fire("FilterUpdate")
UnregisterCallback
Comments