Quantcast
From table to XML - WoWInterface
Thread Tools Display Modes
05-06-15, 06:10 AM   #1
Yukyuk
A Chromatic Dragonspawn
 
Yukyuk's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2015
Posts: 176
From table to XML

Am developing my addon, Historia.
Have set up the database as I want it, but am now running into a problem.

Can't figure out a decent way to put a table I have into the XML its supposed to go.
Its basically a simple table with the players levels and a time when the player gained that level.
Sure, I could define a 100 possible fontstring(s) in my XML file but there is problably a more elegant way to handle this.
Also would like to do this without a scrolling table.

Any help is appriciated.

Lua Code:
  1. ["Level"] = {
  2.         {
  3.             ["time"] = 1430830617,
  4.             ["level"] = 1,
  5.         }, -- [1]
  6.         {
  7.             ["time"] = 1430830830,
  8.             ["level"] = 2,
  9.         }, -- [2]
  10.         {
  11.             ["time"] = 1430845053,
  12.             ["level"] = 3,
  13.         }, -- [3]
  14.         {
  15.             ["time"] = 1430845452,
  16.             ["level"] = 4,
  17.         }, -- [4]
  18.         {
  19.             ["time"] = 1430845770,
  20.             ["level"] = 5,
  21.         }, -- [5]
  22.     }
  Reply With Quote
05-06-15, 07:31 AM   #2
myrroddin
A Pyroguard Emberseer
 
myrroddin's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 1,124
Yes there is a simple way: don't use XML. XML is really only for setting up a frame that never changes, but you can do 99.9% of all frame related things in Lua, which is infinitely easier to read, and more importantly, debug.

In your ADDON_LOADED function (see my other post), assuming your saved variables in the ToC are called HistoriaDB, it should look something like this:
Code:
function private_table.eventFrame:ADDON_LOADED(AddOn)
    if not AddOn == MyAddOn then
        return
    end

    private_table.eventFrame:UnregisterEvent("ADDON_LOADED")
    HistoriaDB = HistoriaDB or {}
end

function private_table.eventFrame:PLAYER_LEVEL_UP(player_level)
    HistoriaDB["player"] = {name = UnitName("player"), level = player_level, current_time = GetTime()}
end

Last edited by myrroddin : 05-06-15 at 03:10 PM. Reason: Thanks SDPhantom!
  Reply With Quote
05-06-15, 07:35 AM   #3
myrroddin
A Pyroguard Emberseer
 
myrroddin's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 1,124
If you want your saved variables' table structure to look more like your example, then change this line:
Code:
HistoriaDB["Level"] = {time = GetTime(), level = player_level}
  Reply With Quote
