Thread Tools Display Modes
Prev Previous Post   Next Post Next
03-15-09, 07:36 PM   #1
PProvost
A Deviate Faerie Dragon
AddOn Author - Click to view addons
Join Date: Aug 2006
Posts: 13
Proposal - Embeddable oUF Extension Mods

Lately I've been looking in to embedding oUF into my layout to make a self-contained addon. Haste supports this quite well with his metadata trick at the top of each file in oUF:

oUF.lua:
Code:
local parent = debugstack():match[[\AddOns\(.-)\]]
local global = GetAddOnMetadata(parent, 'X-oUF')
assert(global, 'X-oUF needs to be defined in the parent add-on.')


All the files in oUF\elements:

Code:
local parent = debugstack():match[[\AddOns\(.-)\]]
local global = GetAddOnMetadata(parent, 'X-oUF')
assert(global, 'X-oUF needs to be defined in the parent add-on.')
local oUF = _G[global]
This is a slick trick because it lets me embed haste's oUF code inside my addon, and all I have to do is put this in my addon's TOC (assuming I've put oUF in a subfolder called oUFembed):

MyAddon\MyAddon.toc:
Code:
## X-oUF: oUFembed
oUFembed/oUF.xml
There is no required relationship between the two names in used in the TOC, but I tend to keep it that way. The X-oUF metadata tag instructs the embedded oUF to publish itself into the global namespace using the provided name. That is the important bit. The second line simply brings in the embedded oUF files.

Then, at the top of my layout file, I can reference the embedded oUF like this:

MyAddon\layout.lua:
Code:
local oUF = oUFembed
oUFembed = nil
Now anywhere in my code that I reference the symbol oUF, I will get the embedded one. Perfect! I can test against a specific version of oUF and embed it within my addon.

The problem comes when I want to embed an oUF extension written by someone else. Let's use as an example oUF_Banzai by Rabbit. If I wanted to embed it into my addon, it will fail. Oh, it won't crash, but it also won't work.

Why?

Because it makes an assumption that oUF is installed as an independent addon, and that it is published on the global symbol oUF and not oUFembed as I did above.

The first non-comment line of code enforces it like this:

oUF_Banzai.lua:
Code:
if not oUF then return end
I understand why Rabbit did this, but I think with a simple change, we can make it so oUF_Banzai (or any other oUF Extension) can work standalone or embedded. And this requires no change to oUF and should let the extensions continue to work standalone OR embedded.

If the top lines in the oUF_Banzai were as follows instead of the simple check used currently, the embedded version would work:

Proposed oUF_Banzai.lua:
Code:
local parent = debugstack():match[[\AddOns\(.-)\]]
local global = GetAddOnMetadata(parent, 'X-oUF')
local oUF = _G[global] or oUF
assert(oUF, 'oUF not loaded')
Here I take advantage of the scheme used by Haste already in oUF. The only issue, which haste and I have discussed but for which there is no good workaround, is one of path length. If you embed oUF too deeply in your addon, you can hit some kind of a max-path issue in the WoW runtime, and the string returned by debugstack() will not contain a full path.

So what I'd like to propose / ask is that all oUF extension authors add these four lines of code to the top of their extensions. It makes it easier to embed and causes no harm to your existing code.

Question/comments appreciated.
  Reply With Quote
 

WoWInterface » Featured Projects » oUF (Otravi Unit Frames) » Proposal - Embeddable oUF Extension Mods


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off