function LP:GetAdds()
count = GetNumAddOns()
name = {}
for i=1,count do
name = GetAddOnInfo(i or "name")
end
for i,v in ipairs(name) do
v:SetProfile("Heal")
end
end
I think it is getting a list of the names of the addons, but it is gagging on my SetProfile line. Plus, I'm afraid that messing this part up could do something very bad to a user.
Help?
local addons = {}
function LP:GetAdds()
count = GetNumAddOns()
wipe(addons)
for i=1,count do
local name, _, _, enabled, loadable = GetAddOnInfo(i)
if enabled then
addons[i] = name
end
end
for i,v in ipairs(addons) do
if IsAddOnLoaded(v) then
_G[v]:SetProfile("Heal")
elseif IsAddOnLoadOnDemand(v) then
local loaded, reason = LoadAddOn(v)
if loaded then
_G[v]:SetProfile("Heal")
else
print(v..":".._G["ADDON_"..reason])
end
end
end
end
Drycoded.
I don't know what SetProfile() is supposed to be doing or why you assume every addon will support such a method.
I just corrected the obvious errors about tables and such.
Thanks!
The SetProfile just sets addons to that profile name if the user has already created a profile with that name. It won't work on Addons that don't have the Profiles.
So my mod can let people change their UI depending on their role, by typing /heal or /dps or /tank. So I can move my Grid, move my Bartender buttons, load or unload Recount, etc, with just a typed command. It also changes the background panels I created etc etc.
Nearly done and will test your correction in the morning when I'm not braindead.
:)
You might take a look at Reflux; it already does exactly what you describe (changes addon profiles en masse through a slash command) and works even for addons that don't use AceDB-3.0.
function LP:GetAdds()
count = GetNumAddOns()
name = {}
for i=1,count do
name = GetAddOnInfo(i or "name")
end
for i,v in ipairs(name) do
v:SetProfile("Heal")
end
end
I think it is getting a list of the names of the addons, but it is gagging on my SetProfile line. Plus, I'm afraid that messing this part up could do something very bad to a user.
Help?
Why loop twice when you only need to loop once? Also, use "local" liberally. P.S. Declaring a variable as a table and assigning it a string value, makes it a string, thus wasting your RAM on an empty table that never gets used.
function LP:GetAdds()
local count = GetNumAddOns()
for i=1,count do
local name = GetAddOnInfo(i or "name")
-- do what you need to do to get the addon's profile
-- assuming you find and have checked for the existence of profiling and :SetProfile(), set the profile
profileVariable:SetProfile("Heal")
end
end
As to the functionality of the code in this post, here are a few things to note (see the code comments):
function LP:GetAdds()
count = GetNumAddOns() -- [I]count [/I]is global (presumably).
name = {} -- global [I]name [/I]equals empty table
for i=1,count do
name = GetAddOnInfo(i or "name") -- returns a string (the addon's name) not a table
-- if you're intention is to insert the value into the [I]name[/I] table, then
tinsert(name, (GetAddOnInfo(i))) -- note the parentheses around "GetAddOnInfo(i)"
end
for i,v in ipairs(name) do -- due to the above, calling ipairs() with [I]name [/I]as the argument will throw an error at you.
v:SetProfile("Heal") -- even if you use the "tinsert" edit above, [I]v[/I] is a string not a table
end
end
I understood very little of that, sorry. Like this? But the red line doesn't appear to be equal to the green line. (Green works, red doesn't.) It prints a list of unloaded addons though, lol. I tried every combination of things to make it work, but I don't really understand it, just get LUA errors on the red line.
function LP:GetAdds()
count = GetNumAddOns()
name = {}
for i=1,count do
tinsert(name, (GetAddOnInfo(i)))
if IsAddOnLoaded(i) then
--[COLOR=Red]name[i]:SetProfile("Heal")[/COLOR]
[COLOR=Green]Bartender4.db:SetProfile("Heal")[/COLOR]
elseif IsAddOnLoadOnDemand(i) then
local loaded, reason = LoadAddOn(i)
if loaded then
[COLOR=Red]--name[i]:SetProfile("Heal")[/COLOR]
[COLOR=Green]Bartender4.db:SetProfile("Heal")[/COLOR]
else
print(i..":".._G["ADDON_"..reason])
end
end
end
end
As for locals and globals and correct form, I'm looking for someone who will rewrite my code the correct way. For now, I'm just trying to make it work.
Thanks!
Thanks!
The SetProfile just sets addons to that profile name if the user has already created a profile with that name. It won't work on Addons that don't have the Profiles.
Note that when you call SetProfile() with the name of a profile that doesn't already exist, AceDB actually creates that as a new profile and then sets the current profile to it. So watch what you are doing..., you may end up switching profiles to a completely new profile that you didn't want to.
Ah.. that's what Reflux does, and not what I was trying to do. I wanted to do something smaller...
Is there any way to say to the bleeping computer "Read all the mods loaded and IF profile exists, then load it, otherwise do nothing." ? It is ok if it only works for Ace addons, since mostly those are the most popular ones used for UI displays. That'd work on Grid, Bartender etc.
Most addons store their database in ADDONTABLE.db, but not necessarily always there. You will need to know what each addon's name and table is in _G[], or otherwise use AceAddon:IterateAddons() to iterate over all the Ace3 addons and see if any of them used AceDB.
There are several problems with your red lines. Most importantly, in your code, [i]name[i][/i] is a string, not a table with methods you can call. You'd need to look up the global value with that string as its name:
local addon = _G[name[i]]
However, not all addons create a global reference to themselves. Most of my addons don't, and many AceAddon-3.0 addons don't. So, before you go any further, you need to see if the global object actually exists:
if addon then
-- it exists
else
-- it doesn't exist
end
Then, you need to check whether the addon is a table with a [i]db[/i] member:
if type(addon) == "table" and addon.db then
-- yes
else
-- no
end
Finally, you need to check whether the addon's [i]db[/i] member has a SetProfile method. An addon could store its settings in a [i]db[/i] member without using AceDB-3.0, in which case calling :SetProfile on it would result in an error.
if addon.db.SetProfile then
-- yes
else
-- no
end
If the addon meets all of the above criteria, then it's using AceDB-3.0, and you can then use AceDB-3.0's GetProfile API to get a list of profiles defined for that addon.
-- Create a table to reuse.
local profiles = { }
-- Create the function to switch to the target profile.
function LP:SetAllProfiles(target)
-- Loop through all installed addons.
for i = 1, GetNumAddOns() do
-- Get the name of the addon as defined in the Title field of its TOC file.
local addonName = GetAddOnInfo(i)
-- If the addon is LoD and not yet loaded, load it now.
if IsAddOnLoadOnDemand(i) and not IsAddOnLoaded(i) then
LoadAddOn(i)
end
-- If the addon still isn't loaded, we can't do anything with it.
if IsAddOnLoaded(i) then
-- See if the addon is in the global namespace.
local addon = _G[addonName]
-- If the addon is in the global namespace, and is a table,
-- and has a db member that is also a table, and has a
-- GetProfile method on its db member, then we can work with it.
if type(addon) == "table" and type(addon.db) == "table" and addon.db.GetProfiles then
-- Get a list of profiles defined for this addon.
-- Note that we're reusing the profiles table we created earlier,
-- to avoid creating extra tables and wasting memory.
profiles = addon.db:GetProfiles(profiles)
-- Loop through the profiles.
for j, profileName in pairs(profiles) do
-- If the profile name matches our target profile...
if profileName == target then
-- ...then switch to that profile...
addon.db:SetProfile(profileName)
-- ...and don't bother looking at the rest of this addon's profiles.
break
end
end
end
end
end
end
As a general rule, [i]all[/i] variables should be defined as local, unless you need them to be accessible to other addons. For what you're doing, nothing needs to be accessible to other addons.
The code posted above for function SetAllProfiles, causes a lua error when trying to type /dbm.
I really can't see why...
DBM-GUI.lua line 1900, attempt to index field 'stats' a nil value.
If this function isn't loaded, this error doesn't occur. Also when clicking the DBM icon, the error doesn't occur. It's only when trying to type /dbm. It also doesn't occur on the other addons.
for _, mod in ipairs(DBM.Mods) do
if mod.modId == addon.modId and (not subtab or subtab == mod.subTab) then
local party = false
bossstats = bossstats + 1
line 1900:
local bossvalue1 = area:CreateText(mod.stats.normalKills, nil, nil, GameFontNormalSmall, "LEFT")
Try updating DBM; I just downloaded the latest version from deadlybossmods.com, and line 1900 in DBM-GUI.lua is a blank line. Other than that, I can't see anything in the code I posted that should be able to break anything; there are no globals, and it doesn't alter anything about any addon. DBM isn't even using AceDB-3.0, or defining a "db" member on any of its global tables as far as I saw.
Also, by "loading" do you mean just having the function written in your Lua file, or do you mean actually calling the function? If it's the former (the function's mere existence breaks DBM) then there is something else wrong in your code.
Rollback Post to RevisionRollBack
To post a comment, please login or register a new account.
-Detect Addons Loaded
-If profile named "Heal" exists, please load it.
I can hard code it, like: Bartender4.db:SetProfile("Heal")
Now if possible I'd like to Autodetect the addons.
Thanks.
http://www.wowwiki.com/API_GetNumAddOns
I think it is getting a list of the names of the addons, but it is gagging on my SetProfile line. Plus, I'm afraid that messing this part up could do something very bad to a user.
Help?
I don't know what SetProfile() is supposed to be doing or why you assume every addon will support such a method.
I just corrected the obvious errors about tables and such.
The SetProfile just sets addons to that profile name if the user has already created a profile with that name. It won't work on Addons that don't have the Profiles.
So my mod can let people change their UI depending on their role, by typing /heal or /dps or /tank. So I can move my Grid, move my Bartender buttons, load or unload Recount, etc, with just a typed command. It also changes the background panels I created etc etc.
Nearly done and will test your correction in the morning when I'm not braindead.
:)
Why loop twice when you only need to loop once? Also, use "local" liberally. P.S. Declaring a variable as a table and assigning it a string value, makes it a string, thus wasting your RAM on an empty table that never gets used.
As to the functionality of the code in this post, here are a few things to note (see the code comments):
As for locals and globals and correct form, I'm looking for someone who will rewrite my code the correct way. For now, I'm just trying to make it work.
Thanks!
Note that when you call SetProfile() with the name of a profile that doesn't already exist, AceDB actually creates that as a new profile and then sets the current profile to it. So watch what you are doing..., you may end up switching profiles to a completely new profile that you didn't want to.
Is there any way to say to the bleeping computer "Read all the mods loaded and IF profile exists, then load it, otherwise do nothing." ? It is ok if it only works for Ace addons, since mostly those are the most popular ones used for UI displays. That'd work on Grid, Bartender etc.
http://www.wowace.com/addons/ace3/pages/api/ace-db-3-0/#w-dbobject-lib-get-profiles-tbl
There are several problems with your red lines. Most importantly, in your code, [i]name[i][/i] is a string, not a table with methods you can call. You'd need to look up the global value with that string as its name:
However, not all addons create a global reference to themselves. Most of my addons don't, and many AceAddon-3.0 addons don't. So, before you go any further, you need to see if the global object actually exists:
Then, you need to check whether the addon is a table with a [i]db[/i] member:
Finally, you need to check whether the addon's [i]db[/i] member has a SetProfile method. An addon could store its settings in a [i]db[/i] member without using AceDB-3.0, in which case calling :SetProfile on it would result in an error.
If the addon meets all of the above criteria, then it's using AceDB-3.0, and you can then use AceDB-3.0's GetProfile API to get a list of profiles defined for that addon.
As a general rule, [i]all[/i] variables should be defined as local, unless you need them to be accessible to other addons. For what you're doing, nothing needs to be accessible to other addons.
That worked and it's so very neat-o, and doesn't even require a reload ui. :cool:
Is it possible to do manual fixes in case of names not matching, like:
As you said, some of the DB names don't match with the addon names, and it would be nice to add a fix just for the more popular UI addons.
Then:
I really can't see why...
DBM-GUI.lua line 1900, attempt to index field 'stats' a nil value.
If this function isn't loaded, this error doesn't occur. Also when clicking the DBM icon, the error doesn't occur. It's only when trying to type /dbm. It also doesn't occur on the other addons.
Any ideas?
line 1900:
Also errors on a bunch of other mods, as reported by users, so I have commented out the code here:
http://www.wowinterface.com/downloads/info18529-Tattoo.html
(You can see in comments that this part isn't working.)
It really worked very nicely on the main mods, but those errors, i don't know.
I can't do this by hand either, because the very simple code:
This errors when Grid's disabled, so I have to do something to check if loaded. Which I'm afraid I don't know how to do that either.
Also, by "loading" do you mean just having the function written in your Lua file, or do you mean actually calling the function? If it's the former (the function's mere existence breaks DBM) then there is something else wrong in your code.