WoWInterface

WoWInterface (http://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (http://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   How to create a copy of an object without reference? (http://www.wowinterface.com/forums/showthread.php?t=45873)

zork 02-23-13 11:47 AM

How to create a copy of an object without reference? [SOLVED]
 
I have a problem that I cannot solve.

For my UI panel I want a "reset" feature. Thus I have a reset button that can be called to load the database defaults.

The problem I'm having is that as soon as I do this the default data becomes a reference. Thus on a second click on reset it will not work anymore. Because of the reference issue.

Here is my code:
Lua Code:
  1. --object container
  2.   local db = CreateFrame("Frame")
  3.   ns.db = db
  4.   db.default = {}
  5.  
  6.   ---------------------------------------------
  7.   --DEFAULTS
  8.   ---------------------------------------------
  9.  
  10.   --default orb setup
  11.   db.default.orb = {
  12.     --health
  13.     ["HEALTH"] = {
  14.       --filling
  15.       filling = {
  16.         texture     = "Interface\\AddOns\\oUF_Diablo\\media\\orb_filling15",
  17.         color       = { r = 1, g = 0, b = 0, },
  18.         colorAuto   = false, --automatic coloring based on class/powertype
  19.       },
  20.     },--health end
  21.     --power
  22.     ["POWER"] = {
  23.       --filling
  24.       filling = {
  25.         texture     = "Interface\\AddOns\\oUF_Diablo\\media\\orb_filling15",
  26.         color       = { r = 0, g = 0, b = 1, },
  27.         colorAuto   = false, --automatic coloring based on class/powertype
  28.       },
  29.     },--power end
  30.   } --default end
  31.  
  32.   db.getDefaultOrbHealth = function() return db.default.orb["HEALTH"] end
  33.   db.getDefaultOrbPower = function() return db.default.orb["POWER"] end
  34.   db.getDefaultOrb = function() return db.default.orb end
  35.  
  36.   ---------------------------------------------
  37.   --CHARACTER DATA
  38.   ---------------------------------------------
  39.  
  40.   --load character data defaults
  41.   db.loadCharacterDataDefaults = function(type)
  42.     if type then
  43.       if type == "HEALTH" then
  44.         OUF_DIABLO_DB_CHAR[type] = db.getDefaultOrbHealth()
  45.         print(addon..": health orb reseted to default")
  46.       elseif type == "POWER" then
  47.         OUF_DIABLO_DB_CHAR[type] = db.getDefaultOrbPower()
  48.         print(addon..": power orb reseted to default")
  49.       end
  50.     else
  51.       OUF_DIABLO_DB_CHAR = db.getDefaultOrb()
  52.       print(addon..": character data defaults loaded")
  53.     end
  54.     db.char = OUF_DIABLO_DB_CHAR
  55.     --update the orb view
  56.     ns.panel.updateOrbView()
  57.   end

OUF_DIABLO_DB_CHAR is my saved variable per character.

Basically when I click the reset button I call
Code:

  db.loadCharacterDataDefaults("HEALTH")
I cannot copy the table data via ipairs. Assoc tables cannot be looped. The following will return 0:
Code:

print(# db.default.orb["HEALTH"])
Any idea?

Tuller uses sth like
Lua Code:
  1. local function copyDefaults(tbl, defaults)
  2.     for k, v in pairs(defaults) do
  3.         if type(v) == 'table' then
  4.             tbl[k] = copyDefaults(tbl[k] or {}, v)
  5.         elseif tbl[k] == nil then
  6.             tbl[k] = v
  7.         end
  8.     end
  9.     return tbl
  10. end

Maybe I'm missing sth...

Oh...his GetDefault funnction is looking like:
Lua Code:
  1. function tullaRange:GetDefaults()
  2.     return {
  3.         normal = {1, 1, 1},
  4.         oor = {1, 0.3, 0.1},
  5.         oom = {0.1, 0.3, 1}
  6.     }
  7. end

Hmmm...so this could be an idea. I do not create a default table variable in first place that could get referenced later on.

I will try that.

Perfect that did it! :)

What I'm now doing is:
Lua Code:
  1. --default orb setup
  2.   function db:GetOrbDefaults()
  3.     return {
  4.       --health
  5.       ["HEALTH"] = {
  6.         --filling
  7.         filling = {
  8.           texture     = "Interface\\AddOns\\oUF_Diablo\\media\\orb_filling15",
  9.           color       = { r = 1, g = 0, b = 0, },
  10.           colorAuto   = false, --automatic coloring based on class/powertype
  11.         },
  12.       },--health end
  13.       --power
  14.       ["POWER"] = {
  15.         --filling
  16.         filling = {
  17.           texture     = "Interface\\AddOns\\oUF_Diablo\\media\\orb_filling15",
  18.           color       = { r = 0, g = 0, b = 1, },
  19.           colorAuto   = false, --automatic coloring based on class/powertype
  20.         },
  21.       },--power end
  22.     } --default end
  23.   end

pelf 02-23-13 12:32 PM

I feel like I remember seeing "default settings" tables in code, before. I assume they're usually used to initialize, but they could just as easily be used to reset. Nice.

ravagernl 02-23-13 12:43 PM

One thing you could also do if your options are not very complicated is make use of metatables:

http://www.lua.org/pil/13.4.3.html

Then when resetting, just loop over the options database table and set all keys to nil.

Haleth 02-23-13 04:08 PM

I use the following function to copy a table by value:

Code:

local function copyTable(source, target)
        for key, value in pairs(source) do
                if type(value) == "table" then
                        target[key] = {}
                        copyTable(value, target[key])
                else
                        target[key] = value
                end
        end
end


pelf 02-23-13 04:23 PM

If that works, then what is this talking about?

Quote:

I cannot copy the table data via ipairs. Assoc tables cannot be looped.

Haleth 02-23-13 05:19 PM

I don't see the problem there. Why not use:

Code:

for key, value in pairs(db.default.orb["HEALTH"]) do
        ...
 end

Any table with only keys in it rather than indexes will have #table return zero. That doesn't mean you can't iterate it.

zork 02-23-13 06:17 PM

Ah damn. I think I tried to iterate over the table length. I think I mixed sth up when using # table.

The loop Haleth posted actually does work.

Thanks.

*edit*

Thanks a bunch it is working now! :)

