Thread Tools Display Modes
03/22/15, 03:39 AM   #1
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
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
  Reply With Quote
03/22/15, 06:04 AM   #2
votan
 
votan's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2014
Posts: 577
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
  Reply With Quote
03/22/15, 06:36 AM   #3
Garkin
 
Garkin's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 832
Originally Posted by votan View Post
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

Last edited by Garkin : 03/22/15 at 06:40 AM.
  Reply With Quote
03/22/15, 02:13 PM   #4
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Originally Posted by votan View Post
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.

Last edited by circonian : 03/22/15 at 02:29 PM.
  Reply With Quote
03/22/15, 02:29 PM   #5
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Originally Posted by Garkin View Post
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?

Last edited by circonian : 03/22/15 at 03:04 PM.
  Reply With Quote
03/22/15, 03:38 PM   #6
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
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:

Last edited by circonian : 03/22/15 at 03:59 PM.
  Reply With Quote
03/22/15, 09:38 PM   #7
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 5,002
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.
  Reply With Quote
03/22/15, 10:51 PM   #8
Sasky
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 231
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
  Reply With Quote
03/22/15, 11:09 PM   #9
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Originally Posted by Sasky View Post
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 !
  Reply With Quote
03/23/15, 01:55 PM   #10
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
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
  Reply With Quote

ESOUI » Developer Discussions » Lua/XML Help » SavedVariables Problem...Any Ideas?


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