Thread Tools Display Modes
03-15-12, 12:26 AM   #1
unlimit
Lookin' Good
 
unlimit's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 484
Proper LUA?

So, I was making a new feature for my unitframes while my internet was down, but since I had no where to test it this is what I came up with. >.>

One of my problems is, though, I hate long lines of repeating crap. So when I was looking at the below, I thought, maybe it'd be better if I made a loop out of it.

lua Code:
  1. local class = select(2, UnitClass("player"))
  2. local mastery = GetPrimaryTalentTree()

lua Code:
  1. if class == "DEATHKNIGHT" then
  2.     if mastery == 1 then return data["deathknight_" .. mastery]; end       
  3.     if mastery == 2 then return data["deathknight_" .. mastery]; end       
  4.     if mastery == 3 then return data["deathknight_" .. mastery]; end
  5. elseif class == "DRUID" then
  6.     if mastery == 1 then return data["druid_" .. mastery]; end     
  7.     if mastery == 2 then return data["druid_" .. mastery]; end     
  8.     if mastery == 3 then return data["druid_" .. mastery]; end
  9. elseif class == "HUNTER" then
  10.     if mastery == 1 then return data["hunter_" .. mastery]; end    
  11.     if mastery == 2 then return data["hunter_" .. mastery]; end    
  12.     if mastery == 3 then return data["hunter_" .. mastery]; end
  13. elseif class == "MAGE" then
  14.     if mastery == 1 then return data["mage_" .. mastery]; end      
  15.     if mastery == 2 then return data["mage_" .. mastery]; end      
  16.     if mastery == 3 then return data["mage_" .. mastery]; end
  17. elseif class == "PALADIN" then
  18.     if mastery == 1 then return data["paladin_" .. mastery]; end       
  19.     if mastery == 2 then return data["paladin_" .. mastery]; end       
  20.     if mastery == 3 then return data["paladin_" .. mastery]; end
  21. elseif class == "PRIEST" then
  22.     if mastery == 1 then return data["priest_" .. mastery]; end    
  23.     if mastery == 2 then return data["priest_" .. mastery]; end    
  24.     if mastery == 3 then return data["priest_" .. mastery]; end
  25. elseif class == "ROGUE" then
  26.     if mastery == 1 then return data["rogue_" .. mastery]; end     
  27.     if mastery == 2 then return data["rogue_" .. mastery]; end     
  28.     if mastery == 3 then return data["rogue_" .. mastery]; end
  29. elseif class == "SHAMAN" then
  30.     if mastery == 1 then return data["shaman_" .. mastery]; end    
  31.     if mastery == 2 then return data["shaman_" .. mastery]; end    
  32.     if mastery == 3 then return data["shaman_" .. mastery]; end
  33. elseif class == "WARLOCK" then
  34.     if mastery == 1 then return data["warlock_" .. mastery]; end       
  35.     if mastery == 2 then return data["warlock_" .. mastery]; end       
  36.     if mastery == 3 then return data["warlock_" .. mastery]; end
  37. elseif class == "WARRIOR" then
  38.     if mastery == 1 then return data["warrior_" .. mastery]; end       
  39.     if mastery == 2 then return data["warrior_" .. mastery]; end       
  40.     if mastery == 3 then return data["warrior_" .. mastery]; end
  41. else
  42.     return data["all"];
  43. end

So this was born. Unfortunately, I'm not certain this is valid LUA. I'm also under the impression that the "classlist" table is completely unnessisary.

lua Code:
  1. classlist = {
  2.     "DEATHKNIGHT",
  3.     "DRUID",
  4.     "HUNTER",
  5.     "MAGE",
  6.     "PALADIN",
  7.     "PRIEST",
  8.     "ROGUE",
  9.     "SHAMAN",
  10.     "WARLOCK",
  11.     "WARRIOR"
  12. }
  13.  
  14. for c = 1, #classlist do
  15.     for m = 1, 3 do
  16.         if class == classlist[c] then
  17.             if mastery == m then return data[class .. "_" .. m]; end
  18.         end
  19.     end
  20. end
  21.  
  22. if mastery ~= nil then
  23.     return data["all"];
  24. end

So my question to you awesome guys is, well, would what I made be pretty much the same as the above? Would there be a more efficent way to do it? And, are there things that I'm doing that might be unnessisary, like the classlist table?
__________________


