ESOUI

ESOUI (https://www.esoui.com/forums/index.php)
-   Lua/XML Help (https://www.esoui.com/forums/forumdisplay.php?f=175)
-   -   Add an array to control.dataEntry.data? (https://www.esoui.com/forums/showthread.php?t=2291)

Baertram 09/29/14 11:46 AM

Add an array to control.dataEntry.data?
 
Hey,

is it possible to add an array to the dataEntry.data node of a control (e.g. an inventory item)?

I've seen ResearchAssistant adding information there. And i've tried to do it the same way.
But I'm not able to add information that are deeper then 1 value.

Let's say this would work:
control.dataEntry.data.newvalue = "Helo World"

But this doesn't work:
local ar = {}
ar[1] = "Hello World"
ar[2] = "Test"
control.dataEntry.data.newvalue = ar

It isn't even possible do add information with a depth of 2:
control.dataEntry.data.newvalue.here = "Hello World"

Any1 got an idea how to do this properly?

Thanks.

Seerah 09/30/14 07:34 PM

Your second example should work fine. Your third example won't because you're treating the newvalue key as a table (adding a key to it), but it hasn't been defined as a table yet (so you can't add a key to it).

Baertram 10/01/14 05:42 AM

But the 2nd one did not work. It was always telling me that the value is nil.

Only adding flat data directly to the dataEntry.data worked for me.

Sasky 10/01/14 06:11 PM

What are you trying to do?

Actually putting something into the dataControl.data doesn't do anything by itself. If you look, the 'researchAssistant' field is not actually read out. The actual controls are created alongside it within the AddResearchIndicatorToSlot function. As such, I don't think there's really a restriction on subtables.

The NIL indicator you get seems to indicate that whatever you put there isn't sticking around for when you need it. Depending on the ZOS control, the dataControl.data can be overwritten for a list refresh or a sort. As such, you'd need to hook into the callback creation of the dataControl and make sure that for each object created, your structure is there. researchAssistant does this with:
Lua Code:
  1. local hookedFunctions = DECONSTRUCTION.dataTypes[1].setupCallback
  2. DECONSTRUCTION.dataTypes[1].setupCallback = function(rowControl, slot)
  3.     hookedFunctions(rowControl, slot)
  4.     AddResearchIndicatorToSlot(rowControl)
  5. end
(which is essentially doing a posthook on the setupCallback). Before data can be added to one of the ZOS lists, each dataType must be registered with (among other things) a callback. That callback is created whenever an item is to be added to make sure the dataControl.data is setup properly.

If you need something to stick around between those refreshes, put it in a local table for your addon.

katkat42 10/02/14 07:21 PM

Quote:

Originally Posted by Sasky (Post 12440)
As such, you'd need to hook into the callback creation of the dataControl and make sure that for each object created, your structure is there. researchAssistant does this with:
Lua Code:
  1. local hookedFunctions = DECONSTRUCTION.dataTypes[1].setupCallback
  2. DECONSTRUCTION.dataTypes[1].setupCallback = function(rowControl, slot)
  3.     hookedFunctions(rowControl, slot)
  4.     AddResearchIndicatorToSlot(rowControl)
  5. end
(which is essentially doing ZO_PreHook on the setupCallback).

Except that this is actually a post-hook, since the new function gets run after the original, not before. (I suspect that if you pre-hooked the setupCallback, your data would immediately get clobbered, like it is now.)

Baertram 10/05/14 05:07 AM

Thx for the comments.

The addon we are talking about is FCOItemSaver.
You are able to mark some items with icons and hide those items by filters, to prevent deconstruction/destroying/selling/trading of these items.

I'm trying to populate the information which item of the inventories was marked with which icon/filter to the dataEntry.data tree.

I know that the info must be added with the post-hook. Otherwise the data of the item isn't there and couldn't be used properly.
I'm doing it exactly the same like katkat42 within ResearchAssistant's method "AddResearchIndicatorToSlot" and I'm using the post-hook from the deconstruction oanel, and the normal inventory.

It is working fine, if I only add one entry (like ResearchAssistant does).
But I wanted to add an entry "FCO", another sub-entry "ItemSaver" and then an arry "Marked {}" with the information which mark has been set for the current item.

The current version of FCOItemSaver got 8 new entries "FCOItemSaverMarked1" to "FCOItemSaverMarked8", because the sub-entries and the array weren't working (always the error with nil).

If someone got the time to review the code, or test it for themselves: Please feel free to do so.
But it is not urgent! I've added some global functions to the addon so you are able to use them, instead of crawling the dataEntry.data trees.

circonian 10/05/14 04:02 PM

Baertram, do you mean something like this:

Since you said you wanted Marked to be a table I'm guessing items can have more than one mark?
So you probably want something like this:


NEW Function: to check and see if an item is already marked, don't want to mark an item twice:
Lua Code:
  1. -- Function used to see if the item has already been marked (dont want duplicate marks in your table) --
  2. local function FCOIsItemMarked(control, mark)
  3.     local bIsMarked = false
  4.    
  5.     if ((control.dataEntry.data.FCO == nil) or (control.dataEntry.data.FCO.ItemSaver == nil)
  6.     or (control.dataEntry.data.FCO.ItemSaver.Marked == nil)) then return bIsMarked end
  7.    
  8.     for k,v in pairs(control.dataEntry.data.FCO.ItemSaver.Marked) do
  9.         if v == mark then
  10.             bIsMarked = true
  11.         end
  12.     end
  13.     return bIsMarked
  14. end

Altered Function: FCOItemSaver_AddInfoToData(control)
  1. checks to see if the control.data.dataEntry exists
  2. checks to see if your myItemInstanceId exists
  3. loops through your marked Indices from 1 to gFCONumFilterIcons
  4. checks to see if the myItemInstanceId exists in your markedItems[markedIndex] table
  5. checks to see if the item control.dataEntry.data.FCO.ItemSaver.Marked table already has the mark in it to avoid duplicates
  6. checks to see of the tables exist, if not it creates them
  7. last, inserts the mark into the table
Lua Code:
  1. local function FCOItemSaver_AddInfoToData(control)
  2.     if ((control ~= nil) and (control.dataEntry ~= nil) and (control.dataEntry.data ~= nil)) then
  3.     local myItemInstanceId = MyGetItemInstanceId(control)
  4.         if (myItemInstanceId ~= nil) then
  5.             debugMessage("[FCOItemSaver_AddInfoToData] ItemIstanceId:" .. tostring(myItemInstanceId))
  6.             --Check if the current item is marked with any of the marker icons
  7.             for markedIndex=1, gFCONumFilterIcons, 1 do
  8.                 if markedItems[markedIndex][myItemInstanceId] and (not FCOIsItemMarked(control, "Mark"..markedIndex))then
  9.                     --if the table doesn't exist create it --
  10.                     if control.dataEntry.data.FCO == nil then
  11.                         control.dataEntry.data.FCO = {}
  12.                         control.dataEntry.data.FCO.ItemSaver = {}
  13.                         control.dataEntry.data.FCO.ItemSaver.Marked = {}
  14.                     end
  15.                            
  16.                     table.insert(control.dataEntry.data.FCO.ItemSaver.Marked, "Mark"..markedIndex)
  17.                 end
  18.             end
  19.         end
  20.     end
  21. end

Baertram 10/05/14 07:08 PM

Thx I'll try this one out.

Perhaps it was all about the table.insert function, that I did not use...

circonian 10/05/14 07:49 PM

It could also be done without table.insert, we could assign a specific key refering to which mark it is.
Lua Code:
  1. control.dataEntry.data.FCO.ItemSaver.Marked = {[markedIndex] = true}

But then when you loop through it later to check marks you'de have to remember that there may be keys missing. For example if an item only had the 1st & 3rd mark:
Lua Code:
  1. Marked = {
  2. [1] = ...
  3. [3] = ...
  4. }
With the 2nd key missing. So you couldn't use
Lua Code:
  1. for k,v in pairs(control.dataEntry.data.FCO.ItemSaver.Marked) do
  2. ...
  3. end
Because the pairs loop would stop at the first nil key [2].

table.inert just makes it easier by ensuring the none of the keys for the table are missing so we dont have to worry about it later when searching through the table (but not the only way to do it).

It could also be done like this, if you only wanted to add 1 marker:
Lua Code:
  1. control.dataEntry.data.FCO.ItemSaver.Marked = "Mark"..markedIndex

or if you wanted to name them
Lua Code:
  1. control.dataEntry.data.FCO.ItemSaver.Marked = {["ReservedMark"] = true}


All times are GMT -6. The time now is 01:02 PM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2014 - 2022 MMOUI