WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   Addon_action_blocked (https://www.wowinterface.com/forums/showthread.php?t=49196)

cokedrivers 04-21-14 09:00 AM

So I'm Still getting errors with boss frames,

So I was wondering would this be the correct way to adjust the scale of a boss frame?

Code:

                local BossFrame = CreateFrame("Frame");
                BossFrame:RegisterEvent("INSTANCE_ENCOUNTER_ENGAGE_UNIT")
                BossFrame:SetScript("OnEvent",
                        for i = 1, MAX_BOSS_FRAMES do
                                local bossFrame = "Boss"..i.."TargetFrame"
                                _G[bossFrame]:SetScale(db.unitframes.boss.scale);       
                        end;
                end)

Because as far as "Boss Frame" this is the only thing I have in my code that directly points to a boss frame.

Thanks
Coke

Phanx 04-21-14 09:42 AM

Boss frames, like all unit frames, are secure. You cannot change their scale, size, position, visibility, or many other properties while in combat. Since your code does not check whether you're in combat when you try to change the scale, you will get "action blocked" errors every time the boss list changes in combat.

However, I'm not really sure why you're even listening for that event... I haven't looked at the Blizzard code, but I'd wager actual money that they never call SetScale on the boss frames, or any other unit frames, so you don't need to keep re-setting the scale over and over. Just do it once when your addon loads.

Duugu 04-21-14 10:13 AM

Quote:

Originally Posted by Phanx (Post 292217)
However, I'm not really sure why you're even listening for that event... I haven't looked at the Blizzard code, but I'd wager actual money that they never call SetScale on the boss frames, or any other unit frames, so you don't need to keep re-setting the scale over and over. Just do it once when your addon loads.

Actually they do. But only in BossTargetFrame_OnLoad. And all the frames should be available on entering world.

cokedrivers 04-21-14 10:31 AM

Quote:

Originally Posted by Phanx (Post 292217)
Boss frames, like all unit frames, are secure. You cannot change their scale, size, position, visibility, or many other properties while in combat. Since your code does not check whether you're in combat when you try to change the scale, you will get "action blocked" errors every time the boss list changes in combat.

However, I'm not really sure why you're even listening for that event... I haven't looked at the Blizzard code, but I'd wager actual money that they never call SetScale on the boss frames, or any other unit frames, so you don't need to keep re-setting the scale over and over. Just do it once when your addon loads.

Quote:

Originally Posted by Duugu (Post 292222)
Actually they do. But only in BossTargetFrame_OnLoad. And all the frames should be available on entering world.

Ok so couple questions:

1st) Am I doing the coding correctly?
2nd) Should I look for a different event or should the code be in a hooksecure?

And thanks for the quick replies.

Also I'm working on rewiting the unitframes.lua of my addon and so far this is what I have...

http://pastebin.com/Z6BuyStU

Coke

Phanx 04-21-14 12:40 PM

OnLoad functions are called at the same time the frame is created, so the end result is the same -- the scale of the frames is never changed after the frames are created, and the frames are already created before the game starts loading any addons, so just change the scale immediately when your addon is read. You don't need to listen for any special events at all.

However, since you do need to wait for your saved variables to load, you should make sure you're not logging in in combat before attempting to do anything secure. To avoid having to split up your code or add a bunch of extra checks, and since you're just tweaking, not creating new frames or anything else critical, I'd suggest just delaying the whole thing in that case, eg.

Code:

function MyAddon:OnEnable()
    if InCombatLockdown() then
          return self:RegisterEvent("PLAYER_REGEN_ENABLED", "OnEnable")
    end

Anyway, here's a revised version of your unitframes module. I did a LOT of cleanup in the individual unit sections; the default UI never changes scales or fonts after creating the frames, so there's no need to listen for events, and even if there were, you should use your module object to listen for them, instead of creating new frames for every unit.

http://pastebin.com/f1DKpNeG

cokedrivers 04-21-14 03:55 PM

Quote:

Originally Posted by Phanx (Post 292227)
OnLoad functions are called at the same time the frame is created, so the end result is the same -- the scale of the frames is never changed after the frames are created, and the frames are already created before the game starts loading any addons, so just change the scale immediately when your addon is read. You don't need to listen for any special events at all.

However, since you do need to wait for your saved variables to load, you should make sure you're not logging in in combat before attempting to do anything secure. To avoid having to split up your code or add a bunch of extra checks, and since you're just tweaking, not creating new frames or anything else critical, I'd suggest just delaying the whole thing in that case, eg.

Code:

function MyAddon:OnEnable()
    if InCombatLockdown() then
          return self:RegisterEvent("PLAYER_REGEN_ENABLED", "OnEnable")
    end