kúdan: im playing pantheon
JRCapablanca: no youre not
** Pantheon has been Banned. **
  Reply With Quote
03-15-12, 12:50 AM   #2
Xrystal
nUI Maintainer
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 5,929
Looking at that little example you could break it down even easier as ...


Code:
local class = select(2, UnitClass("player"))
local mastery = GetPrimaryTalentTree()
return data[class.tolower().."_"..mastery]
__________________


Characters:
Gwynedda - 70 - Demon Warlock
Galaviel - 65 - Resto Druid
Gamaliel - 61 - Disc Priest
Gwynytha - 60 - Survival Hunter
Lienae - 60 - Resto Shaman
Plus several others below level 60

Info Panel IDs : http://www.wowinterface.com/forums/s...818#post136818
  Reply With Quote
03-15-12, 01:10 AM   #3
unlimit
Lookin' Good
 
unlimit's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 484
xD I never imagined it'd be that easy. Thanks a lot Xrystal / Nib (even though you deleted yours xD!)

This one, on the other hand, CAN'T be that easy. I need to return all of them, all of the time.

For instance, for a mage it'd be...

lua Code:
  1. local mage = RDXDB.ObjectFinder:new(parent, function(p,f,md) return (md and type(md) == "table"); end);
  2. mage:SetLabel(VFLI.i18n("MAGE"));
  3. if desc and desc.MAGE then mage:SetPath(desc.MAGE); end
  4. mage:Show();
  5. ui:InsertFrame(mage);

I know the below isn't correct, but it's kind of the only thing that ran through my head. <_<

If it isn't too much to ask here, what would be a MUCH better way of doing this, if I ALWAYS need these to show up?

lua Code:
  1. function TRUESYS.classspec()
  2.     local _, class = UnitClass("player")
  3.     local mastery = GetPrimaryTalentTree()
  4.  
  5.     classlist = {
  6.         "DEATHKNIGHT",
  7.         "DRUID",
  8.         "HUNTER",
  9.         "MAGE",
  10.         "PALADIN",
  11.         "PRIEST",
  12.         "ROGUE",
  13.         "SHAMAN",
  14.         "WARLOCK",
  15.         "WARRIOR"
  16.     }
  17.  
  18.     return class, mastery, classlist
  19. end
  20.  
  21. local function testfunction()
  22.     classlist = TRUESYS.classspec()
  23.  
  24.     for c = 1, #classlist do
  25.         for m = 1, 3 do
  26.             local classlist[c] .. "_" .. m = RDXDB.ObjectFinder:new(parent, function(p,f,md) return (md and type(md) == "table"); end);
  27.             classlist[c] .. "_" .. m:SetLabel(VFLI.i18n(classlist[c] .. "_" .. m));
  28.             if desc and desc.classlist[c] .. "_" .. m then classlist[c] .. "_" .. m:SetPath(desc.classlist[c] .. "_" .. m); end
  29.             classlist[c] .. "_" .. m:Show();
  30.             ui:InsertFrame(classlist[c] .. "_" .. m);
  31.         end
  32.     end
  33.  
  34.     local all = RDXDB.ObjectFinder:new(parent, function(p,f,md) return (md and type(md) == "table"); end);
  35.     all:SetLabel(VFLI.i18n("ALL"));
  36.     if desc and desc.ALL then all:SetPath(desc.ALL); end
  37.     all:Show();
  38.     ui:InsertFrame(all);
  39. end
  40.  
  41. testfunction()
__________________


kúdan: im playing pantheon
JRCapablanca: no youre not
** Pantheon has been Banned. **

Last edited by unlimit : 03-15-12 at 09:17 PM.
  Reply With Quote
03-15-12, 08:45 PM   #4
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
Unless you need that mastery variable later, you can even do
Code:
return data[class:lower().."_"..GetPrimaryTalentTree()]
This would be even leaner if the class names in your data table were all caps and you didn't need to make them lower case. (PS- your formatting and method name are wrong, Xrystal. I corrected it above.)

I would even get rid of that extra select function call and do
Code:
local _,class = UnitClass("player")
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote
03-15-12, 11:02 PM   #5
Xrystal
nUI Maintainer
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 5,929
Oops, thanks Seerah.
__________________


