Superloading and module-level local variables

All development conversation and discussion takes place here

Moderator: Moderator

Post Reply
Message
Author
StarWeaver
Yeek
Posts: 12
Joined: Fri Mar 07, 2014 9:20 am

Superloading and module-level local variables

#1 Post by StarWeaver »

Soo, I was just making a modlet to tweak the display of the chat/gamelogs, which requires changing some functions in mod/class/uiset/Minimalist.lua ... near the top of that file is:

Code: Select all

-- require require etc
module(..., package.seeall, class.inherit(UISet, TooltipsData))

local move_handle = {core.display.loadImage("/data/gfx/ui/move_handle.png"):glTexture()}

local frames_colors = {
	ok = {0.3, 0.6, 0.3},
	sustain = {0.6, 0.6, 0},
	cooldown = {0.6, 0, 0},
	disabled = {0.65, 0.65, 0.65},
}

-- Load the various shaders used to display resources
air_c = {0x92/255, 0xe5, 0xe8}
-- ...
The functions I'm overriding reference move_handle, and there appears to be no way to get at the original copy of that from inside the superload file; even an explicit

Code: Select all

local _M = loadPrevious(...)
local move_handle = _M.move_handle
dosen't work.

The best I can come up with is recreating the object:

Code: Select all

local _M = loadPrevious(...)
local move_handle = {core.display.loadImage("/data/gfx/ui/move_handle.png"):glTexture()}
Which I would guess is probably fine for this particular use, but seems like it would create the potential for unnecessary cross-version disharmony if any of these module locals are changed in the future.

Marson
Uruivellas
Posts: 645
Joined: Thu Jan 16, 2014 4:56 am

Re: Superloading and module-level local variables

#2 Post by Marson »

Don't forget, with superload's loadPrevious() you aren't changing the function, you are just adding code to the beginning or the end. If you want to change the internal code of the function, you have to overwrite it. You can do that with overload—or you can use superload, but instead of loadPrevious(), you copy the function over and make the changes you need.

Doctornull
Sher'Tul Godslayer
Posts: 2402
Joined: Tue Jun 18, 2013 10:46 pm
Location: Ambush!

Re: Superloading and module-level local variables

#3 Post by Doctornull »

StarWeaver wrote:The best I can come up with is recreating the object:
(...)
Which I would guess is probably fine for this particular use, but seems like it would create the potential for unnecessary cross-version disharmony if any of these module locals are changed in the future.
Yep. File-scope 'local' variables are not visible outside that file itself. With superloading what you can do is gain access to the structures created as file-scope globals via '_M:...', but not file-scope locals.

@Marson - one can indeed augment or replace structures and functions, but not all of them.
Check out my addons: Nullpack (classes), Null Tweaks (items & talents), and New Gems fork.

Marson
Uruivellas
Posts: 645
Joined: Thu Jan 16, 2014 4:56 am

Re: Superloading and module-level local variables

#4 Post by Marson »

I didn't phrase it correctly, but this is what I meant:

Let's say example.lua contains:

Code: Select all

function _M:strip(s)
    s = s:gsub("e", "")
    return s
end
If you create a /superload/example.lua:

Code: Select all

local _M = loadPrevious(...)
local base_strip = _M.strip

function _M:strip(s)
    -- you can put code here to modify "s"
    local base_return = base_strip(s)
    -- or you can put code here to modify "base_return"
    return (base_return)
end

return _M
but either way, all "e" characters from the initial input will be stripped out. If you want that to be "i" instead, you will need to copy the entire function over and change it that way.

Code: Select all

local _M = loadPrevious(...)

function _M:strip(s)
    s = s:gsub("i", "")
    return s
end

return _M
which is what I think people are calling superoverload.

darkgod
Master of Eyal
Posts: 10750
Joined: Wed Jul 24, 2002 9:26 pm
Location: Angolwen
Contact:

Re: Superloading and module-level local variables

#5 Post by darkgod »