Anyway, here's a revised version of your unitframes module. I did a LOT of cleanup in the individual unit sections; the default UI never changes scales or fonts after creating the frames, so there's no need to listen for events, and even if there were, you should use your module object to listen for them, instead of creating new frames for every unit.

http://pastebin.com/f1DKpNeG

Thank You for the help yet again.

For some reason im getting a error with the "for" in the arena part of the Module.UnitFunctions could this be because the arena frams are not loaded at the start of the game?

If I --[[ ]] the arena code all is good.

Here is the error:
Code:

1x BasicUI-5.4.7\Modules\Unitframes.lua:174: "for" limit must be a number
BasicUI-5.4.7\Modules\Unitframes.lua:174: in function "func"
BasicUI-5.4.7\Modules\Unitframes.lua:51: in function <BasicUI\Modules\Unitframes.lua:37>
(tail call): ?
<in C code>
<string>:"safecall Dispatcher[1]":9: in function <string>:"safecall Dispatcher[1]":5
(tail call): ?
AuctionLite-v1.8.12\Libs\AceAddon-3.0\AceAddon-3.0-12.lua:558: in function "EnableAddon"
AuctionLite-v1.8.12\Libs\AceAddon-3.0\AceAddon-3.0-12.lua:571: in function "EnableAddon"
AuctionLite-v1.8.12\Libs\AceAddon-3.0\AceAddon-3.0-12.lua:651: in function <AuctionLite\Libs\AceAddon-3.0\AceAddon-3.0.lua:636>
<in C code>
FrameXML\UIParent.lua:306: in function "UIParentLoadAddOn"
FrameXML\UIParent.lua:329: in function "CombatLog_LoadUI"
FrameXML\UIParent.lua:742: in function <FrameXML\UIParent.lua:705>

Locals:
nil

Coke

Clamsoda 04-21-14 05:42 PM

Nothing related to the arena frames is available until Blizzard_ArenaUI is loaded. I can confirm that it does not become loaded upon normal log-in circumstances.

You need to execute the relevant code once Blizzard_ArenaUI has been loaded; listening to ADDON_LOADED can provide you with that information.

Phanx has much more time invested into your code, I'd rather let her deal with refactoring it to allow for the circumstance.

Edit: The reasoning behind the error is that your for limit, MAX_ARENA_ENEMIES, is a nil value.

Phanx 04-21-14 07:03 PM

http://pastebin.com/Lxh5k5RX

This should handle the arena issue, as well as any future issues if you decided to add support for, say, compact raid frames in here.

cokedrivers 04-22-14 08:09 AM

Quote:

Originally Posted by Phanx (Post 292245)
http://pastebin.com/Lxh5k5RX

This should handle the arena issue, as well as any future issues if you decided to add support fo;-)r, say, compact raid frames in here.

Thank you for the help, everything seems to be working.

Tonight ill try a boss encounter and a arena event to make sure.

Now beings everything is in the OnEnable function, how would I use that for my options just point to the OnEnable as the function for set? So that the user doesnt have to do a reloadui. Or is that just opening another bag of worms?

Again thanks for all the help, I wish there was something I could do to return all the help you have given me, and all the future help im sure i will need... ;-)

Coke

Phanx 04-22-14 06:13 PM

http://pastebin.com/YD7jiW51

Call the ApplySettings method from your options, eg.

Code:

local Core = LibStub("AceAddon-3.0"):GetAddon("BasicUI")
local Unitframes = Core:GetModule("Unitframes")
Unitframes:ApplySettings()


cokedrivers 04-22-14 10:47 PM

Quote:

Originally Posted by Phanx (Post 292285)
http://pastebin.com/YD7jiW51

Call the ApplySettings method from your options, eg.

Code:

local Core = LibStub("AceAddon-3.0"):GetAddon("BasicUI")
local Unitframes = Core:GetModule("Unitframes")
Unitframes:ApplySettings()


Thank You AGAIN....

Coke

cokedrivers 04-23-14 08:47 PM

One last question on unitframes...
With the new way of calling the party and boss frames in a function and beings they are load on demand (I think) frames would I now be able to add a SetPoint() to them in there current state without getting a sucure frame error?

Reason I ask (I did notice in one of your other threads you suggested a option to hide the quest tracker) beings have adjusted the scale of the party and boss frames they are now overlapping other frames and it looks tacky. On any toon that has a "powerbar" and a pet for example a Warnock the first party members name is under the pet frame. So as I stated I would like to ad a SetPoint() but last time I tried this it completely hid the raid frames. I'm guessing the reason for this is the pop out window for the raid frames it is attached to the party frames or visa versa.