Characters:
Gwynedda - 70 - Demon Warlock
Galaviel - 65 - Resto Druid
Gamaliel - 61 - Disc Priest
Gwynytha - 60 - Survival Hunter
Lienae - 60 - Resto Shaman
Plus several others below level 60

Info Panel IDs : http://www.wowinterface.com/forums/s...818#post136818
  Reply With Quote
03-15-12, 11:28 PM   #6
unlimit
Lookin' Good
 
unlimit's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 484
Thanks a lot Seerah, Xrystal, and Nib!

I changed the above again, kept calling mastery / class when I didn't need it. c.c
What I'm really looking for out of the rest of this is combining names, kind of like in a string you can just do:

lua Code:
  1. print(test.."_"..tset);

If I wanted a variable in the same fashion, such as:

lua Code:
  1. local classlist[c] .. "_" .. m = dostuff

how would I go about doing it?

lua Code:
  1. function TRUESYS.classspec()
  2.     local _, class = UnitClass("player")
  3.     local mastery = GetPrimaryTalentTree()
  4.  
  5.     classlist = {
  6.         "DEATHKNIGHT",
  7.         "DRUID",
  8.         "HUNTER",
  9.         "MAGE",
  10.         "PALADIN",
  11.         "PRIEST",
  12.         "ROGUE",
  13.         "SHAMAN",
  14.         "WARLOCK",
  15.         "WARRIOR"
  16.     }
  17.  
  18.     return class, mastery, classlist
  19. end
  20.  
  21. local function testfunction()
  22.     classlist = TRUESYS.classspec()
  23.  
  24.     for c = 1, #classlist do
  25.         for m = 1, 3 do
  26.             local classlist[c] .. "_" .. m = RDXDB.ObjectFinder:new(parent, function(p,f,md) return (md and type(md) == "table"); end);
  27.             classlist[c] .. "_" .. m:SetLabel(VFLI.i18n(classlist[c] .. "_" .. m));
  28.             if desc and desc.classlist[c] .. "_" .. m then classlist[c] .. "_" .. m:SetPath(desc.classlist[c] .. "_" .. m); end
  29.             classlist[c] .. "_" .. m:Show();
  30.             ui:InsertFrame(classlist[c] .. "_" .. m);
  31.         end
  32.     end
  33.  
  34.     local all = RDXDB.ObjectFinder:new(parent, function(p,f,md) return (md and type(md) == "table"); end);
  35.     all:SetLabel(VFLI.i18n("ALL"));
  36.     if desc and desc.ALL then all:SetPath(desc.ALL); end
  37.     all:Show();
  38.     ui:InsertFrame(all);
  39. end
  40.  
  41. testfunction()
__________________


kúdan: im playing pantheon
JRCapablanca: no youre not
** Pantheon has been Banned. **
  Reply With Quote
03-16-12, 02:27 AM   #7
kaels
A Cyclonian
AddOn Author - Click to view addons
Join Date: Jan 2011
Posts: 46
I think if you want to access 'dostuff' through that concatenated string, the best way to do it would be to use it as a key in a table:
lua Code:
  1. local sometable = {}
  2. sometable[classlist[c] .. "_" .. m] = dostuff
Then you can access dostuff through e.g. sometable.DEATHKNIGHT_1 or sometable[DEATHKNIGHT_1] or sometable[classlist[c] .. "_" .. m] in a scope where c==1 and m==1.

Last edited by kaels : 03-16-12 at 02:30 AM.
  Reply With Quote
03-16-12, 02:31 AM   #8
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by unlimit View Post
If I wanted a variable in the same fashion, such as:

lua Code:
  1. local classlist[c] .. "_" .. m = dostuff

how would I go about doing it?
You wouldn't. Lua variable names cannot be constructed that way. A variable is called a variable because its contents are variable; the whole point of assigning the value to a variable is so that you have a consistent name to refer to content that's not known ahead of time.

I'm actually not even sure what half your code was attempting to do, and I know nothing about the RDX API, but something like this is surely closer to valid Lua code:

