From 13b8bd88261a040827b0ec27c530a173a3b9273d Mon Sep 17 00:00:00 2001 From: Tercio Jose Date: Sun, 19 Mar 2023 20:10:28 -0300 Subject: [PATCH] Internal Garbage Collector update --- boot.lua | 1 + classes/class_combat.lua | 9 +- classes/class_damage.lua | 5 - classes/class_heal.lua | 4 - classes/class_resources.lua | 4 - classes/class_utility.lua | 4 - classes/container_actors.lua | 14 +- classes/container_pets.lua | 2 +- classes/container_segments.lua | 2 +- core/control.lua | 2 - core/meta.lua | 321 +++++++++++++++------------------ core/parser.lua | 20 +- core/timemachine.lua | 16 +- startup.lua | 217 +++++++++++----------- 14 files changed, 299 insertions(+), 322 deletions(-) diff --git a/boot.lua b/boot.lua index e5c43b1f..84da86d4 100644 --- a/boot.lua +++ b/boot.lua @@ -82,6 +82,7 @@ Details222.Cache = {} Details222.Perf = {} Details222.Cooldowns = {} + Details222.GarbageCollector = {} ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --initialization stuff diff --git a/classes/class_combat.lua b/classes/class_combat.lua index e94930a8..a48c4745 100644 --- a/classes/class_combat.lua +++ b/classes/class_combat.lua @@ -110,10 +110,13 @@ return self.is_mythic_dungeon_trash end + ---return if the combat is a mythic dungeon segment and the run id + ---@return boolean + ---@return number function combate:IsMythicDungeon() - local is_segment = self.is_mythic_dungeon_segment - local run_id = self.is_mythic_dungeon_run_id - return is_segment, run_id + local bIsMythicPlusSegment = self.is_mythic_dungeon_segment + local runId = self.is_mythic_dungeon_run_id + return bIsMythicPlusSegment, runId end function combate:IsMythicDungeonOverall() diff --git a/classes/class_damage.lua b/classes/class_damage.lua index a125531c..4c7ff6e8 100644 --- a/classes/class_damage.lua +++ b/classes/class_damage.lua @@ -6005,11 +6005,6 @@ end return shadow end -function atributo_damage:ColetarLixo (lastevent) - return Details:ColetarLixo (class_type, lastevent) -end - - --actor 1 is who will receive the sum from actor2 function Details.SumDamageActors(actor1, actor2, actorContainer) --general diff --git a/classes/class_heal.lua b/classes/class_heal.lua index d2bbb9aa..37e32099 100644 --- a/classes/class_heal.lua +++ b/classes/class_heal.lua @@ -2760,10 +2760,6 @@ end return shadow end -function atributo_heal:ColetarLixo (lastevent) - return _detalhes:ColetarLixo (class_type, lastevent) -end - atributo_heal.__add = function(tabela1, tabela2) --tempo decorrido diff --git a/classes/class_resources.lua b/classes/class_resources.lua index 57c740de..bfdb7421 100644 --- a/classes/class_resources.lua +++ b/classes/class_resources.lua @@ -1523,10 +1523,6 @@ end return shadow end -function atributo_energy:ColetarLixo (lastevent) - return _detalhes:ColetarLixo (class_type, lastevent) -end - function _detalhes.refresh:r_atributo_energy (este_jogador, shadow) detailsFramework:Mixin(este_jogador, Details222.Mixins.ActorMixin) setmetatable(este_jogador, _detalhes.atributo_energy) diff --git a/classes/class_utility.lua b/classes/class_utility.lua index 53957537..4149b0c7 100644 --- a/classes/class_utility.lua +++ b/classes/class_utility.lua @@ -2743,10 +2743,6 @@ function atributo_misc:r_connect_shadow (actor, no_refresh, combat_object) end -function atributo_misc:ColetarLixo (lastevent) - return _detalhes:ColetarLixo (class_type, lastevent) -end - function _detalhes.refresh:r_atributo_misc(thisActor, shadow) setmetatable(thisActor, _detalhes.atributo_misc) detailsFramework:Mixin(thisActor, Details222.Mixins.ActorMixin) diff --git a/classes/container_actors.lua b/classes/container_actors.lua index 4801bb45..4b7b7a85 100644 --- a/classes/container_actors.lua +++ b/classes/container_actors.lua @@ -280,6 +280,12 @@ end return ipairs(self._ActorTable) end + ---return a table for all actors stored in this Container + ---@return table + function actorContainer:GetActorTable() + return self._ActorTable + end + ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --internals @@ -995,10 +1001,10 @@ end end function actorContainer:remapear() - local mapa = self._NameIndexTable - local conteudo = self._ActorTable - for i = 1, #conteudo do - mapa [conteudo[i].nome] = i + local namingMap = self._NameIndexTable + local actorList = self._ActorTable + for i = 1, #actorList do + namingMap[actorList[i].nome] = i end end diff --git a/classes/container_pets.lua b/classes/container_pets.lua index 23d0b44c..8c262040 100644 --- a/classes/container_pets.lua +++ b/classes/container_pets.lua @@ -227,7 +227,7 @@ function _detalhes:WipePets() return wipe(_detalhes.tabela_pets.pets) end -function _detalhes:LimparPets() +function _detalhes:PetContainerCleanup() --erase old pet table by creating a new one local newPetTable = {} --minimum of 90 minutes to clean a pet from the pet table data diff --git a/classes/container_segments.lua b/classes/container_segments.lua index 189c3f58..52b57b42 100644 --- a/classes/container_segments.lua +++ b/classes/container_segments.lua @@ -485,7 +485,7 @@ function segmentClass:resetar() wipe (Details.schedule_add_to_overall) end - Details:LimparPets() + Details:PetContainerCleanup() Details:ResetSpecCache (true) --for�ar -- novo container de historico diff --git a/core/control.lua b/core/control.lua index 7d3de551..a800c3e8 100644 --- a/core/control.lua +++ b/core/control.lua @@ -628,9 +628,7 @@ -- Details:EqualizeActorsSchedule (Details.host_of) end - --verifica memoria Details:FlagActorsOnCommonFight() --fight_component - --Details:CheckMemoryAfterCombat() -- 7.2.5 is doing some weird errors even out of combat else --this segment is a boss fight diff --git a/core/meta.lua b/core/meta.lua index 2a20d4d7..48c4923c 100644 --- a/core/meta.lua +++ b/core/meta.lua @@ -1,7 +1,7 @@ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - local _detalhes = _G._detalhes - local _tempo = time() + local _detalhes = _G._detalhes + local Details = _detalhes + local tocName, Details222 = ... ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --local pointers @@ -40,14 +40,16 @@ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --core - --reconstr�i o mapa do container - local function ReconstroiMapa (tabela) - local mapa = {} - for i = 1, #tabela._ActorTable do - mapa [tabela._ActorTable[i].nome] = i - end - tabela._NameIndexTable = mapa + ---wipe the naming list and rebuild it + ---@param actorContainer actorcontainer + local fullRemap = function(actorContainer) + local namingMap = actorContainer._NameIndexTable + wipe(namingMap) + for i = 1, #actorContainer._ActorTable do + local actorName = actorContainer._ActorTable[i].nome + namingMap[actorName] = i end + end --reaplica as tabelas no overall function _detalhes:RestauraOverallMetaTables() @@ -560,7 +562,7 @@ end if (_iter.cleaned > 0) then - ReconstroiMapa (_tabela) + fullRemap(_tabela) end end end @@ -697,7 +699,7 @@ end if (_iter.cleaned > 0) then - ReconstroiMapa (_tabela) + fullRemap(_tabela) end end @@ -732,7 +734,7 @@ _detalhes:DoContainerIndexCleanup() end - function _detalhes:reset_window (instancia) + function _detalhes:reset_window(instancia) if (instancia.segmento == -1) then instancia.showing[instancia.atributo].need_refresh = true instancia.v_barras = true @@ -741,65 +743,44 @@ end end - --desativado 7.2.5 veio com algum bug e a checagem de memoria esta sendo feita durante o combate - function _detalhes:CheckMemoryAfterCombat() - if (_detalhes.next_memory_check < time() and not InCombatLockdown() and not UnitAffectingCombat("player")) then - _detalhes.next_memory_check = time()+_detalhes.intervalo_memoria - UpdateAddOnMemoryUsage() - local memory = GetAddOnMemoryUsage ("Details") - if (memory > _detalhes.memory_ram) then - _detalhes:RestartInternalGarbageCollector (true, 60) --sending true doesn't check anythink - end - end - end - - function _detalhes:CheckMemoryPeriodically() - if (_detalhes.next_memory_check <= time() and not _InCombatLockdown() and not _detalhes.in_combat and not UnitAffectingCombat("player")) then - _detalhes.next_memory_check = time() + _detalhes.intervalo_memoria - 3 - UpdateAddOnMemoryUsage() - local memory = GetAddOnMemoryUsage ("Details") - if (_detalhes.debug) then - _detalhes:Msg("(debug) checking memory periodically. Using: ",math.floor(memory)) - end - if (memory > _detalhes.memory_ram * 1000) then - _detalhes:RestartInternalGarbageCollector (1, 60) --sending 1 only check for combat and ignore garbage collect cooldown - end - end - end - - function _detalhes:RestartInternalGarbageCollector(bShouldForceCollect, lastEvent) + ---start/restart the internal garbage collector runtime + ---@param bShouldForceCollect boolean if true, the garbage collector will run regardless of the time interval + ---@param lastEvent unixtime no call is passing lastEvent at the moment + function Details222.GarbageCollector.RestartInternalGarbageCollector(bShouldForceCollect, lastEvent) + --print("d! debug: running garbage collector...") if (not bShouldForceCollect) then - if (_detalhes.ultima_coleta + _detalhes.intervalo_coleta > _detalhes._tempo + 1) then + local thisTime = Details222.GarbageCollector.lastCollectTime + Details222.GarbageCollector.intervalTime + if (thisTime > Details._tempo + 1) then return - elseif (_detalhes.in_combat or _InCombatLockdown() or _detalhes:IsInInstance()) then - _detalhes:ScheduleTimer("RestartInternalGarbageCollector", 5) + elseif (Details.in_combat or _InCombatLockdown() or Details:IsInInstance()) then + Details.Schedules.After(5, Details222.GarbageCollector.RestartInternalGarbageCollector, false, lastEvent) return end else if (type(bShouldForceCollect) ~= "boolean") then if (bShouldForceCollect == 1) then - if (_detalhes.in_combat or _InCombatLockdown()) then - _detalhes:ScheduleTimer("RestartInternalGarbageCollector", 5, bShouldForceCollect) + if (Details.in_combat or _InCombatLockdown()) then + Details.Schedules.After(5, Details222.GarbageCollector.RestartInternalGarbageCollector, bShouldForceCollect, lastEvent) return end end end end - if (_detalhes.debug) then + if (Details.debug) then if (bShouldForceCollect) then - _detalhes:Msg("(debug) collecting garbage with forced state:", bShouldForceCollect) + Details:Msg("(debug) collecting garbage with forced state:", bShouldForceCollect) else - _detalhes:Msg("(debug) collecting garbage.") + Details:Msg("(debug) collecting garbage.") end end --cleanup all the parser caches Details:ClearParserCache() - --cleanup all the window lines (bars) which isn't in use - for index, instanceObject in ipairs(Details.tabela_instancias) do + --cleanup lines which isn't shown but has an actor attached to + for instanceId, instanceObject in Details:ListInstances() do if (instanceObject.barras and instanceObject.barras[1]) then for i, lineRow in ipairs(instanceObject.barras) do if (not lineRow:IsShown()) then @@ -809,26 +790,24 @@ end end - --do garbage collection on the handler for each actor class - local damage = classDamage:ColetarLixo(lastEvent) - local heal = classHeal:ColetarLixo(lastEvent) - local energy = classEnergy:ColetarLixo(lastEvent) - local misc = classUtility:ColetarLixo(lastEvent) - - local limpados = damage + heal + energy + misc + --print("d! debug: RunGarbageCollector() Start") + ---@type number + local amountActorRemoved = Details222.GarbageCollector.RunGarbageCollector(lastEvent) + --print("d! debug: RunGarbageCollector() Ended, cleanup:", amountActorRemoved, "actors.") --139 actor removed, but don't remove anything (/reload it remove again) + --UpdateAddOnMemoryUsage() + --local memoryUsage = GetAddOnMemoryUsage("Details") + --print("Memory:", floor(memoryUsage)/1000, "MBytes") --refresh nas janelas - if (limpados > 0) then - Details:InstanciaCallFunction(_detalhes.reset_window) + if (amountActorRemoved > 0) then + Details:InstanciaCallFunction(Details.reset_window) end - Details:ManutencaoTimeMachine() + Details:TimeMachineMaintenance() --cleanup backlisted pets within the handler of actor containers - _detalhes:LimparPets() - if (not _detalhes.in_combat) then - Details:ClearCCPetsBlackList() - end + Details:PetContainerCleanup() + Details:ClearCCPetsBlackList() --cleanup spec cache Details:ResetSpecCache() @@ -836,152 +815,134 @@ --cleanup the shield cache wipe(Details.ShieldCache) - --set the time of the latest internal garbage collect - Details.ultima_coleta = _detalhes._tempo + --set the time of the last run + Details222.GarbageCollector.lastCollectTime = Details._tempo - if (_detalhes.debug) then + if (Details.debug) then Details:Msg("(debug) executing: collectgarbage().") collectgarbage() - UpdateAddOnMemoryUsage() end end - --combates Normais - local function FazColeta (_combate, tipo, intervalo_overwrite) - - local conteudo = _combate [tipo]._ActorTable - local _iter = {index = 1, data = conteudo[1], cleaned = 0} - local _tempo = _time() - - --local links_removed = 0 + ---check all the actors and remove the ones which are not in use + ---@param combatObject combat + ---@param overriteInterval unixtime + ---@return integer + local collectGarbage = function(combatObject, overriteInterval) + --amount of actors removed + local amountCleaned = 0 --do not collect things in a mythic+ dungeon segment - if (_combate.is_mythic_dungeon_trash or _combate.is_mythic_dungeon_run_id or _combate.is_mythic_dungeon_segment) then - return 0 + if (combatObject.is_mythic_dungeon_trash or combatObject.is_mythic_dungeon_run_id or combatObject.is_mythic_dungeon_segment) then + return amountCleaned end - while (_iter.data) do + ---@type number + local _tempo = _time() - local _actor = _iter.data - local can_garbage = false + for containerId = 1, 4 do + local actorContainer = combatObject:GetContainer(containerId) + ---@type table + local actorList = actorContainer:GetActorTable() + local beforeCleanupAmountOfActors = #actorList - local t - if (intervalo_overwrite) then - t = _actor.last_event + intervalo_overwrite - else - t = _actor.last_event + _detalhes.intervalo_coleta - end + for actorIndex = #actorList, 1, -1 do + ---@type actor + local actorObject = actorList[actorIndex] - if (t < _tempo and not _actor.grupo and not _actor.boss and not _actor.fight_component and not _actor.boss_fight_component) then - local owner = _actor.owner - if (owner) then - local owner_actor = _combate (tipo, owner.nome) - if (not owner.grupo and not owner.boss and not owner.boss_fight_component) then - can_garbage = true + if (not actorObject.grupo and not actorObject.boss and not actorObject.fight_component and not actorObject.boss_fight_component) then + local canCollect = false + + --check the time of the last seen event coming from the actor + ---@type unixtime + local lastSeenEventTime = actorObject.last_event + + ---@type number + local nextGarbageCollection + + if (overriteInterval) then + nextGarbageCollection = lastSeenEventTime + overriteInterval + else + nextGarbageCollection = lastSeenEventTime + Details222.GarbageCollector.intervalTime + end + + if (nextGarbageCollection - 1 < _tempo) then + local owner = actorObject.owner --is the name or object? + if (owner) then + --local owner_actor = combatObject (tipo, owner.nome) + if (not owner.grupo and not owner.boss and not owner.boss_fight_component) then + canCollect = true + end + else + canCollect = true + end + end + + if (canCollect) then + if (not actorObject.owner) then --not a pet + actorObject:subtract_total(combatObject) + end + + amountCleaned = amountCleaned + 1 + + if (containerId == 1 or containerId == 2) then --damage or healing + Details.timeMachine:UnregisterActor(actorObject) + end + + --remove the actor from the container + tremove(actorList, actorIndex) end - else - can_garbage = true end end - if (can_garbage) then - if (not _actor.owner) then --pet - _actor:subtract_total (_combate) - end - - _iter.cleaned = _iter.cleaned+1 - - if (_actor.tipo == 1 or _actor.tipo == 2) then - _actor:DesregistrarNaTimeMachine() - end - - _table_remove(conteudo, _iter.index) - _iter.data = conteudo [_iter.index] - else - _iter.index = _iter.index + 1 - _iter.data = conteudo [_iter.index] + if (amountCleaned > 0) then + fullRemap(combatObject[containerId]) + combatObject[containerId].need_refresh = true + --print(beforeCleanupAmountOfActors, "before cleanup, after:", #combatObject[1]._ActorTable) end - end - --if (_detalhes.debug) then - -- _detalhes:Msg("- garbage collect:", tipo, "actors removed:",_iter.cleaned) - --end - - if (_iter.cleaned > 0) then - ReconstroiMapa (_combate [tipo]) - _combate [tipo].need_refresh = true - end - - return _iter.cleaned + return amountCleaned end - --Combate overall - function _detalhes:ColetarLixo (tipo, lastevent) + ---run the garbage collector + ---@param overriteLastEvent unixtime + function Details222.GarbageCollector.RunGarbageCollector(overriteLastEvent) + ---@type number + local amountRemoved = 0 - --print("fazendo coleta...") + --create a list of all combats except the current one + ---@type table + local allSegments = Details:GetCombatSegments() + ---@type table + local segmentsList = {} - local _tempo = _time() - local limpados = 0 - - --monta a lista de combates - local tabelas_de_combate = {} - for _, _tabela in ipairs(_detalhes.tabela_historico.tabelas) do - if (_tabela ~= _detalhes.tabela_vigente) then - tabelas_de_combate [#tabelas_de_combate+1] = _tabela + for _, combatObject in ipairs(allSegments) do + if (combatObject ~= Details.tabela_vigente) then + segmentsList[#segmentsList+1] = combatObject end end - tabelas_de_combate [#tabelas_de_combate+1] = _detalhes.tabela_vigente - --faz a coleta em todos os combates para este atributo - for _, _combate in ipairs(tabelas_de_combate) do - limpados = limpados + FazColeta (_combate, tipo, lastevent) - end + --add the current segment at the end of the list + segmentsList[#segmentsList+1] = Details.tabela_vigente - --limpa a tabela overall para o atributo atual (limpa para os 4, um de cada vez atrav�s do ipairs) - local _overall_combat = _detalhes.tabela_overall - local conteudo = _overall_combat [tipo]._ActorTable - local _iter = {index = 1, data = conteudo[1], cleaned = 0} --._ActorTable[1] para pegar o primeiro index - - while (_iter.data) do - - local _actor = _iter.data - - local can_garbage = false - if (not _actor.grupo and not _actor.owner and not _actor.boss_fight_component and not _actor.fight_component) then - can_garbage = true + --collect the garbage + for i, combatObject in ipairs(segmentsList) do + local removedActors = collectGarbage(combatObject, overriteLastEvent) + if (i == #segmentsList) then + --print("current segment removed:", removedActors, "actors.") end - - if (can_garbage) then --n�o h� refer�ncias a este objeto - - if (not _actor.owner) then --pet - _actor:subtract_total (_overall_combat) - end - - --apaga a refer�ncia deste jogador na tabela overall - _iter.cleaned = _iter.cleaned+1 - - _table_remove(conteudo, _iter.index) - - _iter.data = conteudo [_iter.index] - else - _iter.index = _iter.index + 1 - _iter.data = conteudo [_iter.index] - end - + amountRemoved = amountRemoved + removedActors end - --termina o coletor de lixo - if (_iter.cleaned > 0) then - _overall_combat[tipo].need_refresh = true - ReconstroiMapa (_overall_combat [tipo]) - limpados = limpados + _iter.cleaned + ---@type combat + local overallCombatObject = Details.tabela_overall + amountRemoved = amountRemoved + collectGarbage(overallCombatObject, overriteLastEvent) + + if (amountRemoved > 0) then + Details:InstanciaCallFunction(Details.ScheduleUpdate) + Details:RefreshMainWindow(-1) end - if (limpados > 0) then - _detalhes:InstanciaCallFunction(_detalhes.ScheduleUpdate) - _detalhes:RefreshMainWindow(-1) - end - - return limpados - end + return amountRemoved + end \ No newline at end of file diff --git a/core/parser.lua b/core/parser.lua index 828016d5..23423ce9 100755 --- a/core/parser.lua +++ b/core/parser.lua @@ -108,7 +108,7 @@ --pets local container_pets = {} --just initialize table (placeholder) --ignore deaths - local ignore_death = {} + local ignore_death_cache = {} --cache local cacheAnything = { arenaHealth = {}, @@ -2476,7 +2476,7 @@ C_Timer.After(0.05, function() --25/12/2022: enabled the delay to wait the combatlog dump damage events which will happen after the buff is applied parser:dead("UNIT_DIED", time, sourceSerial, sourceName, sourceFlags, targetSerial, targetName, targetFlags) - ignore_death [sourceName] = true + ignore_death_cache [sourceName] = true end) return @@ -4093,8 +4093,8 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 --must be in combat _in_combat ) then - if (ignore_death[targetName]) then - ignore_death[targetName] = nil + if (ignore_death_cache[targetName]) then + ignore_death_cache[targetName] = nil return end @@ -4129,6 +4129,10 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 recordedEvents = _current_combat:CreateLastEventsTable(targetName) end + --during a regular combat, 99.9% of the events aren't used by the death log + --hence the process of getting data for the death log is made as fast as it can be + --when a death occurs, the death log data is then parsed and built, the next 200 lines does this processing + --lesses index = older / higher index = newer --[=[ @@ -4326,10 +4330,12 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 overallDeathTable.dead_at = mythicPlusElapsedTime --save data about the mythic run in the deathTable which goes in the regular segment + --confused? 'playerDeathTable' is added into the '_current_combat.last_events_tables' ~20 above on a tinsert playerDeathTable["mythic_plus"] = true playerDeathTable["mythic_plus_dead_at"] = mythicPlusElapsedTime playerDeathTable["mythic_plus_dead_at_string"] = overallDeathTable[6] + --now add the death table into the overall data (this is the regular overall data, not the mythic plus overall data) tinsert(_detalhes.tabela_overall.last_events_tables, #_detalhes.tabela_overall.last_events_tables + 1, overallDeathTable) end end @@ -5557,7 +5563,7 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 if (_detalhes.in_group) then --player entered in a group, cleanup and set the new enviromnent - Details:RestartInternalGarbageCollector(true) + Details222.GarbageCollector.RestartInternalGarbageCollector(true) Details:WipePets() Details:SchedulePetUpdate(1) Details:InstanceCall(Details.AdjustAlphaByContext) @@ -5577,7 +5583,7 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 if (not _detalhes.in_group) then --player left the group, run routines to cleanup the environment - Details:RestartInternalGarbageCollector(true) + Details222.GarbageCollector.RestartInternalGarbageCollector(true) Details:WipePets() Details:SchedulePetUpdate(1) wipe(Details.details_users) @@ -5965,7 +5971,7 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1 wipe(enemy_cast_cache) wipe(empower_cache) - wipe(ignore_death) + wipe(ignore_death_cache) wipe(reflection_damage) wipe(reflection_debuffs) diff --git a/core/timemachine.lua b/core/timemachine.lua index ec7c5f47..24845a77 100644 --- a/core/timemachine.lua +++ b/core/timemachine.lua @@ -76,6 +76,10 @@ end end + function timeMachine:TurnOn() + return timeMachine:Ligar() + end + function timeMachine:Ligar() self.atualizador = self:ScheduleRepeatingTimer ("Core", 1) self.ligada = true @@ -89,6 +93,10 @@ end end + function timeMachine:TurnOff() + return timeMachine:Desligar() + end + function timeMachine:Desligar() self.ligada = false self.tabelas = nil @@ -104,6 +112,10 @@ self.tabelas = {{}, {}} --1 dano 2 cura end + function timeMachine:UnregisterActor(actorObject) + return actorObject:DesregistrarNaTimeMachine() + end + function _detalhes:DesregistrarNaTimeMachine() if (not timeMachine.ligada) then return @@ -127,9 +139,9 @@ local esta_tabela = timeMachine.tabelas [self.tipo] tinsert(esta_tabela, self) self.timeMachine = #esta_tabela - end + end - function _detalhes:ManutencaoTimeMachine() + function Details:TimeMachineMaintenance() for tipo, tabela in ipairs(timeMachine.tabelas) do local t = {} local removed = 0 diff --git a/startup.lua b/startup.lua index 165ff9df..e08fcd8e 100644 --- a/startup.lua +++ b/startup.lua @@ -1,14 +1,20 @@ -local UnitGroupRolesAssigned = _G.DetailsFramework.UnitGroupRolesAssigned -local wipe = _G.wipe -local C_Timer = _G.C_Timer -local CreateFrame = _G.CreateFrame +--[=[ + Details startup file + The function Details:StartMeUp() is called when the addon is fully loaded with saved variables and profiles +--]=] + local Loc = _G.LibStub("AceLocale-3.0"):GetLocale("Details") local _ local tocName, Details222 = ... --start funtion -function Details:StartMeUp() --I'll never stop! +function Details:StartMeUp() + if (Details.AndIWillNeverStop) then + return + end + Details.AndIWillNeverStop = true + --set default time for arena and bg to be the Details! load time in case the client loads mid event Details.lastArenaStartTime = GetTime() Details.lastBattlegroundStartTime = GetTime() @@ -24,31 +30,31 @@ function Details:StartMeUp() --I'll never stop! --single click row function replace --damage, dps, damage taken, friendly fire - self.row_singleclick_overwrite[1] = {true, true, true, true, self.atributo_damage.ReportSingleFragsLine, self.atributo_damage.ReportEnemyDamageTaken, self.atributo_damage.ReportSingleVoidZoneLine, self.atributo_damage.ReportSingleDTBSLine} + Details.row_singleclick_overwrite[1] = {true, true, true, true, Details.atributo_damage.ReportSingleFragsLine, Details.atributo_damage.ReportEnemyDamageTaken, Details.atributo_damage.ReportSingleVoidZoneLine, Details.atributo_damage.ReportSingleDTBSLine} --healing, hps, overheal, healing taken - self.row_singleclick_overwrite[2] = {true, true, true, true, false, self.atributo_heal.ReportSingleDamagePreventedLine} + Details.row_singleclick_overwrite[2] = {true, true, true, true, false, Details.atributo_heal.ReportSingleDamagePreventedLine} --mana, rage, energy, runepower - self.row_singleclick_overwrite[3] = {true, true, true, true} + Details.row_singleclick_overwrite[3] = {true, true, true, true} --cc breaks, ress, interrupts, dispells, deaths - self.row_singleclick_overwrite[4] = {true, true, true, true, self.atributo_misc.ReportSingleDeadLine, self.atributo_misc.ReportSingleCooldownLine, self.atributo_misc.ReportSingleBuffUptimeLine, self.atributo_misc.ReportSingleDebuffUptimeLine} + Details.row_singleclick_overwrite[4] = {true, true, true, true, Details.atributo_misc.ReportSingleDeadLine, Details.atributo_misc.ReportSingleCooldownLine, Details.atributo_misc.ReportSingleBuffUptimeLine, Details.atributo_misc.ReportSingleDebuffUptimeLine} - function self:ReplaceRowSingleClickFunction(attribute, subAttribute, func) + function Details:ReplaceRowSingleClickFunction(attribute, subAttribute, func) assert(type(attribute) == "number" and attribute >= 1 and attribute <= 4, "ReplaceRowSingleClickFunction expects a attribute index on #1 argument.") assert(type(subAttribute) == "number" and subAttribute >= 1 and subAttribute <= 10, "ReplaceRowSingleClickFunction expects a sub attribute index on #2 argument.") assert(type(func) == "function", "ReplaceRowSingleClickFunction expects a function on #3 argument.") - self.row_singleclick_overwrite[attribute][subAttribute] = func + Details.row_singleclick_overwrite[attribute][subAttribute] = func return true end - self.click_to_report_color = {1, 0.8, 0, 1} + Details.click_to_report_color = {1, 0.8, 0, 1} --death tooltip function, exposed for 3rd party customization --called when the mouse hover over a player line when displaying deaths --the function called receives 4 parameters: instanceObject, lineFrame, combatObject, deathTable --@instance: the details! object of the window showing the deaths --@lineFrame: the frame to setpoint your frame - --@combatObject: the combat it self + --@combatObject: the combat itself --@deathTable: a table containing all the information about the player's death Details.ShowDeathTooltipFunction = Details.ShowDeathTooltip @@ -56,83 +62,83 @@ function Details:StartMeUp() --I'll never stop! --initialize --plugin container - self:CreatePluginWindowContainer() - self:InitializeForge() --to install into the container plugin - self:InitializeRaidHistoryWindow() - --self:InitializeOptionsWindow() + Details:CreatePluginWindowContainer() + Details:InitializeForge() --to install into the container plugin + Details:InitializeRaidHistoryWindow() + --Details:InitializeOptionsWindow() C_Timer.After(2, function() - self:InitializeAuraCreationWindow() + Details:InitializeAuraCreationWindow() end) - self:InitializeCustomDisplayWindow() - self:InitializeAPIWindow() - self:InitializeRunCodeWindow() - self:InitializePlaterIntegrationWindow() - self:InitializeMacrosWindow() + Details:InitializeCustomDisplayWindow() + Details:InitializeAPIWindow() + Details:InitializeRunCodeWindow() + Details:InitializePlaterIntegrationWindow() + Details:InitializeMacrosWindow() - if (self.ocd_tracker.show_options) then - self:InitializeCDTrackerWindow() + if (Details.ocd_tracker.show_options) then + Details:InitializeCDTrackerWindow() end --custom window - self.custom = self.custom or {} + Details.custom = Details.custom or {} --micro button alert --"MainMenuBarMicroButton" has been removed on 9.0 - self.MicroButtonAlert = CreateFrame("frame", "DetailsMicroButtonAlert", UIParent) - self.MicroButtonAlert.Text = self.MicroButtonAlert:CreateFontString(nil, "overlay", "GameFontNormal") - self.MicroButtonAlert.Text:SetPoint("center") - self.MicroButtonAlert:Hide() + Details.MicroButtonAlert = CreateFrame("frame", "DetailsMicroButtonAlert", UIParent) + Details.MicroButtonAlert.Text = Details.MicroButtonAlert:CreateFontString(nil, "overlay", "GameFontNormal") + Details.MicroButtonAlert.Text:SetPoint("center") + Details.MicroButtonAlert:Hide() --actor details window - self.playerDetailWindow = self.gump:CriaJanelaInfo() - Details.FadeHandler.Fader(self.playerDetailWindow, 1) + Details.playerDetailWindow = Details.gump:CriaJanelaInfo() + Details.FadeHandler.Fader(Details.playerDetailWindow, 1) --copy and paste window - self:CreateCopyPasteWindow() - self.CreateCopyPasteWindow = nil + Details:CreateCopyPasteWindow() + Details.CreateCopyPasteWindow = nil --start instances - if (self:GetNumInstancesAmount() == 0) then - self:CriarInstancia() + if (Details:GetNumInstancesAmount() == 0) then + Details:CreateInstance() end - self:GetLowerInstanceNumber() + Details:GetLowerInstanceNumber() --start time machine - self.timeMachine:Ligar() + Details.timeMachine:TurnOn() --update abbreviation shortcut - self.atributo_damage:UpdateSelectedToKFunction() - self.atributo_heal:UpdateSelectedToKFunction() - self.atributo_energy:UpdateSelectedToKFunction() - self.atributo_misc:UpdateSelectedToKFunction() - self.atributo_custom:UpdateSelectedToKFunction() + Details.atributo_damage:UpdateSelectedToKFunction() + Details.atributo_heal:UpdateSelectedToKFunction() + Details.atributo_energy:UpdateSelectedToKFunction() + Details.atributo_misc:UpdateSelectedToKFunction() + Details.atributo_custom:UpdateSelectedToKFunction() --start instances updater - self:CheckSwitchOnLogon() + Details:CheckSwitchOnLogon() - function Details:ScheduledWindowUpdate(forced) - if (not forced and Details.in_combat) then + function Details:ScheduledWindowUpdate(bIsForced) + if (not bIsForced and Details.in_combat) then return end Details.scheduled_window_update = nil Details:RefreshMainWindow(-1, true) end - - function Details:ScheduleWindowUpdate(time, forced) + + function Details:ScheduleWindowUpdate(time, bIsForced) if (Details.scheduled_window_update) then Details.Schedules.Cancel(Details.scheduled_window_update) Details.scheduled_window_update = nil end - Details.scheduled_window_update = Details.Schedules.NewTimer(time or 1, Details.ScheduledWindowUpdate, Details, forced) + Details.scheduled_window_update = Details.Schedules.NewTimer(time or 1, Details.ScheduledWindowUpdate, Details, bIsForced) end - self:RefreshMainWindow(-1, true) + Details:RefreshMainWindow(-1, true) Details:RefreshUpdater() - for id = 1, Details:GetNumInstances() do - local instance = Details:GetInstance(id) + for instanceId = 1, Details:GetNumInstances() do + local instance = Details:GetInstance(instanceId) if (instance:IsEnabled()) then Details.Schedules.NewTimer(1, Details.RefreshBars, Details, instance) Details.Schedules.NewTimer(1, Details.InstanceReset, Details, instance) @@ -140,7 +146,7 @@ function Details:StartMeUp() --I'll never stop! end end - function self:RefreshAfterStartup() + function Details:RefreshAfterStartup() --repair nicknames as nicknames aren't saved within the actor when leaving the game if (not Details.ignore_nicktag) then local currentCombat = Details:GetCurrentCombat() @@ -156,7 +162,7 @@ function Details:StartMeUp() --I'll never stop! local refreshAllInstances = -1 local forceRefresh = true - self:RefreshMainWindow(refreshAllInstances, forceRefresh) + Details:RefreshMainWindow(refreshAllInstances, forceRefresh) local lowerInstance = Details:GetLowerInstanceNumber() for id = 1, Details:GetNumInstances() do @@ -177,41 +183,43 @@ function Details:StartMeUp() --I'll never stop! end end - --refresh lower instance plugin icons and skin + --after plugins are loaded and they have registered their icons, reorganize them after the start Details.ToolBar:ReorganizeIcons() --refresh skin for other windows if (lowerInstance) then - for id = lowerInstance+1, Details:GetNumInstances() do - local instance = Details:GetInstance(id) + for instanceId = lowerInstance+1, Details:GetNumInstances() do + local instance = Details:GetInstance(instanceId) if (instance and instance.baseframe and instance.ativa) then instance:ChangeSkin() end end end - self.RefreshAfterStartup = nil + Details.RefreshAfterStartup = nil + --the wallpaper could have been loaded by another addon + --need to refresh wallpaper a few frames or seconds after the game starts function Details:CheckWallpaperAfterStartup() if (not Details.profile_loaded) then Details.Schedules.NewTimer(5, Details.CheckWallpaperAfterStartup, Details) end - for id = 1, self.instances_amount do - local instance = self:GetInstance(id) + for id = 1, Details.instances_amount do + local instance = Details:GetInstance(id) if (instance and instance:IsEnabled()) then if (not instance.wallpaper.enabled) then instance:InstanceWallpaper(false) end instance.do_not_snap = true - self.move_janela_func(instance.baseframe, true, instance, true) - self.move_janela_func(instance.baseframe, false, instance, true) + Details.move_janela_func(instance.baseframe, true, instance, true) + Details.move_janela_func(instance.baseframe, false, instance, true) instance.do_not_snap = false end end - self.CheckWallpaperAfterStartup = nil + Details.CheckWallpaperAfterStartup = nil Details.profile_loaded = nil end Details.Schedules.NewTimer(5, Details.CheckWallpaperAfterStartup, Details) @@ -220,59 +228,58 @@ function Details:StartMeUp() --I'll never stop! Details.Schedules.NewTimer(5, Details.RefreshAfterStartup, Details) --start garbage collector - self.ultima_coleta = 0 - self.intervalo_coleta = 720 - self.intervalo_memoria = 180 - self.garbagecollect = Details.Schedules.NewTicker(self.intervalo_coleta, Details.RestartInternalGarbageCollector, Details) - self.next_memory_check = _G.time() + self.intervalo_memoria + Details222.GarbageCollector.lastCollectTime = 0 + Details222.GarbageCollector.intervalTime = 300 + Details222.GarbageCollector.collectorTimer = Details.Schedules.NewTicker(Details222.GarbageCollector.intervalTime, Details222.GarbageCollector.RestartInternalGarbageCollector) --player role - self.last_assigned_role = UnitGroupRolesAssigned and UnitGroupRolesAssigned("player") + local UnitGroupRolesAssigned = _G.DetailsFramework.UnitGroupRolesAssigned + Details.last_assigned_role = UnitGroupRolesAssigned and UnitGroupRolesAssigned("player") --load parser capture options - self:CaptureRefresh() + Details:CaptureRefresh() --register parser events - self.listener:RegisterEvent("PLAYER_REGEN_DISABLED") - self.listener:RegisterEvent("PLAYER_REGEN_ENABLED") - self.listener:RegisterEvent("UNIT_PET") + Details.listener:RegisterEvent("PLAYER_REGEN_DISABLED") + Details.listener:RegisterEvent("PLAYER_REGEN_ENABLED") + Details.listener:RegisterEvent("UNIT_PET") - self.listener:RegisterEvent("GROUP_ROSTER_UPDATE") - self.listener:RegisterEvent("INSTANCE_ENCOUNTER_ENGAGE_UNIT") + Details.listener:RegisterEvent("GROUP_ROSTER_UPDATE") + Details.listener:RegisterEvent("INSTANCE_ENCOUNTER_ENGAGE_UNIT") - self.listener:RegisterEvent("ZONE_CHANGED_NEW_AREA") - self.listener:RegisterEvent("PLAYER_ENTERING_WORLD") + Details.listener:RegisterEvent("ZONE_CHANGED_NEW_AREA") + Details.listener:RegisterEvent("PLAYER_ENTERING_WORLD") - self.listener:RegisterEvent("ENCOUNTER_START") - self.listener:RegisterEvent("ENCOUNTER_END") + Details.listener:RegisterEvent("ENCOUNTER_START") + Details.listener:RegisterEvent("ENCOUNTER_END") - self.listener:RegisterEvent("START_TIMER") - self.listener:RegisterEvent("UNIT_NAME_UPDATE") + Details.listener:RegisterEvent("START_TIMER") + Details.listener:RegisterEvent("UNIT_NAME_UPDATE") - self.listener:RegisterEvent("PLAYER_ROLES_ASSIGNED") - self.listener:RegisterEvent("ROLE_CHANGED_INFORM") + Details.listener:RegisterEvent("PLAYER_ROLES_ASSIGNED") + Details.listener:RegisterEvent("ROLE_CHANGED_INFORM") - self.listener:RegisterEvent("UNIT_FACTION") + Details.listener:RegisterEvent("UNIT_FACTION") - self.listener:RegisterEvent("PLAYER_TARGET_CHANGED") + Details.listener:RegisterEvent("PLAYER_TARGET_CHANGED") if (not DetailsFramework.IsTimewalkWoW()) then - self.listener:RegisterEvent("PET_BATTLE_OPENING_START") - self.listener:RegisterEvent("PET_BATTLE_CLOSE") - self.listener:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED") - self.listener:RegisterEvent("PLAYER_TALENT_UPDATE") - self.listener:RegisterEvent("CHALLENGE_MODE_START") - self.listener:RegisterEvent("CHALLENGE_MODE_COMPLETED") + Details.listener:RegisterEvent("PET_BATTLE_OPENING_START") + Details.listener:RegisterEvent("PET_BATTLE_CLOSE") + Details.listener:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED") + Details.listener:RegisterEvent("PLAYER_TALENT_UPDATE") + Details.listener:RegisterEvent("CHALLENGE_MODE_START") + Details.listener:RegisterEvent("CHALLENGE_MODE_COMPLETED") end - self.parser_frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") + Details.parser_frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") --update is in group - self.details_users = {} - self.in_group = IsInGroup() or IsInRaid() + Details.details_users = {} + Details.in_group = IsInGroup() or IsInRaid() --done - self.initializing = nil + Details.initializing = nil --scan pets Details:SchedulePetUpdate(1) @@ -283,13 +290,13 @@ function Details:StartMeUp() --I'll never stop! --send instance open signal for id, instancia in Details:ListInstances() do if (instancia.ativa) then - self:SendEvent("DETAILS_INSTANCE_OPEN", nil, instancia) + Details:SendEvent("DETAILS_INSTANCE_OPEN", nil, instancia) end end --send details startup done signal - function self:AnnounceStartup() - self:SendEvent("DETAILS_STARTED", "SEND_TO_ALL") + function Details:AnnounceStartup() + Details:SendEvent("DETAILS_STARTED", "SEND_TO_ALL") if (Details.in_group) then Details:SendEvent("GROUP_ONENTER") @@ -310,7 +317,7 @@ function Details:StartMeUp() --I'll never stop! end --announce alpha version - function self:AnnounceVersion() + function Details:AnnounceVersion() for index, instancia in Details:ListInstances() do if (instancia.ativa) then Details.FadeHandler.Fader(instancia._version, "in", 0.1) @@ -325,15 +332,15 @@ function Details:StartMeUp() --I'll never stop! DetailsTooltipAnchor:Restore() --check is this is the first run ever - if (self.is_first_run) then - if (#self.custom == 0) then + if (Details.is_first_run) then + if (#Details.custom == 0) then Details:AddDefaultCustomDisplays() end Details:FillUserCustomSpells() end --check is this is the first run of this version - if (self.is_version_first_run) then + if (Details.is_version_first_run) then local lowerInstanceId = Details:GetLowerInstanceNumber() if (lowerInstanceId) then lowerInstanceId = Details:GetInstance(lowerInstanceId) @@ -382,7 +389,7 @@ function Details:StartMeUp() --I'll never stop! --version Details.FadeHandler.Fader(instance._version, 0) - instance._version:SetText("Details! " .. Details.userversion .. " (core " .. self.realversion .. ")") + instance._version:SetText("Details! " .. Details.userversion .. " (core " .. Details.realversion .. ")") instance._version:SetTextColor(1, 1, 1, .35) instance._version:SetPoint("bottomleft", instance.baseframe, "bottomleft", 5, 1) @@ -405,7 +412,7 @@ function Details:StartMeUp() --I'll never stop! --Details:OpenCustomDisplayWindow() --Details:OpenWelcomeWindow() end - + Details.Schedules.NewTimer(2, Details.OpenOptionsWindowAtStart, Details) --Details:OpenCustomDisplayWindow() @@ -425,7 +432,7 @@ function Details:StartMeUp() --I'll never stop! Details:StartAnnouncers() --open welcome - if (self.is_first_run) then + if (Details.is_first_run) then C_Timer.After(1, function() --wait details full load the rest of the systems before executing the welcome window Details:OpenWelcomeWindow() end)