ESOUI

ESOUI (https://www.esoui.com/forums/index.php)
-   Lua/XML Help (https://www.esoui.com/forums/forumdisplay.php?f=175)
-   -   SavedVariables Problem...Any Ideas? (https://www.esoui.com/forums/showthread.php?t=4470)

circonian 03/22/15 03:39 AM

SavedVariables Problem...Any Ideas?
 
Anyone have any ideas on this.

Whenever the function (below) runs and adds the scriptName & script to the scripts table...and then I try to reload the UI (or just wait long enough) the game crashes & the saved variable file is over 1 gig.
That is the only line of code that adds anything to the saved variables file.

Code Paste here, Line 392 is the problem: http://pastebin.com/sjnG4v9d

Or if you want/need to see the whole addon you can find it here: Drop Box Zip File

CLICK4INFO.sv -- Is my saved variables
CLICK4INFO.sv.scripts -- Is just an empty table to start out.


Lua Code:
  1. function Click4Info_AddScript(self)
  2.     local scriptName = CLICK4INFO.nameEditBox:GetText()
  3.     local script = CLICK4INFO.scriptEditBox:GetText()
  4.    
  5.     if not scriptName or scriptName == "" then return end
  6.     if not script or script == "" then return end
  7.    
  8.     -- This Msg only prints once
  9.     -- so its not infinitely looping this function
  10.     debugMsg("Adding Script")
  11.  
  12.     -- check to see if it already exists
  13.     if not DoesScriptNameExist(scriptName) then
  14.    
  15.         -- This line is the problem:
  16.         table.insert(CLICK4INFO.sv.scripts, {["scriptName"] = scriptName, ["script"] = script})
  17.     end
  18. end

votan 03/22/15 06:04 AM

I think the problem is the DoesScriptNameExist function.
CLICK4INFO.sv.scripts is a indexed table (using table.insert)

The function should be like this:
Lua Code:
  1. local function DoesScriptNameExist(scriptName)
  2.     local scripts = CLICK4INFO.sv.scripts
  3.     for _, script in ipairs(scripts) do
  4.         if script.scriptName == scriptName then
  5.             return true
  6.         end
  7.     end
  8.     return false
  9. end

CU

Garkin 03/22/15 06:36 AM

Quote:

Originally Posted by votan (Post 19831)
I think the problem is the DoesScriptNameExist function.
CLICK4INFO.sv.scripts is a indexed table (using table.insert)

The function should be like this:
Lua Code:
  1. local function DoesScriptNameExist(scriptName)
  2.     local scripts = CLICK4INFO.sv.scripts
  3.     for _, script in ipairs(scripts) do
  4.         if script.scriptName == scriptName then
  5.             return true
  6.         end
  7.     end
  8.     return false
  9. end

CU

Or you can replace table.insert and remove whole DoesScriptNameExist function:

Lua Code:
  1. function Click4Info_AddScript(self)
  2.     local scriptName = CLICK4INFO.nameEditBox:GetText()
  3.     local script = CLICK4INFO.scriptEditBox:GetText()
  4.  
  5.     if not script or script == "" then return end
  6.     if not scriptName or scriptName == "" then
  7.         scriptName = "New Script"
  8.     end
  9.  
  10.     debugMsg("Adding Script")
  11.  
  12.     local scripts = CLICK4INFO.sv.scripts
  13.     local uniqueScriptName = scriptName
  14.     local counter = 1
  15.  
  16.     while scripts[uniqueScriptName] ~= nil do
  17.         uniqueScriptName = ("%s (%d)"):format(scriptName, counter)
  18.         counter = counter + 1
  19.     end
  20.  
  21.     scripts[uniqueScriptName] = script
  22. end

circonian 03/22/15 02:13 PM

Quote:

Originally Posted by votan (Post 19831)
I think the problem is the DoesScriptNameExist function.
CLICK4INFO.sv.scripts is a indexed table (using table.insert)

The function should be like this:
Lua Code:
  1. local function DoesScriptNameExist(scriptName)
  2.     local scripts = CLICK4INFO.sv.scripts
  3.     for _, script in ipairs(scripts) do
  4.         if script.scriptName == scriptName then
  5.             return true
  6.         end
  7.     end
  8.     return false
  9. end

CU

Oh yeah I forgot I changed how I was saving the information. I was doing it like Garkin suggested below and forgot to fix that function.

But, that does not solve the problem.

circonian 03/22/15 02:29 PM

Quote:

Originally Posted by Garkin (Post 19832)
Or you can replace table.insert and remove whole DoesScriptNameExist function:

I was originally doing something similar to what you suggested adding the information to the table and checking to see if it already existed like this:
Lua Code:
  1. if not CLICK4INFO.sv.scripts[scriptName] then
  2.     CLICK4INFO.sv.scripts[scriptName] = script
  3. end
By the way doing it like this does NOT cause the error.


But if I do it like that then every time I try to populate the scroll list with that information I would have to copy it into another table & reorganize it like this any way:
Lua Code:
  1. {["scriptName"] = scriptName, ["script"] = script}

Because in When you call:
Lua Code:
  1. local entry = ZO_ScrollList_CreateDataEntry(ROW_TYPE_ID, rowData, 1)
  2. table.insert(dataList, entry)
To add a row to the scrollList you have to pass in rowData which is a table (well it doesn't have to be a table, but since I need to pass in two pieces of information it needs to be a table to hold all of the information). If I did it the old way:
Lua Code:
  1. CLICK4INFO.sv.scripts[scriptName] = script
I would loose the scriptName & only script would get passed to my setupDataRow function. Unless I copy the script information into the correct format first so I can pass in rowData as a table like:
Lua Code:
  1. {["scriptName"] = scriptName, ["script"] = script}

Although I could do that..it just seemed like a waste and slower. My choices are do a little extra function call with special code to see if a scriptName already exists, which only runs when you add a new script. Or Repack all of the information into a new table every time the data is displayed.

The only thing that stops the error (without changing it to the old way that Garkin suggested) is commenting out this line:
Lua Code:
  1. --table.insert(CLICK4INFO.sv.scripts, {["scriptName"] = scriptName, ["script"] = script})
So the problem has to have something to do with that?

circonian 03/22/15 03:38 PM

EDIT: I had tried to open the saved variable file before to see what was in it, why it was getting so large but notepad++ always crashed. I got lucky this time & was able to open it & see what was getting saved in the scripts table.
Which now knowing what was in there I was able to find the problem.

This function calls ZO_ScrollList_CreateDataEntry
Lua Code:
  1. function Click4Info:UpdateScrollList(sourceTable)
  2.    ...
  3.    -- which calls:
  4.    local entry = ZO_ScrollList_CreateDataEntry(ROW_TYPE_ID, rowData, 1)  
  5.   ...
  6. end

Which causes some recursion here copying data into itself, data.dataEntry.data = data
Which I guess is ok for items in the game ? not sure why or what the purpose of that is ? but since the data object I was passing in was a table inside the saved variable file it was doing that recursion in the saved variable file saving data inside its self infinitely.

Lua Code:
  1. function ZO_ScrollList_CreateDataEntry(typeId, data, categoryId)
  2.     local entry =
  3.     {
  4.         typeId = typeId,
  5.         categoryId = categoryId,
  6.         data = data,
  7.     }
  8.     data.dataEntry = entry
  9.     return entry
  10. end

Saved Variable file scripts table:

Baertram 03/22/15 09:38 PM

I guess I also sometimes see this inside ZGOO when I inspect controls.
They seem to have an data entry which got another data entry with a third data entry and so on.

I was always wondering why was shown this way and thought it's only a "visual" problem with ZGOO, where parents and childs (where parent and child are the same somehow) are shown in the same control again.

Sasky 03/22/15 10:51 PM

Lua tables are essentially references, so it's not that uncommon/difficult to have some nested loops.

For example, this is really all you need for setting it up:
Lua Code:
  1. local foo = {}
  2. foo.bar = foo

I'm not sure that you can throw a recursive table structure into SavedVars normally, so probably create it elsewhere and do a deep copy that removes those references.

Here's a gist someone put up on different deep copy methods:
https://gist.github.com/tylerneylon/...21109155b2d244

circonian 03/22/15 11:09 PM

Quote:

Originally Posted by Sasky (Post 19863)
Lua tables are essentially references, so it's not that uncommon/difficult to have some nested loops.

For example, this is really all you need for setting it up:
Lua Code:
  1. local foo = {}
  2. foo.bar = foo

I'm not sure that you can throw a recursive table structure into SavedVars normally, so probably create it elsewhere and do a deep copy that removes those references.

Here's a gist someone put up on different deep copy methods:
https://gist.github.com/tylerneylon/...21109155b2d244

Yeah, I didn't want the recursion in the saved variables, I just didn't realize that was happening until now.
Thats what I did to solve it, I just did a deep copy and used that to add the data rows to the scroll list.

BTW, theres already a built in function for it:
Lua Code:
  1. ZO_DeepTableCopy(table source, table dest)

Thanks everyone for the ideas !

merlight 03/23/15 01:55 PM

You could also get around that by giving CreateDataEntry a wrapper table instead of copying the data:
Lua Code:
  1. local entry = ZO_ScrollList_CreateDataEntry(typeId, {mydata = realdata})
  2. -- it will then look like this
  3. entry = {
  4.   typeId = typeId,
  5.   categoryId = categoryId,
  6.   data = {mydata = realdata, dataEntry = entry},
  7. }
  8. -- the data.dataEntry.data.dataEntry... cycle doesn't infect realdata

Or use a metatable:
Lua Code:
  1. local mtdata = {__index = realdata}
  2. local entry = ZO_ScrollList_CreateDataEntry(typeId, setmetatable({}, mtdata))
  3. mtdata.__newindex = realdata
  4. -- it will then look like this
  5. entry = {
  6.   typeId = typeId,
  7.   categoryId = categoryId,
  8.   data = {dataEntry = entry},
  9. }
  10. -- but entry.data.thing will return realdata.thing


All times are GMT -6. The time now is 02:26 AM.

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