Lua Code:
  1. --  Define this once instead of making a new table
  2. --  every time your call your function.
  3. local classlist = {
  4.     "DEATHKNIGHT",
  5.     "DRUID",
  6.     "HUNTER",
  7.     "MAGE",
  8.     "PALADIN",
  9.     "PRIEST",
  10.     "ROGUE",
  11.     "SHAMAN",
  12.     "WARLOCK",
  13.     "WARRIOR"
  14. }
  15.  
  16. function TRUESYS.classspec()
  17.     local _, class = UnitClass("player")
  18.     local mastery = GetPrimaryTalentTree()
  19.  
  20.     return class, mastery
  21.     --  Don't bother returning the classlist table
  22.     --  unless you're going to be calling this function
  23.     --  from other files. Inside this file, you can
  24.     --  simply refer to the table directly.
  25. end
  26.  
  27. --  Define this once, instead of making a new duplicate function
  28. --  30 times every time you run testfunction().
  29. local function newfunc(p, f, md)
  30.     --  You don't need to check for simple existence on "md" first,
  31.     --  because "nil" is also a type, and "nil" ~= "table".
  32.     return type(md) == "table"
  33. end
  34.  
  35. local function testfunction()
  36. --  classlist = TRUESYS.classspec()
  37. --  for c = 1, #classlist do
  38. --  ^ These lines from your original code don't even make sense.
  39. --  The TRUESYS.classspec() function returns three values, not a table,
  40. --  so by assigning its returns to a single variable, you're actually
  41. --  only catching the first one, which is a string describing the
  42. --  player's class. The # operator will also give you the length of a
  43. --  string, so if you're on a DRUID, your loop will run from 1 to 5,
  44. --  because the string "DRUID" is 5 characters long.
  45.  
  46.     local class, spec = TRUESYS.classpsec()
  47.     for i = 1, #classlist do
  48.         for j = 1, 3 do
  49.             local iclass = classlist[i]
  50.             --  I think you want to make a table for each class:
  51.             classlist[iclass] = classlist[iclass] or {}
  52.             --  ... and then make some kind of RDX object for each spec for that class:
  53.             --      Probably this will trigger an error because "parent" is not defined.
  54.             local specObject = RDXDB.ObjectFinder:new(parent, newfunc)
  55.             -- ... and then add that object to the table for the class:
  56.             classlist[iclass][j] = specObject
  57.  
  58.             specObject:SetLabel(VFLI.i18n(specObject))
  59.  
  60.             --  This line should actually trigger Lua errors, because
  61.             --  1. the variable "desc" is not defined in this scope, and
  62.             --  2. "desc" is not a table with the RDX object you just created
  63.             --      as one of its keys.
  64.             --  I know basically nothing about the RDX API, so you're on your own
  65.             --  with fixing this section. I commented it out for now.
  66. --          if desc and desc.specObject then
  67. --              specObject:SetPath(desc.specObject)
  68. --          end
  69.  
  70.             specObject:Show()
  71.             ui:InsertFrame(specObject)
  72.         end
  73.     end
  74.  
  75.     --  Probably this will trigger an error because "parent" is not defined.
  76.     local all = RDXDB.ObjectFinder:new(parent, newfunc)
  77.     all:SetLabel(VFLI.i18n("ALL"))
  78.     --  Probably this will trigger an error because "desc" is not defined.
  79.     if desc and desc.ALL then
  80.         all:SetPath(desc.ALL)
  81.     end
  82.     all:Show()
  83.     ui:InsertFrame(all)
  84. end
  85.  
  86. testfunction()
  Reply With Quote
03-16-12, 06:46 AM   #9
unlimit
Lookin' Good
 
unlimit's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 484
Thanks so much Phanx.

Your posts are always so incredibly educational, and I really do appreciate it. Every time I see you reply to someone it's so in depth. >.< I was sitting here wracking my brain on what the hell to do, and you come in and do this

__________________


kúdan: im playing pantheon
JRCapablanca: no youre not
** Pantheon has been Banned. **

Last edited by unlimit : 03-16-12 at 09:10 AM.
  Reply With Quote
03-16-12, 07:41 AM   #10
Ketho
A Pyroguard Emberseer
 
Ketho's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,026
Originally Posted by unlimit View Post
Thanks so much Phanx.

Your posts are always so incredibly educational, and I really do appreciate it. every time I see you reply to someone it's so in depth. >.< I was sitting here wracking my brain on what the hell to do, and you come in and do this
Time to revive the Phanx admiration thread
  Reply With Quote
