Thread Tools Display Modes
01/04/16, 03:10 PM   #1
prasoc
 
prasoc's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2016
Posts: 24
Overwriting gamepad initializelist function

Hi, I am looking to replace the gamepad's ZO_GamepadTradingHouse_BrowseResults:InitializeList function, so that I can get rid of the original "ItemListRow" (added via the dataType table) with my own, a custom one. However, I keep trying to set a nil value from trying to overwrite the function like this:

Code:
local original_results_init = ZO_GamepadTradingHouse_BrowseResults.InitializeList
function ZO_GamepadTradingHouse_BrowseResults:InitializeList()
	original_results_init(self)
	d("[NUI] Calling new InitializeList")
end
giving the error:

Code:
user:/AddOns/HelloWorldSkeleton/HelloWorldSkeleton.lua:257: attempt to index a nil value
which is the first line "local original_results_init = ZO_GamepadTradingHouse_BrowseResults.InitializeList".

How do I overwrite this function? It's mystifying me!

Edit: Can anyone also tell me the difference between "GAMEPAD_TRADING_HOUSE_BROWSE_RESULTS" and "ZO_GamepadTradingHouse_BrowseResults"?
  Reply With Quote
01/04/16, 04:03 PM   #2
Wandamey
Guest
Posts: n/a
Originally Posted by prasoc View Post
Hi, I am looking to replace the gamepad's ZO_GamepadTradingHouse_BrowseResults:InitializeList function, so that I can get rid of the original "ItemListRow" (added via the dataType table) with my own, a custom one. However, I keep trying to set a nil value from trying to overwrite the function like this:

Code:
local original_results_init = ZO_GamepadTradingHouse_BrowseResults.InitializeList
function ZO_GamepadTradingHouse_BrowseResults:InitializeList()
	original_results_init(self)
	d("[NUI] Calling new InitializeList")
end
giving the error:

Code:
user:/AddOns/HelloWorldSkeleton/HelloWorldSkeleton.lua:257: attempt to index a nil value
which is the first line "local original_results_init = ZO_GamepadTradingHouse_BrowseResults.InitializeList".

How do I overwrite this function? It's mystifying me!

Edit: Can anyone also tell me the difference between "GAMEPAD_TRADING_HOUSE_BROWSE_RESULTS" and "ZO_GamepadTradingHouse_BrowseResults"?


on the form it would be more something like that instead of re-declaring the existing function :
Code:
local original_results_init = ZO_GamepadTradingHouse_BrowseResults.InitializeList
ZO_GamepadTradingHouse_BrowseResults.InitializeList = function(self,...)
	original_results_init(self,...)
	d("[NUI] Calling new InitializeList")
end
just ZO_Something is (always?) a control (aka UI element) whereas CAPS_SOMETHING is a global value (number in principle, they are referenced in the page "Globals" in the wiki, it can help retrieve some arguments to look there sometimes)

Edit : but seing the error, it seems that there is no function InitializeList attached to that object (ZO_GamepadTradingHouse_BrowseResults) so you probably will have the same error.
I think the addon zgoo would help but it is a bit tricky to use in gamepad mode. There must be a topic or two about that around november (Orsinum release and a little before with PTS)

Edit 2 : found it : http://www.esoui.com/forums/showthread.php?t=5262
that post might help for coding for the Gamepad UI.

Last edited by Wandamey : 01/04/16 at 04:25 PM.
  Reply With Quote
01/04/16, 04:28 PM   #3
prasoc
 
prasoc's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2016
Posts: 24
That make sense, redefining an existing function would have not been what I wanted, but you're right that "ZO_GamepadTradingHouse_BrowseResults" doesn't exist, but located here: http://esodata.uesp.net/100013/src/i...ad.lua.html#62 it seemingly *does* exist. There is a difference between the LUA code and my addon's code? is my addon running before ZOS's? I didn't think that was possible!

edit: thanks for the Gamepad UI thread, I'll have a thorough read of the API to try to make sense of it. Quite a large chunk to bite off for my first addon!
  Reply With Quote
