These forums are in read-only mode. Please see this news post for more information.

New forums can be found here


Go Back   WowAce Forums > Addon Chat > Frameworks
Frameworks Framework Discussion

Reply
 
Thread Tools
Old 05-17-2009   #1
sylvanaar
Legendary Member
 
Join Date: Nov 2006
Posts: 2,876
Default LibStub - Enhancing/Instrumenting

I decided to revisit the "load-on-use" topic since i am playing with ACP today.

For those who don't know what i mean. "Load-on-use" means (for libraries), don't load them until I try to use them.

So that means:

PHP Code:
local function dbg(...) if Prat then Prat:PrintLiteral(...) end end
 
function getOnUseProxy(majorsilent)
    
dbg("proxy LibStub("..major..")")
    return 
setmetatable({}, 
        { 
            
__index=function(tk
                if 
== "__lib" then 
                    dbg
("Loading "..major
                    
local lib LibStub:GetLibrary(majorsilent)
                    
rawset(t"__lib"lib)
                    return 
lib
                end
                
return t.__lib[k
 
                
end 
        
})
end
 
--
--
setmetatable(LibStub, { __call 
--        function(
majorsilent
--            
dbg("LibStub("..major..")")
--            return 
getOnUseProxy(majorsilent
--        
end})
 
ProxyLibStub getOnUseProxy
 
local LDB 
ProxyLibStub("LibDataBroker-1.1")
--
local LDB LibStub("LibDataBroker-1.1"

I created the proxies locally at first, but then i wanted to have libstub always generate them. That broke things is lots of ways. What am i doing wrong? It seems like it should be possible to introduce an additional proxy between the library user and libstub.


And before anyone asks - im doing this to explore how to detect addon dependencies which arent listed in the TOC

Last edited by sylvanaar; 05-17-2009 at 08:23 PM.
sylvanaar is offline   Reply With Quote
Old 05-17-2009   #2
Adirelle
Legendary Member
 
Adirelle's Avatar
 
Join Date: Dec 2006
Posts: 2,403
Default Re: LibStub - Enhancing/Instrumenting

You should better pastey your modified libstub and some errors. This piece of code seems far from a "proxyfying" libstub.
__________________
Author of AdiButtonAuras, AdiBags, Squire2 and several other addons.

Each time you hit your "copy" command with a block of code, think about a way to refactor it so it did what you want without using the "paste" command.
Adirelle is offline   Reply With Quote
Old 05-18-2009   #3
sylvanaar
Legendary Member
 
Join Date: Nov 2006
Posts: 2,876
Default Re: LibStub - Enhancing/Instrumenting

Quote:
Originally Posted by Adirelle View Post
You should better pastey your modified libstub and some errors. This piece of code seems far from a "proxyfying" libstub.

It does, You just replace libstubs metatable __call, and all LibStub("library") calls get proxied.

That code is commented out in my example.
sylvanaar is offline   Reply With Quote
Old 05-18-2009   #4
OrionShock
Legendary Member
 
OrionShock's Avatar
 
Join Date: May 2006
Posts: 3,787
Default Re: LibStub - Enhancing/Instrumenting

have you tried to implement this locally? and does it work?
__________________
Author of GuildCraft, SickOfClickingDailies, CursorCooldown, Broken_LFD
WoWAce Addon List WoWInterface Addon List

"I was there in the beginning... and things were very different back then" --An Echo from a time before.
OrionShock is offline   Reply With Quote
Old 05-18-2009   #5
sylvanaar
Legendary Member
 
Join Date: Nov 2006
Posts: 2,876
Default Re: LibStub - Enhancing/Instrumenting

Quote:
Originally Posted by OrionShock View Post
have you tried to implement this locally? and does it work?

Yes. Thats where the code comes from.

I get wierd behavior when i make the global replacement. Sometimes addons dont load, or they load but thier options dont.

All i am doing is replacing the __call metamethod with the function that returns my proxy table.

Last edited by sylvanaar; 05-18-2009 at 08:26 AM.
sylvanaar is offline   Reply With Quote
Old 05-18-2009   #6
jerry
Amazing Member
 
Join Date: Jul 2006
Posts: 1,461
Default Re: LibStub - Enhancing/Instrumenting

Doing :
Code:
local real_newindex = function (self, key, value)
	getmetatable(self).__index[key] = value
end

local first_index = function (self, key)
	local mt = getmetatable(self)
	mt.__index = LibStub:GetLibrary(mt.major, mt.silent)
	mt.__newindex = real_newindex
	mt.major = nil
	mt.silent = nil
	return self[key]
end

local function first_newindex(self, key, value)
	local mt = getmetatable(self)
	mt.__index(self, key) -- this calls first_index and replaces __index
	mt.__index[key] = value
end

function getOnUseProxy(major, silent)
	return setmetatable({}, { __index = first_index, __newindex = first_newindex, major = major, silent = silent })
end
Should make libs using "__lib" a non-issue.

Setting __newindex in the metatable is a good idea, but it probably wont correct all issues. Your proxy is breaking assertions like this:
Code:
function MyLib:foo()
	assert(self == MyLib)
end
which is something that's quite easy to fall for non-embedded libs. It's even worse if the code is :
Code:
local MyLib = MyLib
function MyLib:foo()
	assert(self == MyLib)
end
jerry is offline   Reply With Quote
Old 05-18-2009   #7
sylvanaar
Legendary Member
 
Join Date: Nov 2006
Posts: 2,876
Default Re: LibStub - Enhancing/Instrumenting

Quote:
Originally Posted by jerry View Post
Doing :
Code:
local real_newindex = function (self, key, value)
    getmetatable(self).__index[key] = value
end
 
local first_index = function (self, key)
    local mt = getmetatable(self)
    mt.__index = LibStub:GetLibrary(mt.major, mt.silent)
    mt.__newindex = real_newindex
    mt.major = nil
    mt.silent = nil
    return self[key]
end
 
local function first_newindex(self, key, value)
    local mt = getmetatable(self)
    mt.__index(self, key) -- this calls first_index and replaces __index
    mt.__index[key] = value
end
 
function getOnUseProxy(major, silent)
    return setmetatable({}, { __index = first_index, __newindex = first_newindex, major = major, silent = silent })
end
Should make libs using "__lib" a non-issue.

Setting __newindex in the metatable is a good idea, but it probably wont correct all issues. Your proxy is breaking assertions like this:
Code:
function MyLib:foo()
    assert(self == MyLib)
end
which is something that's quite easy to fall for non-embedded libs. It's even worse if the code is :
Code:
local MyLib = MyLib
function MyLib:foo()
    assert(self == MyLib)
end
Thanks alot, thats a really helpful explaination.
sylvanaar is offline   Reply With Quote
Old 05-18-2009   #8
Adirelle
Legendary Member
 
Adirelle's Avatar
 
Join Date: Dec 2006
Posts: 2,403
Default Re: LibStub - Enhancing/Instrumenting

Quote:
Originally Posted by sylvanaar View Post
It does, You just replace libstubs metatable __call, and all LibStub("library") calls get proxied.

That code is commented out in my example.
What I meant is: you told us the example works and when I read the example, I'd say it might work. If the whole thing does not work, you should show us the whole thing and not the example that works. As Jerry pointed out, there are other methods to support and I could not tell if you added proper support from your example.

Jerry, isn't there some "metamethods" to support == ?
__________________
Author of AdiButtonAuras, AdiBags, Squire2 and several other addons.

Each time you hit your "copy" command with a block of code, think about a way to refactor it so it did what you want without using the "paste" command.

Last edited by Adirelle; 05-18-2009 at 08:59 AM.
Adirelle is offline   Reply With Quote
Old 05-18-2009   #9
jerry
Amazing Member
 
Join Date: Jul 2006
Posts: 1,461
Default Re: LibStub - Enhancing/Instrumenting

Quote:
Originally Posted by Adirelle View Post
Jerry, isn't there some "metamethods" to support == ?
Yes, there is. But that won't help as "MyLib == self" is only a way to represent the assertion that is done in the programmer's mind, not as real code.

Code:
local MyLib = LibStub"foo"

function MyLib:foo()
  self.bar = "test"
  return function () print(MyLib.bar) end
end
The code above makes the assertion.
jerry is offline   Reply With Quote
Old 05-18-2009   #10
sylvanaar
Legendary Member
 
Join Date: Nov 2006
Posts: 2,876
Default Re: LibStub - Enhancing/Instrumenting

Ok, one main bug is that my _call should have been
Code:
 
function(self, major, silent)
I think that was what was wrong with the code i had originally.

the use:

local LIB = LibStub("Foo")

works now that i have fixed my __call so it passes the right self.

Still though - this breaks alot of addons - especially auctioneer.

However - it does work alot better than it did.

It's what you say Jerry. Essentially we want to be able to do

Code:
MyLib:foo()
 
and have it be  
 
MyLib.__index["foo"](MyLib.__index)
 
vs
 
MyLib.__index["foo"](MyLib)

Last edited by sylvanaar; 05-18-2009 at 12:18 PM.
sylvanaar is offline   Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

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

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

Forum Jump


All times are GMT. The time now is 06:09 AM.