03-16-12, 09:38 AM   #11
unlimit
Lookin' Good
 
unlimit's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 484
Originally Posted by Ketho View Post
Time to revive the Phanx admiration thread
Here here!

Well, at this point, I'll just post the entire feature.

lua Code:
  1. function TRUESYS.classspec()
  2.     local _, class = UnitClass("player")
  3.     local mastery = GetPrimaryTalentTree()
  4.  
  5.     return class, mastery
  6. end
  7.  
  8. local classlist = {
  9.     "DEATHKNIGHT",
  10.     "DRUID",
  11.     "HUNTER",
  12.     "MAGE",
  13.     "PALADIN",
  14.     "PRIEST",
  15.     "ROGUE",
  16.     "SHAMAN",
  17.     "WARLOCK",
  18.     "WARRIOR"
  19. }
  20.  
  21. local function newfunc(p, f, md)
  22.     return type(md) == "table"
  23. end
  24.  
  25. RDXDB.RegisterSymLinkClass({
  26.     name = "class/spec";
  27.     title = "class/spec";
  28.     GetTargetPath = function(data)
  29.         class, mastery = TRUESYS.classspec()
  30.         if mastery == nil then
  31.             return data["all"]
  32.         else
  33.             return data[class .. mastery]
  34.         end
  35.     end;
  36.     Register = function(path)
  37.         VFLEvents:Bind("PLAYER_TALENT_UPDATE", nil, function() RDXDB.NotifyUpdate(path); end, "symlink_" .. path);
  38.     end;
  39.     Unregister = function(path)
  40.         VFLEvents:Unbind("symlink_" .. path);
  41.     end;
  42.     GetUI = function(parent, desc)
  43.         local ui = VFLUI.CompoundFrame:new(parent);
  44.        
  45.         for i = 1, #classlist do
  46.             for j = 1, 3 do
  47.                 local cl = classlist[i]
  48.                 classlist[cl] = classlist[cl] or {}
  49.                 local specObject = RDXDB.ObjectFinder:new(parent, newfunc)
  50.                 classlist[cl][j] = specObject
  51.                 specObject:SetLabel(VFLI.i18n(cl .. " " .. j))
  52.                 if desc and desc.specObject then
  53.                     specObject:SetPath(desc.specObject)
  54.                 end
  55.  
  56.                 specObject:Show()
  57.                 ui:InsertFrame(specObject)
  58.             end
  59.         end
  60.  
  61.         local all = RDXDB.ObjectFinder:new(parent, newfunc)
  62.         all:SetLabel(VFLI.i18n("ALL"))
  63.         if desc and desc.ALL then
  64.             all:SetPath(desc.ALL)
  65.         end
  66.         all:Show()
  67.         ui:InsertFrame(all)
  68.  
  69.         ui.GetDescriptor = function(x)
  70.             return {
  71.                 class = "class/talent",
  72.                 mage3 = classlist.MAGE[3]:GetPath(),
  73.                 all = all:GetPath(),
  74.             };
  75.         end;
  76.  
  77.         ui.Destroy = VFL.hook(function(s) s.GetDescriptor = nil; end, ui.Destroy);
  78.  
  79.         return ui;
  80.     end;
  81. });

The only two things I'm having a problem with now are, in the ui.GetDescriptor function, creating a loop for all classes / specs (i.e. mage3 = classlist.MAGE[3]:GetPath()) instead of just posting it all. It's probably not worth the trouble (to be honest, none of it really was, I just can't stand seeing long repetitious lines. c.c) And the problem of the new table only populating on-open.

Using the code Phanx wrote, it works great! All of the data for the object is stored in classlist.<class>[3], it JUST doesn't work on reloadui (and login/logoff), unless I open the frame again. x3
__________________


kúdan: im playing pantheon
JRCapablanca: no youre not
** Pantheon has been Banned. **

Last edited by unlimit : 03-16-12 at 09:59 AM.
  Reply With Quote
03-16-12, 10:56 AM   #12
Waky
A Cobalt Mageweaver
 
Waky's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2010
Posts: 200
Originally Posted by Ketho View Post
Time to revive the Phanx admiration thread
I laughed when I saw this post :P
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Proper LUA?


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