05-06-15, 12:45 PM   #4
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 1,964
You forgot the end parenthesis on UnitName("player"
__________________
ESOUI AddOns | WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote
05-07-15, 12:30 PM   #5
Yukyuk
A Chromatic Dragonspawn
 
Yukyuk's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2015
Posts: 176
Yes there is a simple way: don't use XML. XML is really only for setting up a frame that never changes, but you can do 99.9% of all frame related things in Lua, which is infinitely easier to read, and more importantly, debug.
Yes you are right (of course ).
Made my first frame in lua today, easy
  Reply With Quote
05-07-15, 04:19 PM   #6
Dorwido
A Wyrmkin Dreamwalker
AddOn Author - Click to view addons
Join Date: Apr 2006
Posts: 54
Originally Posted by myrroddin View Post
Yes there is a simple way: don't use XML. XML is really only for setting up a frame that never changes, but you can do 99.9% of all frame related things in Lua, which is infinitely easier to read, and more importantly, debug.

In your ADDON_LOADED function (see my other post), assuming your saved variables in the ToC are called HistoriaDB, it should look something like this:
Code:
function private_table.eventFrame:ADDON_LOADED(AddOn)
    if not AddOn == MyAddOn then
        return
    end

    private_table.eventFrame:UnregisterEvent("ADDON_LOADED")
    HistoriaDB = HistoriaDB or {}
end

function private_table.eventFrame:PLAYER_LEVEL_UP(player_level)
    HistoriaDB["player"] = {name = UnitName("player"), level = player_level, current_time = GetTime()}
end
you should overwork
"if not AddOn == MyAddOn then
return
end"

2nd time i see you posting that which wont work
__________________
Auction Analytics
http://www.wowauction.org/
  Reply With Quote
05-07-15, 04:45 PM   #7
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,196
Originally Posted by Dorwido View Post
you should overwork
"if not AddOn == MyAddOn then
return
end"

2nd time i see you posting that which wont work
Reposting what I posted in another thread:

That's because "not AddOn" evaluates to false if AddOn is non-nil and true otherwise. So that line is essentially saying "if false/true == MyAddOn then" which isn't at all what you want for a string comparison.
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.
  Reply With Quote
05-07-15, 05:23 PM   #8
Banknorris
A Chromatic Dragonspawn
 
Banknorris's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2014
Posts: 153
I think it would be more didactic to mention that it is an operator precedence issue:
not (which is a unary operator, with the operand on the right side of the operator) will be evaluated in the expression before the == operator (which is a binary operator, with one operand to the left and one the right of the operator). And that is because not has a higher operator precedence than ==.
http://www.lua.org/pil/3.5.html

so

not AddOn == MyAddOn

is the same as

(not Addon) == MyAddon

instead of

not (Addon == MyAddOn)

When you want to change the evaluation order, you can use the parentheses like in the last expression. So
Code:
if not (AddOn == MyAddOn) then
        return
end
__________________
"In this world nothing can be said to be certain, except that fractional reserve banking is a Ponzi scheme and that you won't believe it." - Mandrill
  Reply With Quote
05-07-15, 05:43 PM   #9
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,196
Or just use
Code:
 if AddOn ~= MyAddOn then
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.
  Reply With Quote
05-07-15, 07:52 PM   #10
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 1,964
Internally, these two do the exact same operations in the Lua engine. The only difference is the later is in C code for both operations instead of popping in and out of the Lua code. The result is the second is slightly faster than the first.

Code:
not (var1 == var2)
Code:
var1 ~= var2
__________________
ESOUI AddOns | WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote
05-08-15, 11:34 AM   #11
Yukyuk
A Chromatic Dragonspawn
 
Yukyuk's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2015
Posts: 176
Took myrroddin's advice and coded part of my addon in lua instead of XML.
Would like to get the opinion of this community of how well I did.
There is problably room for improvement

This is the result of the coding (its part of a larger frame that is defined in XML).


And this is the code:
Lua Code:
  1. function addon:Levels()
  2.     -- log(format("Historia levels"))
  3.     --  Define the container frame for the level frames (MC  = Middle container)
  4.     local Historia_Level_MC = CreateFrame("FRAME", "Historia_Level_MC", Historia_UI_Level);
  5.     Historia_Level_MC:SetPoint("TOP" ,"Historia_Level_Header1", 0, -48)
  6.     Historia_Level_MC:SetPoint("BOTTOM" ,"Historia_UI_Level", 0, 32)
  7.     Historia_Level_MC:SetPoint("LEFT" ,"Historia_UI_Level", 32, 0)
  8.     Historia_Level_MC:SetPoint("RIGHT" ,"Historia_UI_Level", -32, 0)
  9.     Historia_Level_MC:SetBackdrop({bgFile = "Interface/DialogFrame/UI-DialogBox-Background",
  10.                    edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
  11.                    tile = true, tileSize = 32, edgeSize = 16,
  12.                    insets = { left = 0, right = 0, top = 5, bottom = 5 }});
  13.  
  14.     --  Define the frame for the first group of levels (ML1 = Middle Level one)            
  15.     local Historia_Level_ML1 = CreateFrame("FRAME", "Historia_Level_ML1", Historia_Level_MC);
  16.     Historia_Level_ML1:SetPoint("TOP" ,"Historia_Level_MC", 0, -0)
  17.     Historia_Level_ML1:SetPoint("BOTTOM" ,"Historia_Level_MC", 0, 0)
  18.     Historia_Level_ML1:SetPoint("LEFT" ,"Historia_Level_MC", 0, 0)
  19.     Historia_Level_ML1:SetPoint("RIGHT" ,"Historia_Level_MC", "LEFT", 40, 0)
  20.     Historia_Level_ML1:SetBackdrop({bgFile = "Interface/DialogFrame/UI-DialogBox-Background",
  21.                    edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
  22.                    tile = true, tileSize = 32, edgeSize = 16,
  23.                    insets = { left = 0, right = 0, top = 5, bottom = 5 }});
  24.                    
  25.     --  Define the frame for the first group of dates (MD1 = Middle Date one)              
  26.     local Historia_Level_MD1 = CreateFrame("FRAME", "Historia_Level_MD1", Historia_Level_MC);
  27.     Historia_Level_MD1:SetPoint("TOP" ,"Historia_Level_MC", 0, -0)
  28.     Historia_Level_MD1:SetPoint("BOTTOM" ,"Historia_Level_MC", 0, 0)
  29.     Historia_Level_MD1:SetPoint("LEFT" ,"Historia_Level_MC", 36, 0)
  30.     Historia_Level_MD1:SetPoint("RIGHT" ,"Historia_Level_MC", "LEFT", 200, 0)
  31.     Historia_Level_MD1:SetBackdrop({bgFile = "Interface/DialogFrame/UI-DialogBox-Background",
  32.                    edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
  33.                    tile = true, tileSize = 32, edgeSize = 16,
  34.                    insets = { left = 0, right = 0, top = 5, bottom = 5 }});                    
  35.                    
  36.     --  Define the header fontstring for the first group of levels (HLML1 = Historia Level ML1)
  37.     local HLML1 = Historia_Level_ML1:CreateFontString("HLML1", "ARTWORK", "GameFontWhite")
  38.     HLML1:SetPoint("TOP" ,"Historia_Level_ML1", 0, -10)
  39.     HLML1:SetText(L['Level'])
  40.     --  Define the header fontstring for the first group of dates (HLML1 = Historia Date ML1)
  41.     local HLMD1 = Historia_Level_MD1:CreateFontString("HLMD1", "ARTWORK", "GameFontWhite")
  42.     HLMD1:SetPoint("TOP" ,"Historia_Level_MD1", 0, -10)
  43.     HLMD1:SetText(L['Date'])   
  44.     --  Set the levels and the date in the UI
  45.     for i = 1, #HistoriaLocalDb.Level do
  46.         local HLML1L1 = Historia_Level_ML1:CreateFontString("HLML1L1", "ARTWORK", "GameFontWhite")
  47.             HLML1L1:SetPoint("TOP", "Historia_Level_ML1", 0, -((i+1)*12))
  48.             HLML1L1:SetText(tostring(HistoriaLocalDb.Level[i].level))
  49.         local HLML1D1 = Historia_Level_MD1:CreateFontString("HLML1D1", "ARTWORK", "GameFontNormal")
  50.             HLML1D1:SetPoint("TOP" ,"Historia_Level_MD1", "TOP", 0, -((i+1)*12))
  51.             HLML1D1:SetText(format(date("%a, %b %d %Y %H:%M", HistoriaLocalDb.Level[i].time))) 
  52.     end
  53. end
  Reply With Quote
05-08-15, 03:46 PM   #12
myrroddin
A Pyroguard Emberseer
 
myrroddin's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 1,124
You can add some readability and breathing room by breaking chunks into paragraphs. Also, when localizing, you can refer to the global strings, which are built-in localizations of common strings. For example, replace
Code:
HLML1:SetText(L['Level'])
with
Code:
HLML1:SetText(LEVEL)
As for your columns, I would suggest adding, as the first column, the character name, because many players have alts. And see what you can do about justifying the columns as center-aligned.

A good start!
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » From table to XML

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