1 QuestHelper_File
["collect.lua"] = "Development Version"
2 QuestHelper_Loadtime
["collect.lua"] = GetTime()
4 local debug_output
= false
5 if QuestHelper_File
["collect.lua"] == "Development Version" then debug_output
= true end
7 local QuestHelper_Collector_Version_Current
= 6
9 QuestHelper_Collector
= {}
10 QuestHelper_Collector_Version
= QuestHelper_Collector_Version_Current
12 local EventRegistrar
= {}
13 local OnUpdateRegistrar
= {}
14 local TooltipRegistrar
= {}
16 local frame
= CreateFrame("Frame")
18 local function OnEvent(_
, event
, ...)
19 local tstart
= GetTime()
20 for _
, v
in pairs(EventRegistrar
[event
]) do
23 QH_Timeslice_Increment(GetTime() - tstart
, "collect_event")
26 frame
:UnregisterAllEvents()
27 frame
:SetScript("OnEvent", OnEvent
)
31 function EventHookRegistrar(event
, func
)
32 QuestHelper
:Assert(func
)
33 if not EventRegistrar
[event
] then
34 frame
:RegisterEvent(event
)
35 EventRegistrar
[event
] = {}
37 table.insert(EventRegistrar
[event
], func
)
40 function OnUpdateHookRegistrar(func
)
41 QuestHelper
:Assert(func
)
42 table.insert(OnUpdateRegistrar
, func
)
45 local suppress
= false
47 -- real tooltips don't use this function
48 local SetTextScript
= GameTooltip
.SetText
49 GameTooltip
.SetText
= function (...)
55 local OriginalScript
= GameTooltip
:GetScript("OnShow")
56 GameTooltip
:SetScript("OnShow", function (self
, ...)
57 if suppress
then return end
59 if not self
then self
= GameTooltip
end
61 local tstart
= GetTime()
62 for k
, v
in pairs(TooltipRegistrar
) do
65 QH_Timeslice_Increment(GetTime() - tstart
, "collect_tooltip") -- anything past here is not my fault
66 if OriginalScript
then
67 return OriginalScript(self
, ...)
71 function TooltipHookRegistrar(func
)
72 QuestHelper
:Assert(func
)
73 table.insert(TooltipRegistrar
, func
)
77 Registrar_EventHook
= EventHookRegistrar
,
78 Registrar_OnUpdateHook
= OnUpdateHookRegistrar
,
79 Registrar_TooltipHook
= TooltipHookRegistrar
,
80 Callback_RawLocation
= function () return QuestHelper
:RetrieveRawLocation() end,
83 local CompressCollection
85 function QH_Collector_Init()
86 QH_Collector_UpgradeAll(QuestHelper_Collector
)
88 for _
, v
in pairs(QuestHelper_Collector
) do
89 if not v
.modified
then v
.modified
= time() - 7 * 24 * 60 * 60 end -- eugh. Yeah, we set it to be a week ago. It's pretty grim.
92 QuestHelper_Collector_Version
= QuestHelper_Collector_Version_Current
94 local sig
= string.format("%s on %s/%s/%d", GetAddOnMetadata("QuestHelper", "Version"), GetBuildInfo(), GetLocale(), QuestHelper
:PlayerFaction())
95 if not QuestHelper_Collector
[sig
] or QuestHelper_Collector
[sig
].compressed
then QuestHelper_Collector
[sig
] = {version
= QuestHelper_Collector_Version
} end -- fuckin' bullshit, man
96 local QHCData
= QuestHelper_Collector
[sig
]
97 QuestHelper
: Assert(not QHCData
.compressed
)
98 QuestHelper
: Assert(QHCData
.version
== QuestHelper_Collector_Version_Current
)
99 QHCData
.modified
= time()
101 QH_Collect_Util_Init(nil, API
) -- Some may actually add their own functions to the API, and should go first. There's no real formalized order, I just know which depend on others, and it's heavily asserted so it will break if it goes in the wrong order.
102 QH_Collect_Merger_Init(nil, API
)
103 QH_Collect_Bitstream_Init(nil, API
)
105 QH_Collect_Location_Init(nil, API
)
106 QH_Collect_Patterns_Init(nil, API
)
107 QH_Collect_Notifier_Init(nil, API
)
108 QH_Collect_Spec_Init(nil, API
)
110 QH_Collect_LZW_Init(nil, API
)
112 QH_Collect_Achievement_Init(QHCData
, API
)
113 QH_Collect_Traveled_Init(QHCData
, API
)
114 QH_Collect_Zone_Init(QHCData
, API
)
115 QH_Collect_Monster_Init(QHCData
, API
)
116 QH_Collect_Item_Init(QHCData
, API
)
117 QH_Collect_Object_Init(QHCData
, API
)
118 QH_Collect_Flight_Init(QHCData
, API
)
119 QH_Collect_Quest_Init(QHCData
, API
)
120 QH_Collect_Warp_Init(QHCData
, API
)
122 QH_Collect_Loot_Init(QHCData
, API
)
123 QH_Collect_Equip_Init(QHCData
, API
)
124 QH_Collect_Merchant_Init(QHCData
, API
)
126 if not QHCData
.realms
then QHCData
.realms
= {} end
127 QHCData
.realms
[GetRealmName()] = (QHCData
.realms
[GetRealmName()] or 0) + 1 -- I'm not entirely sure why I'm counting
129 -- So, why do we delay it?
130 -- It's simple. People are gonna update to this version, and then they're going to look at the memory usage. Then they will panic because omg this version uses so much more memory, I bet that will somehow hurt my framerates in a way which is not adequately explained!
131 -- So instead, we just wait half an hour before compressing. Compression will still get done, and I won't have to deal with panicked comments about how bloated QH has gotten.
132 -- Want QH to work better? Just make that "30 * 60" bit into "0" instead.
133 API
.Utility_Notifier(GetTime() + 30 * 60, function() CompressCollection(QHCData
, API
.Utility_Merger
, API
.Utility_LZW
.Compress
) end)
136 function QH_Collector_OnUpdate()
137 local tstart
= GetTime()
138 for _
, v
in pairs(OnUpdateRegistrar
) do
141 QH_Timeslice_Increment(GetTime() - tstart
, "collect_update")
146 --- I've tossed the compression stuff down here just 'cause I don't feel like making an entire file for it (even though I probably should.)
148 local noncompressible
= {
157 local serializers
= {
158 ["nil"] = function(item
, add
)
161 ["number"] = function(item
, add
)
164 ["string"] = function(item
, add
)
165 add(string.format("%q", item
))
167 ["boolean"] = function(item
, add
)
168 add(item
and "true" or "false")
170 ["table"] = function(item
, add
)
173 for k
, v
in pairs(item
) do
174 if not first
then add(",") end
185 seritem
= function(item
, add
)
187 serializers
[type(item
)](item
, add
)
190 local function DoCompress(item
, merger
, comp
)
191 if debug_output
then QuestHelper
: TextOut("Item condensing") end
195 for k
, v
in pairs(item
) do
196 if not noncompressible
[k
] then
202 seritem(target
, function(dat
) merger
.Add(mg
, dat
) end)
204 local tg
= merger
.Finish(mg
)
205 if debug_output
then QuestHelper
: TextOut(string.format("Item condensed to %d bytes, %f taken so far", #tg
, GetTime() - ts
)) end
208 local cmp
= comp(tg
, 256, 8)
210 for k
, v
in pairs(target
) do
211 if not noncompressible
[k
] then
215 item
.compressed
= cmp
217 if debug_output
then QuestHelper
: TextOut(string.format("Item compressed to %d bytes (previously %d), %f taken", #cmp
, #tg
, GetTime() - ts
)) end
220 CompressCollection
= function(active
, merger
, comp
)
221 for _
, v
in pairs(QuestHelper_Collector
) do
222 if v
~= active
and not v
.compressed
then
223 QH_Timeslice_Add(function ()
224 DoCompress(v
, merger
, comp
)
225 CompressCollection(active
, merger
, comp
)