semlar 02-23-13 06:23 PM

You can use either pairs or next to loop over a dictionary table.

Lua only returns a length for numerically indexed tables (or at least the highest consecutive index).

pelf 02-24-13 01:19 AM

I love it when I go down another path almost to completion to avoid a problem I didn't have when I'm coding. Always fun :).

Rilgamon 02-24-13 02:53 AM

Just incase you missed it ... CopyTable is a global function since quite some time now

Lua Code:
  1. function CopyTable(settings)
  2.     local copy = {};
  3.     for k, v in pairs(settings) do
  4.         if ( type(v) == "table" ) then
  5.             copy[k] = CopyTable(v);
  6.         else
  7.             copy[k] = v;
  8.         end
  9.     end
  10.     return copy;
  11. end

http://wowprogramming.com/utils/xmlb...L/UIParent.lua

Haleth 02-24-13 03:44 AM

Oh, interesting. There's quite a few useful function in UIParent.lua. However I noticed this...

Code:

    if ( tempName == "LeftButton" ) then
        tempName = "BUTTON1";
    elseif ( tempName == "RightButton" ) then
        tempName = "BUTTON2";
    elseif ( tempName == "MiddleButton" ) then
        tempName = "BUTTON3";
    elseif ( tempName == "Button4" ) then
        tempName = "BUTTON4";
    elseif ( tempName == "Button5" ) then
        tempName = "BUTTON5";
    elseif ( tempName == "Button6" ) then
        tempName = "BUTTON6";
    elseif ( tempName == "Button7" ) then
        tempName = "BUTTON7";
    elseif ( tempName == "Button8" ) then
        tempName = "BUTTON8";
    elseif ( tempName == "Button9" ) then
        tempName = "BUTTON9";
    elseif ( tempName == "Button10" ) then
        tempName = "BUTTON10";
    elseif ( tempName == "Button11" ) then
        tempName = "BUTTON11";
    elseif ( tempName == "Button12" ) then
        tempName = "BUTTON12";
    elseif ( tempName == "Button13" ) then
        tempName = "BUTTON13";
    elseif ( tempName == "Button14" ) then
        tempName = "BUTTON14";
    elseif ( tempName == "Button15" ) then
        tempName = "BUTTON15";
    elseif ( tempName == "Button16" ) then
        tempName = "BUTTON16";
    elseif ( tempName == "Button17" ) then
        tempName = "BUTTON17";
    elseif ( tempName == "Button18" ) then
        tempName = "BUTTON18";
    elseif ( tempName == "Button19" ) then
        tempName = "BUTTON19";
    elseif ( tempName == "Button20" ) then
        tempName = "BUTTON20";
    elseif ( tempName == "Button21" ) then
        tempName = "BUTTON21";
    elseif ( tempName == "Button22" ) then
        tempName = "BUTTON22";
    elseif ( tempName == "Button23" ) then
        tempName = "BUTTON23";
    elseif ( tempName == "Button24" ) then
        tempName = "BUTTON24";
    elseif ( tempName == "Button25" ) then
        tempName = "BUTTON25";
    elseif ( tempName == "Button26" ) then
        tempName = "BUTTON26";
    elseif ( tempName == "Button27" ) then
        tempName = "BUTTON27";
    elseif ( tempName == "Button28" ) then
        tempName = "BUTTON28";
    elseif ( tempName == "Button29" ) then
        tempName = "BUTTON29";
    elseif ( tempName == "Button30" ) then
        tempName = "BUTTON30";
    elseif ( tempName == "Button31" ) then
        tempName = "BUTTON31";
    end

:rolleyes:

pelf 02-24-13 08:44 AM

Well, if Button4 ever changes to RightRightButton, we'll be ready.


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

vBulletin © 2014, Jelsoft Enterprises Ltd
©2012 ZAM Network LLC