10-16-11, 03:03 PM | #1 |
LUA error - my addon collides with WIM
Hello ppl,
I'm working on a chat addon, in which I use ChatFrame_AddMessageEventFilter for officer chat. The filter breaks the message into several lines by adding "\n". The addon works fine with this filter. However, when I run it with WIM addon loaded, I get this LUA error: Code:
Message: memory allocation error: block too big Time: 10/16/11 22:45:19 Count: 4 Stack: [C]: ? [C]: in function `insert' Interface\AddOns\hebChat\hebChat.lua:512: in function `filterFunc' Interface\AddOns\WIM\WIM.lua:314: in function `honorChatFrameEventFilter' Interface\AddOns\WIM\Modules\ChatEngine.lua:409: in function `handler' ...s\WIM\Libs\LibChatHandler-1.0\LibChatHandler-1.0.lua:267: in function <...s\WIM\Libs\LibChatHandler-1.0\LibChatHandler-1.0.lua:252> ...s\WIM\Libs\LibChatHandler-1.0\LibChatHandler-1.0.lua:308: in function <...s\WIM\Libs\LibChatHandler-1.0\LibChatHandler-1.0.lua:296> Locals: Code:
table.insert(newStringTable, lineStringBkp.."\n") Code:
function WIM.honorChatFrameEventFilter(event, ...) local arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15 = ...; local chatFilters = _G.ChatFrame_GetMessageEventFilters(event); local filter = false; if chatFilters then local narg1, narg2, narg3, narg4, narg5, narg6, narg7, narg8, narg9, narg10, narg11, narg12, narg13, narg14, narg15; for _, filterFunc in next, chatFilters do filter, narg1, narg2, narg3, narg4, narg5, narg6, narg7, narg8, narg9, narg10, narg11, narg12, narg13, narg14, narg15 = filterFunc(workerFrame, event, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); if filter then return true, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15; elseif(narg1) then arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12 = narg1, narg2, narg3, narg4, narg5, narg6, narg7, narg8, narg9, narg10, narg11, narg12, narg13, narg14, narg15; end end end return filter, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15; end |
|
10-16-11, 04:46 PM | #2 |
I don't think that's relevant to WIM.
Does 'newStringTable' keep growing indefinitely? If yes that's your problem. |
|
10-17-11, 02:24 AM | #4 |
Thank you
Then I should understand what is wrong with my filterfunc. I have the following declared in this func: Code:
local newStringTable = {} I also have this: Code:
local tempFrame = CreateFrame("Frame", nil, UIParent) tempFrame:Hide() tempFrame.text = tempFrame:CreateFontString() tempFrame.text:SetAllPoints(tempFrame) tempFrame.text:SetFont(hebChat.fonts[hebChatDB.currentFont][2], hebChatDB.currentFontSize) In addition, I have 2 while loops, one nested inside the other. Perhaps it's too much? These loops run on each char of the message string. The thing is I get the error on the first thing I write in Officer chat, even if it's only one single letter. So it's not that these local variables can grow indefinitely until then. |
|
10-17-11, 02:26 AM | #5 |
You should probably post your full code.
|
|
10-17-11, 02:46 AM | #6 |
filterfunc calling:
Code:
ChatFrame_AddMessageEventFilter("CHAT_MSG_OFFICER", hebChat.hebChatFixWrap) Code:
function hebChat.hebChatFixWrap(chatFrame, event, msg, author, ...) local remainingString = msg local newStringTable = {} local newString = "" local lineString = "" local lineStringBkp = "" local remainingStringBkp = "" local chatFrameWidth = chatFrame:GetWidth() local effectiveChatFrameWidth = 0 local header1 = "" local headerWidth1 = 0 local headerWidth2 = 0 -- In case of hebrew char if (msg:find("[א-ת]")) then -- Create temporary frame to calculate string width local tempFrame = CreateFrame("Frame", nil, UIParent) tempFrame:Hide() tempFrame.text = tempFrame:CreateFontString() tempFrame.text:SetAllPoints(tempFrame) tempFrame.text:SetFont(hebChat.fonts[hebChatDB.currentFont][2], ebChatDB.currentFontSize) -- Calculate header widths if (event == "CHAT_MSG_WHISPER" or event == CHAT_MSG_BN_WHISPER") then header = "["..author.."] whispers: " elseif (event == "CHAT_MSG_WHISPER_INFORM" or event == CHAT_MSG_BN_WHISPER_INFORM") then header = "To ["..author.."]: " elseif (event == "CHAT_MSG_GUILD") then header = "[Guild] ["..author.."]: " elseif (event == "CHAT_MSG_OFFICER") then header = "[Officer] ["..author.."]: " elseif (event == "CHAT_MSG_RAID") then header = "[Raid] ["..author.."]: " elseif (event == "CHAT_MSG_PARTY") then header = "[Party] ["..author.."]: " elseif (event == "CHAT_MSG_BN_CONVERSATION") then header = "11. [Conversation] ["..author.."]: " else header = "" end tempFrame.text:SetText(header) headerWidth1 = tempFrame.text:GetStringWidth() tempFrame.text:SetText("[2") headerWidth2 = tempFrame.text:GetStringWidth() -- first line effective width effectiveChatFrameWidth = chatFrameWidth - headerWidth1 - 10 -- Prepare for outer while loop tempFrame.text:SetText(remainingString) while (tempFrame.text:GetStringWidth() > effectiveChatFrameWidth) do -- Prepare for inner while loop tempFrame.text:SetText(lineString) while (tempFrame.text:GetStringWidth() <= effectiveChatFrameWidth) do -- Extract last char lineString = utf8sub(remainingString, strlenutf8(remainingString), 1)..lineString remainingString = utf8sub(remainingString, 1, strlenutf8(remainingString) - 1) -- Store current lineString between words and move last space to end of line if (lineString:find("^%s")) then lineStringBkp = utf8sub(lineString, 2, strlenutf8(lineString) - 1)..utf8sub(lineString, 1, 1) remainingStringBkp = remainingString end -- Prepare for next while loop check tempFrame.text:SetText(lineString) end -- Inner while loop -- out of inner while loop: lineString is wider than frame width if (#lineStringBkp ~= 0) then remainingString = remainingStringBkp else -- Single word longer than width - just add the word lineStringBkp = lineString end -- Break lines and insert to table. table.insert(newStringTable, lineStringBkp.."\n") -- Prepare for outer while loop tempFrame.text:SetText(remainingString) -- non-first line effective width effectiveChatFrameWidth = chatFrameWidth - headerWidth2 - 10 -- reset strings lineStringBkp = "" lineString = "" end -- Outer while loop table.insert (newStringTable, remainingString) newString = table.concat(newStringTable) return false, newString, author, ... --return false else return false end end |
|
10-17-11, 04:21 AM | #7 |
Try this for starters.
filterfunc code: Code:
local newStringTable = {} local tempFrame = CreateFrame("Frame", nil, UIParent) tempFrame.text = tempFrame:CreateFontString() tempFrame.text:SetAllPoints(tempFrame) tempFrame:Hide() function hebChat.hebChatFixWrap(chatFrame, event, msg, author, ...) local remainingString = msg wipe(newStringTable) local newString = "" local lineString = "" local lineStringBkp = "" local remainingStringBkp = "" local chatFrameWidth = chatFrame:GetWidth() local effectiveChatFrameWidth = 0 local header1 = "" local headerWidth1 = 0 local headerWidth2 = 0 -- In case of hebrew char if (msg:find("[א-ת]")) then tempFrame.text:SetFont(hebChat.fonts[hebChatDB.currentFont][2], ebChatDB.currentFontSize) -- Calculate header widths if (event == "CHAT_MSG_WHISPER" or event == CHAT_MSG_BN_WHISPER") then header = "["..author.."] whispers: " elseif (event == "CHAT_MSG_WHISPER_INFORM" or event == CHAT_MSG_BN_WHISPER_INFORM") then header = "To ["..author.."]: " elseif (event == "CHAT_MSG_GUILD") then header = "[Guild] ["..author.."]: " elseif (event == "CHAT_MSG_OFFICER") then header = "[Officer] ["..author.."]: " elseif (event == "CHAT_MSG_RAID") then header = "[Raid] ["..author.."]: " elseif (event == "CHAT_MSG_PARTY") then header = "[Party] ["..author.."]: " elseif (event == "CHAT_MSG_BN_CONVERSATION") then header = "11. [Conversation] ["..author.."]: " else header = "" end tempFrame.text:SetText(header) headerWidth1 = tempFrame.text:GetStringWidth() tempFrame.text:SetText("[2") headerWidth2 = tempFrame.text:GetStringWidth() -- first line effective width effectiveChatFrameWidth = chatFrameWidth - headerWidth1 - 10 -- Prepare for outer while loop tempFrame.text:SetText(remainingString) while (tempFrame.text:GetStringWidth() > effectiveChatFrameWidth) do -- Prepare for inner while loop tempFrame.text:SetText(lineString) while (tempFrame.text:GetStringWidth() <= effectiveChatFrameWidth) do -- Extract last char lineString = utf8sub(remainingString, strlenutf8(remainingString), 1)..lineString remainingString = utf8sub(remainingString, 1, strlenutf8(remainingString) - 1) -- Store current lineString between words and move last space to end of line if (lineString:find("^%s")) then lineStringBkp = utf8sub(lineString, 2, strlenutf8(lineString) - 1)..utf8sub(lineString, 1, 1) remainingStringBkp = remainingString end -- Prepare for next while loop check tempFrame.text:SetText(lineString) end -- Inner while loop -- out of inner while loop: lineString is wider than frame width if (#lineStringBkp ~= 0) then remainingString = remainingStringBkp else -- Single word longer than width - just add the word lineStringBkp = lineString end -- Break lines and insert to table. table.insert(newStringTable, lineStringBkp.."\n") -- Prepare for outer while loop tempFrame.text:SetText(remainingString) -- non-first line effective width effectiveChatFrameWidth = chatFrameWidth - headerWidth2 - 10 -- reset strings lineStringBkp = "" lineString = "" end -- Outer while loop table.insert (newStringTable, remainingString) newString = table.concat(newStringTable) return false, newString, author, ... --return false else return false end end |
|
10-17-11, 05:11 AM | #8 |
Thank you for your answer.
I have found the reason for the error. I've removed line after line from my code, until I had only the outer while loop with almost no content in it. Then the game stuck, without even giving lua error. So I made some var prints and I realized WIM is running my filterfunc as well. WIM got into infinite loop since Code:
local chatFrameWidth = chatFrame:GetWidth() What is the reason for that? How can I make WIM get the correct width when running my filterfunc? Perhaps it is related to the "workerFrame" WIM is passing to the filterfunc? Last edited by Animor : 10-17-11 at 05:13 AM. |
|
10-17-11, 05:18 AM | #9 |
Nice, but you should still avoid creating a new table and new frame every time your filter function runs.
|
|
10-17-11, 05:21 AM | #10 | |
Do you have an idea how to fix the chatframe width and WIM? |
||
10-17-11, 09:08 AM | #11 |
I can't run the code in-game atm so this is just guessing,
but it looks like you're "eating" the chatframe in your function Your filterfunc is passed chatframe, event, msg, author, ... ie 4 named parameters and the ellipsis (...) with any more params passed but later you return from msg onward - newstring, author, ... |
|
10-17-11, 09:20 AM | #12 | |
http://www.wowpedia.org/API_ChatFram...ageEventFilter and specific line: Code:
filter, arg1, arg2, arg3, ..., arg11 = myFilterFunc(chatFrame, event, arg1, arg2, arg3, ..., arg11); |
||
WoWInterface » Developer Discussions » Lua/XML Help » LUA error - my addon collides with WIM |
«
Previous Thread
|
Next Thread
»
|
Display Modes |
Linear Mode |
Switch to Hybrid Mode |
Switch to Threaded Mode |
|
|