From 37c46d377be4c0b2308ed6c96ee3d307ae3e642b Mon Sep 17 00:00:00 2001 From: omicron Date: Fri, 19 May 2023 17:23:11 +0200 Subject: [PATCH] Initial commit Basic interopability with LibSharedMedia, functions to register and retrieve media. --- .gitignore | 2 + LICENSE.md | 19 ++++++ Makefile | 47 +++++++++++++++ src/LibFreeMedia.lua | 140 +++++++++++++++++++++++++++++++++++++++++++ src/LibFreeMedia.toc | 7 +++ src/libs/LibStub.lua | 51 ++++++++++++++++ 6 files changed, 266 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE.md create mode 100644 Makefile create mode 100644 src/LibFreeMedia.lua create mode 100644 src/LibFreeMedia.toc create mode 100644 src/libs/LibStub.lua diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..67e07b8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/build +/release diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..d7d659d --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,19 @@ +Copyright (c) 2023 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0fa4fe7 --- /dev/null +++ b/Makefile @@ -0,0 +1,47 @@ +.PHONY: all release build build-addon build-embed release-addon-zip release-addon-tar release-embed-zip release-embed-tar clean install + +BUILD_DIR := ./build +RELEASE_DIR := ./release +SRC_DIR := ./src +MEDIA_DIR := ./media + +all: release-addon-zip release-addon-tar release-embed-zip release-embed-tar + + +release: build + mkdir -p $(RELEASE_DIR) + +build: build-addon build-embed + + +build-addon: clean + mkdir -p $(BUILD_DIR)/addon + cp -r $(SRC_DIR) $(BUILD_DIR)/addon/LibFreeMedia + cp LICENSE.md $(BUILD_DIR)/addon/LibFreeMedia + #cp CHANGELOG.md $(BUILD_DIR)/addon/LibFreeMedia + +build-embed: clean + mkdir -p $(BUILD_DIR)/embed/LibFreeMedia + cp $(SRC_DIR)/LibFreeMedia.lua $(BUILD_DIR)/embed/LibFreeMedia + cp LICENSE.md $(BUILD_DIR)/embed/LibFreeMedia + +release-addon-zip: release + 7z a -tzip $(RELEASE_DIR)/LibFreeMedia-standalone.zip -w $(BUILD_DIR)/addon/. + +release-addon-tar: release + tar -cJf $(RELEASE_DIR)/LibFreeMedia-standalone.tar.xz -C $(BUILD_DIR)/addon LibFreeMedia + tar -czf $(RELEASE_DIR)/LibFreeMedia-standalone.tar.gz -C $(BUILD_DIR)/addon LibFreeMedia + +release-embed-zip: release + 7z a -tzip $(RELEASE_DIR)/LibFreeMedia-embed.zip -w $(BUILD_DIR)/embed/. + +release-embed-tar: release + tar -cJf $(RELEASE_DIR)/LibFreeMedia-embed.tar.xz -C $(BUILD_DIR)/embed LibFreeMedia + tar -czf $(RELEASE_DIR)/LibFreeMedia-embed.tar.gz -C $(BUILD_DIR)/embed LibFreeMedia + +clean: + rm -rf $(BUILD_DIR) $(RELEASE_DIR) + +install: build + test -d "${WOW_ADDON_DIR}" + echo rsync -q -a ./build/addon/LibFreeMedia "${WOW_ADDON_DIR}/" --delete diff --git a/src/LibFreeMedia.lua b/src/LibFreeMedia.lua new file mode 100644 index 0000000..eea021f --- /dev/null +++ b/src/LibFreeMedia.lua @@ -0,0 +1,140 @@ +local lib = LibStub:NewLibrary("LibFreeMedia", 100) +if not lib then + return +end + +local DEFAULT_MEDIA_TABLE = { + background = { + ["Blizzard Dialog Background"] = "Interfacee\\DialogFrame\\UI-DialogBox-Background", + ["Blizzard Dialog Background Dark"] = "Interfacee\\DialogFrame\\UI-DialogBox-Background-Dark", + ["Blizzard Dialog Background Gold"] = "Interfacee\\DialogFrame\\UI-DialogBox-Gold-Background", + ["Blizzard Low Health"] = "Interfacee\\FullScreenTextures\\LowHealth", + ["Blizzard Marble"] = "Interfacee\\FrameGeneral\\UI-Background-Marble", + ["Blizzard Out of Control"] = "Interfacee\\FullScreenTextures\\OutOfControl", + ["Blizzard Parchment"] = "Interfacee\\AchievementFrame\\UI-Achievement-Parchment-Horizontal", + ["Blizzard Parchment 2"] = "Interfacee\\AchievementFrame\\UI-GuildAchievement-Parchment-Horizontal", + ["Blizzard Rock"] = "Interfacee\\FrameGeneral\\UI-Background-Rock", + ["Blizzard Tabard Background"] = "Interfacee\\TabardFrame\\TabardFrameBackground", + ["Blizzard Tooltip"] = "Interfacee\\Tooltips\\UI-Tooltip-Background", + ["Solid"] = "Interfacee\\Buttons\\WHITE8X8", + }, + font = { + ["Arial Narrow"] = "Fonts\\ARIALN.TTF", + ["Friz Quadrata TT"] = "Fonts\\FRIZQT__.TTF", + ["Morpheus"] = "Fonts\\MORPHEUS.TTF", + ["Skurri"] = "Fonts\\SKURRI.TTF", + }, + border = { + ["None"] = "Interface\\None", + ["Achievement Wood"] = "Interface\\AchievementFrame\\UI-Achievement-WoodBorder", + ["Chat Bubble"] = "Interface\\Tooltips\\ChatBubble-Backdrop", + ["Blizzard Dialog"] = "Interface\\DialogFrame\\UI-DialogBox-Border", + ["Blizzard Dialog Gold"] = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border", + ["Blizzard Party"] = "Interface\\CHARACTERFRAME\\UI-Party-Border", + ["Blizzard Tooltip"] = "Interface\\Tooltips\\UI-Tooltip-Border", + }, + statusbar = { + ["Blizzard"] = "Interface\\TargetingFrame\\UI-StatusBar", + ["Blizzard Character Skills Bar"] = "Interface\\PaperDollInfoFrame\\UI-Character-Skills-Bar", + }, + sound = { + ["None"] = "Interface\\Quiet.ogg", + } +} + +local function MakeDefaultList() + local lists = {} + for kind, media in pairs(DEFAULT_MEDIA_TABLE) do + local list = {} + lists[kind] = list + for identifier, _ in pairs(media) do + table.insert(list, identifier) + end + table.sort(list) + end + return lists +end + +local DEFAULT_MEDIA_LIST = MakeDefaultList() + + +-- Interopability with a proprietary alternative is contained in this block +do + local libsm = LibStub:GetLibrary("LibSharedMedia-3.0", true) + if not libsm then + -- Register an empty library with just the data tables + libsm = LibStub:NewLibrary("LibSharedMedia-3.0", 0) + libsm.MediaTable = DEFAULT_MEDIA_TABLE + libsm.MediaList = DEFAULT_MEDIA_LIST + end + + ---@type table> + lib.media = libsm.MediaTable + ---@type table + lib.mediaList = libsm.MediaList +end + + +---@param kind string The kind of media you are registering. E.g. "font" or "background" +---@param identifier string Named identifier for the media +---@param data any +---@return boolean +-- Does not sort the media list after it added a file +local function RegisterOne(kind, identifier, data) + local media = lib.media[kind] + local mediaList = lib.mediaList[kind] + if not media then + media = {} + mediaList = {} + lib.media[kind] = media + lib.mediaList[kind] = mediaList + end + if media[identifier] then + return false + end + + media[identifier] = data + table.insert(lib.mediaList[kind], identifier) + return true +end + + +---@param kind string The kind of media you are registering. E.g. "font" or "background" +---@param identifier string Named identifier for the media +---@param data any +---@return boolean +function lib:Register(kind, identifier, data) + local retval = RegisterOne(kind, identifier, data) + if retval then + table.sort(self.mediaList[kind]) + end + return retval +end + + +---Return the media that matches the given kind and identifier. May return nil if the media does not exist. +---@param kind string The kind of media you are requesting. E.g. "font" or "background" +---@param identifier string Named identifier for the media +---@return any | nil +function lib:Get(kind, identifier) + local media = self.media[kind] + if media then + return media[identifier] + end +end + + +---Return a sorted list of identifiers. May return nil if there is no media of that kind. +---@param kind string The kind of media you are requesting. E.g. "font" or "background" +---@return string[] | nil +function lib:GetList(kind) + return self.mediaList[kind] +end + + +---Return a table with identifier keys and media data values +---@param kind string The kind of media you are requesting. E.g. "font" or "background" +---@return table | nil +function lib:GetTable(kind) + return self.media[kind] +end diff --git a/src/LibFreeMedia.toc b/src/LibFreeMedia.toc new file mode 100644 index 0000000..f2f5adf --- /dev/null +++ b/src/LibFreeMedia.toc @@ -0,0 +1,7 @@ +## Interface: 100100 +## Title: LibFreeMedia +## Notes: Freely share media between addons +## Version: 0.1.0 + +libs/LibStub.lua +LibFreeMedia.lua diff --git a/src/libs/LibStub.lua b/src/libs/LibStub.lua new file mode 100644 index 0000000..7e7b76d --- /dev/null +++ b/src/libs/LibStub.lua @@ -0,0 +1,51 @@ +-- $Id: LibStub.lua 103 2014-10-16 03:02:50Z mikk $ +-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/addons/libstub/ for more info +-- LibStub is hereby placed in the Public Domain +-- Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke +local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS! +local LibStub = _G[LIBSTUB_MAJOR] + +-- Check to see is this version of the stub is obsolete +if not LibStub or LibStub.minor < LIBSTUB_MINOR then + LibStub = LibStub or {libs = {}, minors = {} } + _G[LIBSTUB_MAJOR] = LibStub + LibStub.minor = LIBSTUB_MINOR + + -- LibStub:NewLibrary(major, minor) + -- major (string) - the major version of the library + -- minor (string or number ) - the minor version of the library + -- + -- returns nil if a newer or same version of the lib is already present + -- returns empty library object or old library object if upgrade is needed + function LibStub:NewLibrary(major, minor) + assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)") + minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.") + + local oldminor = self.minors[major] + if oldminor and oldminor >= minor then return nil end + self.minors[major], self.libs[major] = minor, self.libs[major] or {} + return self.libs[major], oldminor + end + + -- LibStub:GetLibrary(major, [silent]) + -- major (string) - the major version of the library + -- silent (boolean) - if true, library is optional, silently return nil if its not found + -- + -- throws an error if the library can not be found (except silent is set) + -- returns the library object if found + function LibStub:GetLibrary(major, silent) + if not self.libs[major] and not silent then + error(("Cannot find a library instance of %q."):format(tostring(major)), 2) + end + return self.libs[major], self.minors[major] + end + + -- LibStub:IterateLibraries() + -- + -- Returns an iterator for the currently registered libraries + function LibStub:IterateLibraries() + return pairs(self.libs) + end + + setmetatable(LibStub, { __call = LibStub.GetLibrary }) +end