Thread Tools Display Modes
09-06-14, 07:41 PM   #1
Wimpface
A Molten Giant
 
Wimpface's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 648
Chicchai and docked chat frames

I was recently told one of my favorite AddOns, Chicchai, still worked. I downloaded and installed it, and it does! But, not without bugs as is expected of a 4 year old AddOn.

My problem is with docked chat frames, as the title says. The AddOn works perfectly fine if you undock every chat window, but the second you dock any you run into an error and the addon stops working correctly.

This is the error
Code:
Message: Interface\AddOns\Chicchai\core.lua:182: attempt to index local 'self' (a nil value)
Time: 09/07/14 03:40:40
Count: 1
Stack: Interface\AddOns\Chicchai\core.lua:182: in function `updateHeight'
Interface\AddOns\Chicchai\core.lua:224: in main chunk
Here's the code
Lua Code:
  1. --[[            Chicchai
  2. ]]--    by Lolzen & Cargor (EU-Nozdormu)
  3.  
  4. -- Configuration
  5. local maxHeight = 123               -- How high the chat frames are when maximized
  6. local animTime = 0.3                -- How lang the animation takes (in seconds)
  7. local minimizeTime = 10             -- Minimize after X seconds
  8. local minimizedLines = 1            -- Number of chat messages to show in minimized state
  9.  
  10. local MaximizeOnEnter = true        -- Maximize when entering chat frame, minimize when leaving
  11. local WaitAfterEnter = 0            -- Wait X seconds after entering before maximizing
  12. local WaitAfterLeave = 0            -- Wait X seconds after leaving before minimizing
  13.  
  14. local LockInCombat = nil            -- Do not maximize in combat
  15.  
  16. local MaximizeCombatLog = true      -- When the combat log is selected, it will be maximized
  17.  
  18. -- Modify this to maximize only on special channels
  19. -- comment/remove it to react on all channels
  20. -- you still need the "channel"-event on your chat frame!
  21. local channelNumbers = {
  22.     [1] = true,
  23.     [2] = true,
  24.     [3]  = true,
  25. }
  26.  
  27. local ChatFrameConfig = {   -- Events which maximize the chat for the different windows
  28.     ["ChatFrame1"] = {
  29.         "say", "emote", "text_emote",
  30.         "party", "party_leader", "party_guide",
  31.         "whisper",
  32.         "guild", "officer",
  33.         "battleground", "battleground_leader",
  34.         "raid", "raid_leader", "raid_warning",
  35.         "instance_chat", "instance_chat_leader",
  36.    
  37.         "bn_whisper",
  38.         "bn_conversation",
  39.         "bn_broadcast",
  40.     },
  41.     ["ChatFrame2"] = true, -- "true" just makes this frame available for minimizing and registers it with Chicchai
  42.     ["ChatFrame3"] = true, -- "true" just makes this frame available for minimizing and registers it with Chicchai
  43.     ["ChatFrame4"] = true, -- "true" just makes this frame available for minimizing and registers it with Chicchai
  44. }
  45.  
  46. --[[
  47.     REFERENCE LIST
  48.     These are the available chat events for ChatFrameConfig
  49.         say, yell, emote, text_emote,
  50.         party, party_leader, party_guide,
  51.         whisper, whisper_inform, afk, dnd, ignored,
  52.         guild, officer,
  53.         channel, channel_join, channel_leave, channel_list, channel_notice, channel_notice_user,
  54.         battleground, battleground_leader,
  55.         raid, raid_leader, raid_warning,
  56.  
  57.         bn_whisper, bn_whisper_inform,
  58.         bn_conversation, bn_conversation_notice, bn_conversation_list,
  59.         bn_alert,
  60.         bn_broadcast, bn_broadcast_inform,
  61.         bn_inline_toast_alert, bn_inline_toast_broadcast, bn_inline_toast_broadcast_inform, bn_inline_toast_conversation,
  62.  
  63.         system, achievement, guild_achievement,
  64.         bg_system_neutral, bg_system_alliance, bg_system_horde,
  65.         monster_say, monster_party, monster_yell, monster_whisper, monster_emote,
  66.         raid_boss_whisper, raid_boss_emote,
  67.         skill, loot, money, opening, tradeskills, pet_info, combat_misc_info, combat_xp_gain, combat_honor_gain, combat_faction_change,
  68. ]]
  69. -- Configuration End
  70. -- Do not change anything under this line except you know what you're doing (:
  71.  
  72.  
  73.  
  74. local select = select
  75. local UP, DOWN = 1, -1
  76.  
  77. local function getMinHeight(self)
  78.     local minHeight = 0
  79.     for i=1, minimizedLines do
  80.         local line = select(9+i, self:GetRegions())
  81.         if(line) then
  82.             minHeight = minHeight + line:GetHeight() + 2.5
  83.         end
  84.     end
  85.     if(minHeight == 0) then
  86.         minHeight = select(2, self:GetFont()) + 2.5
  87.     end
  88.     return minHeight
  89. end
  90.  
  91. local function Update(self, elapsed)
  92.     if(self.WaitTime) then
  93.         self.WaitTime = self.WaitTime - elapsed
  94.         if(self.WaitTime > 0) then return end
  95.         self.WaitTime = nil
  96.         if(self.Frozen) then return self:Hide() end
  97.     end
  98.  
  99.     self.State = nil
  100.  
  101.     self.TimeRunning = self.TimeRunning + elapsed
  102.     local animPercent = min(self.TimeRunning/animTime, 1)
  103.  
  104.     local heightPercent = self.Animate == DOWN and 1-animPercent or animPercent
  105.  
  106.     local minHeight = getMinHeight(self.Frame)
  107.     self.Frame:SetHeight(minHeight + (maxHeight-minHeight) * heightPercent)
  108.  
  109.     if(animPercent >= 1) then
  110.         self.State = self.Animate
  111.         self.Animate = nil
  112.         self.TimeRunning = nil
  113.         self:Hide()
  114.         if(self.finishedFunc) then self:finishedFunc() end
  115.     end
  116. end
  117.  
  118. local function getChicchai(self)
  119.     if(self:GetObjectType() == "Frame") then self = self.Frame  end
  120.     if(self.isDocked) then self = GENERAL_CHAT_DOCK.DOCKED_CHAT_FRAMES[1] end
  121.     return self.Chicchai
  122. end
  123.  
  124. local function SetFrozen(self, isFrozen)
  125.     getChicchai(self).Frozen = isFrozen
  126. end
  127.  
  128. local function Animate(self, dir, waitTime, finishedFunc)
  129.     local self = getChicchai(self)
  130.     if(self.Frozen) then return end
  131.     if(self.Animate == dir or self.State == dir and not self.Animate) then return end
  132.  
  133.     if(self.Animate == -dir) then
  134.         self.TimeRunning = animTime - self.TimeRunning
  135.     else
  136.         self.TimeRunning = 0
  137.     end
  138.     self.WaitTime = waitTime
  139.     self.Animate = dir
  140.     self.finishedFunc = finishedFunc
  141.     self:Show()
  142. end
  143.  
  144. local function Maximize(self) Animate(self, UP) end
  145. local function Minimize(self) Animate(self, DOWN) end
  146.  
  147. local function MinimizeAfterWait(self)
  148.     Animate(self, DOWN, minimizeTime)
  149. end
  150.  
  151. local CheckEnterLeave
  152. if(MaximizeOnEnter) then
  153.     CheckEnterLeave = function(self)
  154.         self = getChicchai(self)
  155.         if(MouseIsOver(self.Frame) and not self.wasOver) then
  156.             self.wasOver = true
  157.             Animate(self, UP, WaitAfterEnter)
  158.         elseif(self.wasOver and not MouseIsOver(self.Frame)) then
  159.             self.wasOver = nil
  160.             Animate(self, DOWN, WaitAfterLeave)
  161.         end
  162.     end
  163. end
  164.  
  165. if(MaximizeCombatLog) then
  166.     hooksecurefunc("FCF_Tab_OnClick", function(self)
  167.         local frame = getChicchai(ChatFrame2)
  168.         if(not frame) then return end
  169.  
  170.         if(self == ChatFrame2Tab) then
  171.             Animate(frame, UP)
  172.             SetFrozen(frame, true)
  173.         elseif(frame.Frozen) then
  174.             SetFrozen(frame, nil)
  175.             Animate(frame, DOWN)
  176.         end
  177.     end)
  178. end
  179.  
  180. local function updateHeight(self)
  181.     local self = getChicchai(self)
  182.     if(self.State ~= DOWN) then return end
  183.     self.Frame:ScrollToBottom()
  184.     self.Frame:SetHeight(getMinHeight(self.Frame))
  185. end
  186.  
  187. local function chatEvent(self)
  188.     if(event == "CHAT_MSG_CHANNEL" and channelNumbers and not channelNumbers[arg8]) then return end
  189.  
  190.     if(not LockInCombat or not UnitAffectingCombat("player")) then
  191.         Animate(self, UP, nil, MinimizeAfterWait)
  192.     end
  193. end
  194.  
  195. for chatname, options in pairs(ChatFrameConfig) do
  196.     local chatframe = _G[chatname]
  197.     local chicchai = CreateFrame"Frame"
  198.     if(MaximizeOnEnter) then
  199.         local updater = CreateFrame("Frame", nil, chatframe)
  200.         updater:SetScript("OnUpdate", CheckEnterLeave)
  201.         updater.Frame = chatframe
  202.     end
  203.     chicchai.Frame = chatframe
  204.     chatframe.Chicchai = chicchai
  205.     if(type(options) == "table") then
  206.         for _, event in pairs(options) do
  207.             if(not event:match("[A-Z]")) then
  208.                 event = "CHAT_MSG_"..event:upper()
  209.             end
  210.             chicchai:RegisterEvent(event)
  211.         end
  212.     end
  213.     ChatFrameConfig[chatname] = chicchai
  214.    
  215.     chatframe.Maximize = Maximize
  216.     chatframe.Minimize = Minimize
  217.     chatframe.UpdateHeight = updateHeight
  218.     chatframe.SetFrozen = SetFrozen
  219.  
  220.     chicchai:SetScript("OnUpdate", Update)
  221.     chicchai:SetScript("OnEvent", chatEvent)
  222.     chicchai:Hide()
  223.  
  224.     updateHeight(chatframe)
  225.  
  226.     hooksecurefunc(chatframe, "AddMessage", updateHeight)
  227. end
  228.  
  229. _G.Chicchai = ChatFrameConfig

Does anyone know how to fix this?

EDIT: Found another error! When switching to the docked chat frames, it throws this error. And it throws it a lot.
Code:
Message: Interface\AddOns\Chicchai\core.lua:155: attempt to index local 'self' (a nil value)
Time: 09/07/14 03:42:21
Count: 166
Stack: [C]: ?
Interface\AddOns\Chicchai\core.lua:155: in function <Interface\AddOns\Chicchai\core.lua:153>
__________________
All I see is strobe lights blinding me in my hindsight.
  Reply With Quote
09-07-14, 10:30 AM   #2
myrroddin
A Pyroguard Emberseer
 
myrroddin's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 1,240
I'm not going to fine-tooth comb the code, but this chunk at line 180 doesn't look like it should work correctly.
Code:
local function updateHeight(self)
    local self = getChicchai(self)
    if(self.State ~= DOWN) then return end
    self.Frame:ScrollToBottom()
    self.Frame:SetHeight(getMinHeight(self.Frame))
end
Let me get this straight:
  1. Pass self (presumably the AddOn reference?) to the function updateHeight
  2. Immediately overwrite self with an entirely new value (why??)
  3. If the new value is anything other than DOWN, exit out
No wonder self is throwing nil errors. Based on a cursory look at the code, how in the world are you, as a follow-up author, supposed to keep track of what self is referring?

If I understand that chunk correctly, using different names that are descriptive, it goes like this:

Hey function, here is Bob. Now use a Star Trek transporter to make a copy of Bob, and assign Bob's copy the DNA of Bob's uncle Tony, but still call the copy Bob. Bob is still here, and we have a copy of Bob that looks like Tony. Bob isn't doing anything, so he sits down and reads a book.

Tony looks around confused, thinking he is in the wrong home, and has no clue why. Meanwhile BobTony is feeling emotional, but only sticks around if he is feeling down. If he is feeling up, he bolts and goes plays some Diablo III. Smart guy, BobTony!

On track, add some debug prints before and after line 181. Both should print out the value of self. See what you get.

Last edited by myrroddin : 09-07-14 at 10:43 AM. Reason: Silly narrative?
  Reply With Quote
09-07-14, 10:42 AM   #3
Wimpface
A Molten Giant
 
Wimpface's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 648
Originally Posted by myrroddin View Post
I'm not going to fine-tooth comb the code, but this chunk at line 180 doesn't look like it should work correctly.
Code:
local function updateHeight(self)
    local self = getChicchai(self)
    if(self.State ~= DOWN) then return end
    self.Frame:ScrollToBottom()
    self.Frame:SetHeight(getMinHeight(self.Frame))
end
Let me get this straight:
  1. Pass self (presumably the AddOn reference?) to the function updateHeight
  2. Immediately overwrite self with an entirely new value (why??)
  3. If the new value is anything other than DOWN, exit out
No wonder self is throwing nil errors. Based on a cursory look at the code, how in the world are you, as a follow-up author, supposed to keep track of what self is referring?
I have no idea how it works, the code is really confusing to me. That block of code is the one that's throwing most errors and the only one that straight up breaks the addon to force it into a permanently minimized state.

This chunk at line 151 throws an error sometimes too, and stops the chat frame from being maximized on mouseover. It works after a reload though, so I'm not sure what's wrong.
Lua Code:
  1. local CheckEnterLeave
  2. if(MaximizeOnEnter) then
  3.     CheckEnterLeave = function(self)
  4.         self = getChicchai(self)
  5.         if(MouseIsOver(self.Frame) and not self.wasOver) then
  6.             self.wasOver = true
  7.             Animate(self, UP, WaitAfterEnter)
  8.         elseif(self.wasOver and not MouseIsOver(self.Frame)) then
  9.             self.wasOver = nil
  10.             Animate(self, DOWN, WaitAfterLeave)
  11.         end
  12.     end
  13. end
__________________
All I see is strobe lights blinding me in my hindsight.
  Reply With Quote
09-07-14, 10:50 AM   #4
myrroddin
A Pyroguard Emberseer
 
myrroddin's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 1,240
Yeah, that line 151 bit is horrendous. That should be using OnEnter and OnLeave scripts.

I'm thinking this whole AddOn is an example of what not to do when writing code, and depending on what the AddOn does (sorry, haven't checked yet), might be worth rewriting from scratch. Hmm, it needs a complete rewrite regardless; I was musing the worthiness of the venture.
  Reply With Quote
09-07-14, 10:55 AM   #5
myrroddin
A Pyroguard Emberseer
 
myrroddin's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 1,240
I think this AddOn will have to be rewritten for WoD, as I seem to recall there will be enough changes to various APIs such as animation that it won't work in its current state.
  Reply With Quote
09-07-14, 12:23 PM   #6
Wimpface
A Molten Giant
 
Wimpface's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 648
Originally Posted by myrroddin View Post
Yeah, that line 151 bit is horrendous. That should be using OnEnter and OnLeave scripts.

I'm thinking this whole AddOn is an example of what not to do when writing code, and depending on what the AddOn does (sorry, haven't checked yet), might be worth rewriting from scratch. Hmm, it needs a complete rewrite regardless; I was musing the worthiness of the venture.

Originally Posted by myrroddin View Post
I think this AddOn will have to be rewritten for WoD, as I seem to recall there will be enough changes to various APIs such as animation that it won't work in its current state.
I don't have anywhere near the knowledge to do a complete rewrite, I was hoping it was a quick fix away but if what you say about WoD is true, it'd be futile anyway.

To save you the trouble, the addon minimizes the chat to only show 1 message at a time, unless you get a message in a specified channel (Party chat, for example) or on mouseover at which point it maximizes.
Like so: http://gyazo.com/48a052d00ae238ae044634b94bb371a3
I recommend switching to MP4 at the top.
__________________
All I see is strobe lights blinding me in my hindsight.

Last edited by Wimpface : 09-07-14 at 12:29 PM.
  Reply With Quote
10-11-14, 03:47 PM   #7
MoonWitch
A Firelord
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 455
I don't know how relevant this still is; I use Chiccai as well - without errors. And it worked on WoD as well... Just saying

Attached my version... Yes I do intend to rewrite it one of these days.
Attached Files
File Type: lua core.lua (6.7 KB, 176 views)
__________________
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Chicchai and docked chat frames

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