Accessing the local variables is possible if you can run inside a function that executes in its lexical scope.
To cut short the explanation you are lucky, you can!

You must hook on "UISet:Minimalist:Load" like that:

Code: Select all

class:bindHook("UISet:Minimalist:Load", function(self, data)
	local i = 1
	while true do
		local kk, vv = debug.getlocal(3, i)
		if not kk then break end
		if kk == "move_handle" then
			-- here vv is the value of the local "move_handle"
		end
		i = i + 1
	end
end
[tome] joylove: You can't just release an expansion like one would release a Kraken XD
--
[tome] phantomfrettchen: your ability not to tease anyone is simply stunning ;)

Doctornull
Sher'Tul Godslayer
Posts: 2402
Joined: Tue Jun 18, 2013 10:46 pm
Location: Ambush!

Re: Superloading and module-level local variables

#6 Post by Doctornull »

Marson wrote:which is what I think people are calling superoverload.
Hmm, I've never heard that term before.
darkgod wrote:Accessing the local variables is possible if you can run inside a function that executes in its lexical scope.
To cut short the explanation you are lucky, you can!
Holy cow that's awesome.
Check out my addons: Nullpack (classes), Null Tweaks (items & talents), and New Gems fork.

Marson
Uruivellas
Posts: 645
Joined: Thu Jan 16, 2014 4:56 am

Re: Superloading and module-level local variables

#7 Post by Marson »

Ooh handy. Thanks DG!

darkgod
Master of Eyal
Posts: 10750
Joined: Wed Jul 24, 2002 9:26 pm
Location: Angolwen
Contact:

Re: Superloading and module-level local variables

#8 Post by darkgod »

Oh and a warning, it uses the debug API which as you see is not exactly explicit; and it's also very slow.
Using it for init is fine, jsut dont do it 1000 times every frame :)
[tome] joylove: You can't just release an expansion like one would release a Kraken XD
--
[tome] phantomfrettchen: your ability not to tease anyone is simply stunning ;)

StarWeaver
Yeek
Posts: 12
Joined: Fri Mar 07, 2014 9:20 am

Re: Superloading and module-level local variables

#9 Post by StarWeaver »

Marson - the superload system dosen't actually do the 'before and after original function' thing for you, that's why the examples explicitly save the old function to something else and then call it; I chose not to do that right off the bat :3.

DG - That's interesting. It really seems that for superload to work as intended in all cases it should forward the module locals to the new file's namespace as well as the globals -- I mean, ideally, the execution environment in the superloaded file should be the same as that of the original file, right?

If that's not possible, how about hacking the interpreter to dump those locals into a _L object for the superload file?

darkgod
Master of Eyal
Posts: 10750
Joined: Wed Jul 24, 2002 9:26 pm
Location: Angolwen
Contact:

Re: Superloading and module-level local variables

#10 Post by darkgod »

No, it's extremely rare that there are locals and even more locals of interrest
[tome] joylove: You can't just release an expansion like one would release a Kraken XD
--
[tome] phantomfrettchen: your ability not to tease anyone is simply stunning ;)

HousePet
Perspiring Physicist
Posts: 6215
Joined: Sun Sep 09, 2012 7:43 am

Re: Superloading and module-level local variables

#11 Post by HousePet »

darkgod wrote:No, it's extremely rare that there are locals and even more locals of interrest
Lies!
Try superloading anything into the FoV stuff.
My feedback meter decays into coding. Give me feedback and I make mods.

Nagyhal
Wyrmic
Posts: 282
Joined: Tue Feb 15, 2011 12:01 am

Re: Superloading and module-level local variables

#12 Post by Nagyhal »

darkgod wrote: Accessing the local variables is possible if you can run inside a function that executes in its lexical scope.
To cut short the explanation you are lucky, you can!
This is so awesome it:

1. Deserves a bump
2. Is going in my one-day-to-be-released grimoire of DG Lua trickery. It's getting to be quite a collection!

Post Reply