Skip to content

Commit

Permalink
#33: Improved performance when get linked info by memoizing its result
Browse files Browse the repository at this point in the history
  • Loading branch information
AssisrMatheus committed Sep 24, 2019
1 parent a85dc46 commit c42a03e
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 37 deletions.
86 changes: 52 additions & 34 deletions src/components/TodoChecklister.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ local ResponsiveFrame = TodoAddon.ResponsiveFrame
local TableUtils = TodoAddon.TableUtils
---@class TodoList
local TodoList = TodoAddon.TodoList
---@class FunctionUtils
local FunctionUtils = TodoAddon.FunctionUtils

--------------------------------------
-- Declarations
Expand All @@ -38,6 +40,7 @@ function TodoChecklisterFrame:AddItem(text)
else
TodoList:UpdateItem(self.selectedItem, {text = text})
end
self.memoizationId = self.memoizationId + 1
self:ClearSelected()
self:OnUpdate()
end
Expand Down Expand Up @@ -68,6 +71,7 @@ function TodoChecklisterFrame:RemoveItemWithIndex(indexToRemove)
self.selectedItem = indexToSelect
end

self.memoizationId = self.memoizationId + 1
self:OnUpdate()
end
end
Expand Down Expand Up @@ -104,6 +108,7 @@ function TodoChecklisterFrame:Move(fromIndex, toIndex, fromChat)
self.selectedItem = TodoList:GetIndexByItem(selectedItem)
end

self.memoizationId = self.memoizationId + 1
self:OnUpdate()
end
end
Expand All @@ -115,6 +120,7 @@ function TodoChecklisterFrame:CheckItemWithIndex(indexToCheck)
if (indexToCheck and type(indexToCheck) == "number" and indexToCheck > 0) then
local item = TodoList:GetItems()[indexToCheck]
TodoList:UpdateItem(indexToCheck, {isChecked = (not item.isChecked)})
self.memoizationId = self.memoizationId + 1
self:OnUpdate()
if
(Settings:PlayFanfare() and
Expand Down Expand Up @@ -155,6 +161,7 @@ function TodoChecklisterFrame:SelectItem(todoItem, buttonFrame)
self:ClearSelected()
end

self.memoizationId = self.memoizationId + 1
self:OnUpdate()
end

Expand Down Expand Up @@ -214,40 +221,46 @@ function TodoChecklisterFrame:PaintItem(frame, todoItem, index)
frame.TodoContent:SetWidth(TodoItemsScrollFrame:GetWidth() - frame.RemoveButton:GetWidth() - 23)

if (self.displayLinked) then
-- Startup regex process by storing string values
local finalString = ""
local remainingString = todoItem.text

-- If the remaining string still has linked items
while (remainingString and not (not GetItemInfo(remainingString))) do
-- Find the linked item position
local st, en = string.find(remainingString, "|Hitem:.-|r")

if (en) then
-- Set the final string to:
finalString =
table.concat {
finalString, -- Current final string
remainingString:sub(1, en), -- Current string until now
"(",
GetItemCount(remainingString), -- Amount from bag
") "
}

-- Remove the current linked item from the remaining string to continue the process
remainingString = remainingString:sub(en + 1)
else
remainingString = ""
end
end

-- If the final string has been set
if (string.len(finalString) > 0) then
frame.TodoContent.FontText:SetText(finalString .. remainingString)
else
-- If not, the string doesn't have links
frame.TodoContent.FontText:SetText(todoItem.text)
end
FunctionUtils:Memoize(
function()
-- Startup regex process by storing string values
local finalString = ""
local remainingString = todoItem.text

-- If the remaining string still has linked items
while (remainingString and not (not GetItemInfo(remainingString))) do
-- Find the linked item position
local st, en = string.find(remainingString, "|Hitem:.-|r")

if (en) then
-- Set the final string to:
finalString =
table.concat {
finalString, -- Current final string
remainingString:sub(1, en), -- Current string until now
"(",
GetItemCount(remainingString), -- Amount from bag
") "
}

-- Remove the current linked item from the remaining string to continue the process
remainingString = remainingString:sub(en + 1)
else
remainingString = ""
end
end

-- If the final string has been set
if (string.len(finalString) > 0) then
frame.TodoContent.FontText:SetText(finalString .. remainingString)
else
-- If not, the string doesn't have links
frame.TodoContent.FontText:SetText(todoItem.text)
end
end,
todoItem.id .. self.memoizationId,
todoItem.id .. "Count"
)
else
frame.TodoContent.FontText:SetText(todoItem.text)
end
Expand Down Expand Up @@ -489,11 +502,16 @@ end
function TodoChecklisterFrame:Init()
-- Creates the addon frame
local frame = CreateFrame("Frame", "TodoChecklister", UIParent, "TodoChecklisterTemplate")

-- Store a value to be used as a memoization id
self.memoizationId = 0

frame:RegisterEvent("BAG_UPDATE_DELAYED")
frame:HookScript(
"OnEvent",
function(frame, event)
if (event == "BAG_UPDATE_DELAYED") then
self.memoizationId = self.memoizationId + 1
self:OnUpdate()
end
end
Expand Down
7 changes: 4 additions & 3 deletions src/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ local MinimapIcon = TodoAddon.MinimapIcon
--------------------------------------
-- Init keybindings
--------------------------------------
BINDING_HEADER_TC_HEADER = "TodoChecklister"
BINDING_HEADER_TC_HEADER = addonName
BINDING_NAME_TC_TOGGLE_FRAME = "Toggle log visibility"

-- Export the method TodoChecklisterFrame:Toggle to a global function
-- so that it can be called from a keybind
GLOBAL_TodoChecklisterFrameToggle = function () TodoChecklisterFrame:Toggle() end

GLOBAL_TodoChecklisterFrameToggle = function()
TodoChecklisterFrame:Toggle()
end

--------------------------------------
-- Initialization
Expand Down
40 changes: 40 additions & 0 deletions src/utils/functionUtils.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
--------------------------------------
-- Imports
--------------------------------------
---@class TodoAddon
local TodoAddon = select(2, ...)

--------------------------------------
-- Declarations
--------------------------------------
TodoAddon.FunctionUtils = {}

---@class FunctionUtils
local FunctionUtils = TodoAddon.FunctionUtils

local memoizedValues = {}

--------------------------------------
-- TableUtils functions
--------------------------------------

---
---Calls a function once and store its key value, if the function gets called again but the parameters haven't changed.
---Instead of calling it again, it just return the previously calculated value
---@generic T
---@param execution fun(): T @A complex function that you want to Memoize
---@param comparator any @The value used to decide wether or not the function should be called again
---@param name string @A unique name for this memoization
---@return T @The returned value from the executed function
function FunctionUtils:Memoize(execution, comparator, name)
if (memoizedValues[name] and memoizedValues[name].comparator == comparator) then
return memoizedValues[name].result
end

memoizedValues[name] = {
result = execution(),
comparator = comparator
}

return memoizedValues[name].result
end
1 change: 1 addition & 0 deletions src/utils/utils.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="functionUtils.lua"/>
<Script file="tableUtils.lua"/>
</Ui>

0 comments on commit c42a03e

Please sign in to comment.