I know a lot of explaining but i would rather let you know the why not just a question.

Coke

Phanx 04-23-14 09:41 PM

Quote:

Originally Posted by cokedrivers (Post 292307)
With the new way of calling the party and boss frames in a function and beings they are load on demand (I think) frames would I now be able to add a SetPoint() to them in there current state without getting a sucure frame error?

Yes, but there's no way to stop the default UI from moving them back to the original position.

For party frames, it doesn't look like the default UI moves them after loading, so just adding this should be fine:
Code:

PartyMemberFrame1:ClearAllPoints()
PartyMemberFrame1:SetPoint("TOPLEFT", UIParent, 100, -300)

Boss frames are a bit trickier, since the UI panel manager system moves them around all the time.
Code:

local movingBossFrame
hooksecurefunc(Boss1TargetFrame, "SetPoint", function(f, ...)
        if movingBossFrame or InCombatLockdown() then
                return
        end
        movingBossFrame = true
        Boss1TargetFrame:ClearAllPoints()
        Boss1TargetFrame:SetPoint("TOPRIGHT", -100, -300)
        movingBossFrame = nil
end)

If you notice it getting moved in combat (when you can't move it back) you'll also need to listen for combat ending so you can move it then.

Both of these should go in the OnEnable function, not in the individual unit frame functions -- those should only contain the code that applies the user's settings, and definitely shouldn't include any hook creation, since you can't remove or replace a secure hook, only add a new one.

cokedrivers 04-23-14 10:15 PM

Quote:

Originally Posted by Phanx (Post 292308)
Yes, but there's no way to stop the default UI from moving them back to the original position.

For party frames, it doesn't look like the default UI moves them after loading, so just adding this should be fine:
Code:

PartyMemberFrame1:ClearAllPoints()
PartyMemberFrame1:SetPoint("TOPLEFT", UIParent, 100, -300)

Boss frames are a bit trickier, since the UI panel manager system moves them around all the time.
Code:

local movingBossFrame
hooksecurefunc(Boss1TargetFrame, "SetPoint", function(f, ...)
        if movingBossFrame or InCombatLockdown() then
                return
        end
        movingBossFrame = true
        Boss1TargetFrame:ClearAllPoints()
        Boss1TargetFrame:SetPoint("TOPRIGHT", -100, -300)
        movingBossFrame = nil
end)

If you notice it getting moved in combat (when you can't move it back) you'll also need to listen for combat ending so you can move it then.

Both of these should go in the OnEnable function, not in the individual unit frame functions -- those should only contain the code that applies the user's settings, and definitely shouldn't include any hook creation, since you can't remove or replace a secure hook, only add a new one.

I really, really appreciate all the help you have given me. One day (might take a year not a day) I will find a lua programmers guide (looked into the WoW Programmers Guide version 2) and learn all these name, func, v, k, and other symbols/terms and what they actually mean.

Thanks
Coke

Clamsoda 04-24-14 09:03 PM

Func is just short for function, at least in reference to hooksecurefunc.

K and V typically refer to key and value, for use in iterating over a table with pairs or ipairs. In reality, those variables can be named anything.

Phanx 04-24-14 09:06 PM

Quote:

Originally Posted by cokedrivers (Post 292309)
... learn all these name, func, v, k, and other symbols/terms and what they actually mean.

None of those are Lua language keywords (eg. "local", "and", "function"), Lua functions (eg. "tonumber", "pairs"), or WoW API functions (eg. "UnitName", "GetGameTime"), so that means they don't "actually mean" anything -- they're just variable names. :P

Obviously, a variable name like "func" would probably be pointing to a function value, but "name" could be a lot of things (a player name, a frame name, an item name, a guild name, an NPC name, a spell name, etc.). "k" and "v" are normally used in pairs loops to represent the keys and values, respectively:

Code:

-- Given this table:
local t = {
    cat = "meow",
    dog = "woof",
    pig = "oink",
}
-- This:
for k, v in pairs(t) do
    print(format("The %s says %s.", k, v))
end
-- Is the same as this:
for animal, sound in pairs(t) do
    print(format("The %s says %s.", animal, sound))
end
-- Is the same as this:
for refdsaf, uiopioj in pairs(t) do
    print(format("The %s says %s.", refdsaf, uiopioj))
end

Like using an underscore to name a variable whose value you don't care about, using k and v to name the variables pointing to the keys and values in a loop over a table is just a convention. There's nothing magical about those variable names, just as there's nothing magical about using an underscore as a variable name; it just means that the purpose of those variables is immediately obvious, whereas in the example above, it's not immediately obvious what a variable like "uipioj" might be pointing at until you read more of the code to get context.

Similarly, "i" is commonly used in loops to represent the iteration count:
Code:

for i = 1, 10 do
    print("This is loop iteration #" .. i)
end

However, you could just as easily use it for something else:

Code:

local k, v, i, name, func = GetFriendInfo(1)
... though I wouldn't recommend it, since in that context those variable names aren't meaningful and don't help you keep track of the information they contain.

cokedrivers 04-25-14 11:16 AM

Ok now im starting to see it, as you stated "k" is normal short for "key" and "v" is short for "value" just like I see "f" for "frame".

Now is this normally the standard or do different people use different letters, also would it be beneficial to use different letters not to accidently interact with other peoples functions?

In this example:
Lua Code:
  1. self.plugins = {}
  2. for name, constructor in pairs(self.pluginConstructors) do
  3.     local position = db.datapanel[name]
  4.     if position and position > 0 then
  5.         local plugin = constructor()
  6.         self.plugins[name] = plugin
  7.         self:PlacePlugin(position, plugin)
  8.     end
  9. end

name = the name of the plugin.
constructor = ?? Where did the constructor() function come from?

And why is it I see a lot of people do somename = {} I understand the the {} is the start and finish of a table but wouldn't if just be a blank table.

Also does the [] around a "name" make it so that it could be any "name" in that table, so instead fo using db.datapanel.dps and db.datapanel.hps, db.datapanel[name] would be able to find both of those name in a shorter text.

It was stated before that this is a file not a macro so we should not shorten names because there is no need to save space. If that is the case why do I see a lot of other using short cuts and abbreviated name?

Thanks for answering these questions and helping me and maybe others trying to learn this wonderful thing called lua.

Coke

Seerah 04-25-14 11:39 AM

As stated above, k and v are just regular old variables. You could use anything else in their place. This is what has been done with your example. Instead of doing
Lua Code:
  1. for k, v in pairs(self.pluginConstructors) do
They did
Lua Code:
  1. for name, constructor in pairs(self.pluginConstructors) do
Since constructor turns out to be a function that they can call later in that statement,
Lua Code:
  1. local plugin = constructor()
I assume that the table self.pluginConstructors is structured like this:
Lua Code:
  1. self.pluginConstructors = {
  2.      pluginName1 = constructorFunction1,
  3.      pluginName2 = constructorFunction2,
  4.      pluginName3 = constructorFunction3,
  5. }

Seerah 04-25-14 11:45 AM

Forgot to address these:

Quote:

Originally Posted by cokedrivers (Post 292325)
And why is it I see a lot of people do somename = {} I understand the the {} is the start and finish of a table but wouldn't if just be a blank table.

They are defining self.plugins to be a table before they start putting things into it. Otherwise you'll get an error for treating self.plugins as a table when it hasn't been made into a table yet. ;)

Quote:

Also does the [] around a "name" make it so that it could be any "name" in that table, so instead fo using db.datapanel.dps and db.datapanel.hps, db.datapanel[name] would be able to find both of those name in a shorter text.
name is whatever is assigned to it in the pairs loop.

Quote:

It was stated before that this is a file not a macro so we should not shorten names because there is no need to save space. If that is the case why do I see a lot of other using short cuts and abbreviated name?
They're not doing it to save space. They're just coding and using variables - you can use whatever variable names you want to, so long as things still make sense when you come back and look at your code a year or two from now.

cokedrivers 04-25-14 11:55 AM

Quote:

Originally Posted by Seerah (Post 292327)
As stated above, k and v are just regular old variables. You could use anything else in their place. This is what has been done with your example. Instead of doing
Lua Code:
  1. for k, v in pairs(self.pluginConstructors) do
They did
Lua Code:
  1. for name, constructor in pairs(self.pluginConstructors) do
Since constructor turns out to be a function that they can call later in that statement,
Lua Code:
  1. local plugin = constructor()
I assume that the table self.pluginConstructors is structured like this:
Lua Code:
  1. self.pluginConstructors = {
  2.      pluginName1 = constructorFunction1,
  3.      pluginName2 = constructorFunction2,
  4.      pluginName3 = constructorFunction3,
  5. }

Quote:

Originally Posted by Seerah (Post 292328)
Forgot to address these:


They are defining self.plugins to be a table before they start putting things into it. Otherwise you'll get an error for treating self.plugins as a table when it hasn't been made into a table yet. ;)


name is whatever is assigned to it in the pairs loop.


They're not doing it to save space. They're just coding and using variables - you can use whatever variable names you want to, so long as things still make sense when you come back and look at your code a year or two from now.

Thank You for these descriptions and explanations. I still have a long way to go but with the great people at WoWInterface there is a light at the end of the LONG tunnel.

Coke


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

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI