Thread Tools Display Modes
09/29/14, 11:46 AM   #1
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,912
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.
  Reply With Quote
09/30/14, 07:34 PM   #2
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 648
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).
  Reply With Quote
10/01/14, 05:42 AM   #3
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,912
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.
  Reply With Quote
10/01/14, 06:11 PM   #4
Sasky
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 231
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.

Last edited by Sasky : 10/02/14 at 10:31 PM. Reason: fix to posthook
  Reply With Quote
10/02/14, 07:21 PM   #5
katkat42
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 155
Originally Posted by Sasky View Post
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.)
  Reply With Quote
10/05/14, 05:07 AM   #6
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,912
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.
  Reply With Quote
10/05/14, 04:02 PM   #7
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
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

Last edited by circonian : 10/05/14 at 04:59 PM.
  Reply With Quote
10/05/14, 07:08 PM   #8
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,912
Thx I'll try this one out.

Perhaps it was all about the table.insert function, that I did not use...
  Reply With Quote
10/05/14, 07:49 PM   #9
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
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}
  Reply With Quote

ESOUI » Developer Discussions » Lua/XML Help » Add an array to control.dataEntry.data?

Thread Tools
Display Modes

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