01/04/16, 04:40 PM   #4
Wandamey
Guest
Posts: n/a
Basically what you are doing is that :


Code:
local MyFunctionCopy = TheFunctionToEdit

-- then you redefine the original function to include your stuff. you use the copy instead to avoid some looping with the function calling itself I guess

TheFunctionToEdit = function(self,...)
  StuffIWannaDoBefore()
  MyFunctionCopy(self,...)   --use the same args than the true original copy
  StuffIwannaDoAfter()
end
For what control is able to use what function, as I said zgoo will help a lot.
I've had a hard time with that (still have) and i'm still at the trial and errors stage on that kind of stuff. But other people will help. In the meantime, just try to make that /zgoo mouse work, it'll keep you very busy
  Reply With Quote
01/04/16, 04:40 PM   #5
haggen
 
haggen's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2015
Posts: 137
ZO_GamepadTradingHouse_BrowseResults does exist, but it's local as you can see here:
http://esodata.uesp.net/100013/src/i...ad.lua.html#16

`local` means that variable is only accessible inside that scope.

You still can achieve what you're looking for by changing the instance instead of the class, like this:

Code:
local ZO_GamepadTradingHouse_BrowseResults_InitializeList = GAMEPAD_TRADING_HOUSE_BROWSE_RESULTS.InitializeList
function GAMEPAD_TRADING_HOUSE_BROWSE_RESULTS:InitializeList()
    -- ...
end
I should say it works only because ZO uses a singleton, meaning one global instance. If you were to change this function for all instances, since the class is local we'd have a problem. :P
  Reply With Quote
01/04/16, 05:13 PM   #6
prasoc
 
prasoc's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2016
Posts: 24
Thanks for the information, it does seem to be a local variable, but because it's a singleton actually makes it possible to override (thank god!). So I tried the following, but I can't seem to get ANY response; do I have to pass the function parameter #1 as "self"? This code just does nothing, doesn't seem to be executed:

Code:
	local ZO_GamepadTradingHouse_BrowseResults_InitializeList = GAMEPAD_TRADING_HOUSE_BROWSE_RESULTS.InitializeList

	function GAMEPAD_TRADING_HOUSE_BROWSE_RESULTS:InitializeList()
	   	--ZO_GamepadTradingHouse_BrowseResults_InitializeList()
	   	d("Hello!")
	end
It's located after my Initialize method, outside of the scope of my program (into the global scope?)
  Reply With Quote
01/04/16, 06:16 PM   #7
haggen
 
haggen's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2015
Posts: 137
Maybe the function has already been called and won't be called again, let me check it.

Edit:

Yes that's it.

ZO_GamepadTradingHouse_BrowseResults inherits from ZO_GamepadTradingHouse_SortableItemList, which inherits from ZO_GamepadTradingHouse_BaseList and here you see InitializeList being called by Initialize:

http://esodata.uesp.net/100013/src/i...d.lua.html#144

So when you override this function it's been already called and nothing can be done about that.

But, there are other ways to inject the changes you want. What in the InitializeList function you'd like to change?

I've done something similar with one of my add-ons, can't remember which now.

Edit, again:

I just reread your post. Could it be this line?
http://esodata.uesp.net/100013/src/i...ad.lua.html#62

If that's the case, you can't prevent that line from running, but you could undo what it does, know what I mean?

Edit, three times:

GetList function:
http://esodata.uesp.net/100013/src/l...t.lua.html#111

...and itemList is set in the same file, line 59:
http://esodata.uesp.net/100013/src/l...st.lua.html#59

...and ZO_GamepadVerticalParametricScrollList is a subclass of ZO_ParametricScrollList:
http://esodata.uesp.net/100010/src/c...es.lua.html#30

Now we have what AddDataTemplate does:
http://esodata.uesp.net/100013/src/l...st.lua.html#99

I think you could mess with self.dataTypes since that's where the parameters for your item row comes from.

The key used in BrowserResults' InitializeList was "ZO_TradingHouse_ItemListRow_Gamepad", the way I see you have two options:

1. You could change the table in self.dataTypes["ZO_TradingHouse_ItemListRow_Gamepad"], or;

2. You could remove it and create your own entry, you just have to see what else makes reference to the key "ZO_TradingHouse_ItemListRow_Gamepad" and patch that as well.

Last edited by haggen : 01/04/16 at 06:43 PM.
  Reply With Quote
01/04/16, 06:20 PM   #8
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Originally Posted by prasoc View Post
Thanks for the information, it does seem to be a local variable, but because it's a singleton actually makes it possible to override (thank god!). So I tried the following, but I can't seem to get ANY response; do I have to pass the function parameter #1 as "self"?
Yes, you have to pass all arguments you receive. `X:func(...)` is just syntax sugar, it saves typing but is effectively equivalent to `X.func(self, ...)`
  Reply With Quote
01/05/16, 08:26 AM   #9
prasoc
 
prasoc's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2016
Posts: 24
You are all very helpful, special thank you to haagen for the in-depth code analysis. Finally got the old dataType entry out, and put my own custom version in!

Code:
	GAMEPAD_TRADING_HOUSE_BROWSE_RESULTS:GetList().dataTypes["ZO_TradingHouse_ItemListRow_Gamepad"]=nil

	local dataTypeInfo = {
            pool = ZO_ControlPool:New("NewUI_ItemListRow_Gamepad", GAMEPAD_TRADING_HOUSE_BROWSE_RESULTS:GetList().scrollControl, "NewUI_ItemListRow_Gamepad"),
            setupFunction = SetupListing,
            parametricFunction = ZO_GamepadMenuEntryTemplateParametricListFunction,
            equalityFunction = DefaultEqualityFunction,
            hasHeader = false,
        }
	GAMEPAD_TRADING_HOUSE_BROWSE_RESULTS:GetList().dataTypes["NewUI_ItemListRow_Gamepad"] = dataTypeInfo
It works after overwriting the other function "AddEntryToList" which needed to be updated with the new template name, too.

I had an issue with "too many anchors processed", but in my XML file, instead of copy-pasting "ZO_TradingHouse_ItemListRow_Gamepad" and renaming it, I actually inherited it and am adding my own custom labels and text to that. It takes a little longer to load the guild store, but it seems to be working correctly

Thanks everyone, this has been enlightening!
  Reply With Quote
01/05/16, 08:33 AM   #10
haggen
 
haggen's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2015
Posts: 137
Originally Posted by prasoc View Post
You are all very helpful, special thank you to haagen for the in-depth code analysis. Finally got the old dataType entry out, and put my own custom version in!

Code:
	GAMEPAD_TRADING_HOUSE_BROWSE_RESULTS:GetList().dataTypes["ZO_TradingHouse_ItemListRow_Gamepad"]=nil

	local dataTypeInfo = {
            pool = ZO_ControlPool:New("NewUI_ItemListRow_Gamepad", GAMEPAD_TRADING_HOUSE_BROWSE_RESULTS:GetList().scrollControl, "NewUI_ItemListRow_Gamepad"),
            setupFunction = SetupListing,
            parametricFunction = ZO_GamepadMenuEntryTemplateParametricListFunction,
            equalityFunction = DefaultEqualityFunction,
            hasHeader = false,
        }
	GAMEPAD_TRADING_HOUSE_BROWSE_RESULTS:GetList().dataTypes["NewUI_ItemListRow_Gamepad"] = dataTypeInfo
It works after overwriting the other function "AddEntryToList" which needed to be updated with the new template name, too.

I had an issue with "too many anchors processed", but in my XML file, instead of copy-pasting "ZO_TradingHouse_ItemListRow_Gamepad" and renaming it, I actually inherited it and am adding my own custom labels and text to that. It takes a little longer to load the guild store, but it seems to be working correctly

Thanks everyone, this has been enlightening!
You're welcome. And don't worry about the performance right now, just get it done, then do it better, and finally do it faster.
  Reply With Quote

ESOUI » Developer Discussions » Lua/XML Help » Overwriting gamepad initializelist function


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