forked from Dusk/ShaguTweaks-ClassicAPI
142 lines
7.9 KiB
Lua
142 lines
7.9 KiB
Lua
local root=(arg[1] or '.')..'/'
|
|
assert(loadfile(root..'mods/cooldown-numbers.lua'))
|
|
local function read(path)local f=assert(io.open(root..path));local s=f:read('*a');f:close();return s end
|
|
local helpers=read('helpers.lua')
|
|
local a=assert(string.find(helpers,'ShaguTweaks.TimeConvert = function',1,true))
|
|
local b=assert(string.find(helpers,'\nend',a,true))
|
|
local reference={ShaguTweaks={},ceil=math.ceil}
|
|
setmetatable(reference,{__index=getfenv(0)})
|
|
local chunk=assert(loadstring(string.sub(helpers,a,b+3)));setfenv(chunk,reference);chunk()
|
|
local env=setmetatable({},{__index=getfenv(0)});env._G=env
|
|
local frames,formatted,cvar,now={},0,'1',101
|
|
local nativeFactory
|
|
local function newFrame(parent)
|
|
local f={parent=parent,scripts={},visible=true,alpha=1}
|
|
function f:GetParent()return self.parent end
|
|
function f:GetHeight()return self.height or 36 end
|
|
function f:GetFrameLevel()return 4 end
|
|
function f:GetAlpha()return self.alpha end
|
|
function f:SetAlpha(n)self.alpha=n end
|
|
function f:SetAllPoints()end
|
|
function f:SetFrameLevel()end
|
|
function f:SetScript(k,v)self.scripts[k]=v end
|
|
function f:RegisterEvent(k)self.event=k end
|
|
function f:Hide()self.visible=false end
|
|
function f:Show()self.visible=true end
|
|
function f:CreateFontString()
|
|
local text={}
|
|
function text:SetFont(font,size,flags)self.font,self.size,self.flags=font,size,flags end
|
|
function text:ClearAllPoints()end
|
|
function text:SetPoint()end
|
|
function text:SetTextColor()end
|
|
function text:SetText(value)self.value=value end
|
|
return text
|
|
end
|
|
return f
|
|
end
|
|
env.CreateFrame=function(kind,_,parent)
|
|
if kind=='Cooldown' and env.createNative then return env.createNative(parent) end
|
|
local f=newFrame(parent);table.insert(frames,f);return f
|
|
end
|
|
env.GetTime=function()return now end
|
|
env.GetCVar=function()return cvar end
|
|
env.SetCVar=function()error('must not change global cooldown policy')end
|
|
env.STANDARD_TEXT_FONT='font'
|
|
env.Enum={NumericRuleFormatRounding={Up=1}}
|
|
env.C_StringUtil={CreateNumericRuleFormatter=function()
|
|
formatted=formatted+1
|
|
local formatter={}
|
|
function formatter:SetBreakpoints(rules)self.rules=rules end
|
|
function formatter:FormatNumber(n)
|
|
local rule
|
|
for _,candidate in ipairs(self.rules)do if n>=candidate.threshold then rule=candidate end end
|
|
local function round(value,step)if step then return math.ceil(value/step)*step end;return value end
|
|
local value=round(n,rule.step)
|
|
if rule.components then value=round(value/rule.components[1].div,rule.components[1].step)end
|
|
return string.format(rule.format,value)
|
|
end
|
|
return formatter
|
|
end}
|
|
nativeFactory=env.C_StringUtil.CreateNumericRuleFormatter
|
|
local set
|
|
env.hooksecurefunc=function(name,callback)assert(name=='CooldownFrame_SetTimer');set=callback end
|
|
env.ShaguTweaks={T={},API={nativecooldowns=false},GetGlobalEnv=function()return env end,GetExpansion=function()return 'vanilla' end,
|
|
TimeConvert=reference.ShaguTweaks.TimeConvert,register=function(_,module)env.module=module;return module end}
|
|
local load=assert(loadfile(root..'mods/cooldown-numbers.lua'));setfenv(load,env);load();env.module:enable()
|
|
local parent=newFrame();parent.height=18
|
|
local function native(owner)
|
|
local f=newFrame(owner or parent);f.nativeText=f:CreateFontString()
|
|
function f:GetCountdownFontString()return self.nativeText end
|
|
function f:SetCountdownFormatter(value)self.formatter=value end
|
|
function f:SetMinimumCountdownDuration(value)self.minimum=value end
|
|
function f:SetHideCountdownNumbers(value)self.hidden=value end
|
|
function f:SetDrawSwipe(value)self.swipe=value end
|
|
function f:SetDrawEdge(value)self.edge=value end
|
|
function f:SetDrawBling(value)self.bling=value end
|
|
function f:SetCooldown(start,duration)self.start,self.duration=start,duration;self.visible=true;self.starts=(self.starts or 0)+1 end
|
|
return f
|
|
end
|
|
local cd=native();set(cd,100,20,1)
|
|
assert(not cd.cooldowntext and not cd.scripts.OnUpdate and not cd.hidden)
|
|
assert(cd.minimum==1999 and cd.nativeText.size==18*.64)
|
|
assert(table.getn(frames)==1 and frames[1].event=='CVAR_UPDATE')
|
|
local second=native();set(second,100,20,1)
|
|
assert(formatted==1 and second.formatter==cd.formatter,'one shared native formatter')
|
|
for _,n in ipairs({.01,.99,1,4.01,4.99,5,5.01,9.99,10,59,59.99,60,60.01,3599.99,3600,86399.99,86400,172801})do
|
|
assert(cd.formatter:FormatNumber(n)==reference.ShaguTweaks.TimeConvert(n),'TimeConvert mismatch at '..n)
|
|
end
|
|
set(cd,100,1.5,1);assert(cd.hidden and not cd.cooldowntext)
|
|
set(cd,100,2,1);assert(not cd.hidden)
|
|
set(cd,0,20,1);assert(cd.hidden)
|
|
set(cd,100,20,0);assert(cd.hidden)
|
|
set(cd,100,20,1);cd.noCooldownCount=true;set(cd,100,20,1);assert(cd.hidden)
|
|
cd.noCooldownCount=nil;cd.pfCooldownType='spell';set(cd,100,20,1);assert(cd.hidden)
|
|
cd.pfCooldownType=nil;cd.readable=true;set(cd,100,20,1);assert(cd.hidden)
|
|
cd.readable=nil
|
|
local foreign=native();foreign.pfCooldownType='spell';set(foreign,100,20,1)
|
|
assert(foreign.hidden==nil and foreign.formatter==nil,'must leave foreign-owned native setup alone')
|
|
local excluded=native();excluded.noCooldownCount=true;set(excluded,100,20,1)
|
|
assert(excluded.hidden and not excluded.cooldowntext and not excluded.formatter)
|
|
-- CVar changes switch existing native indicators without setting the CVar.
|
|
local watcher=frames[1]
|
|
cvar='0';watcher.scripts.OnEvent()
|
|
assert(cd.cooldowntext and cd.cooldowntext.visible and cd.hidden)
|
|
local function tick(frame,dt)env.this,env.arg1=frame,dt;frame.scripts.OnUpdate();env.this,env.arg1=nil,nil end
|
|
tick(cd.cooldowntext,.1);assert(cd.cooldowntext.text.value==reference.ShaguTweaks.TimeConvert(19))
|
|
local frameCount=table.getn(frames);watcher.scripts.OnEvent();assert(table.getn(frames)==frameCount)
|
|
cvar='1';watcher.scripts.OnEvent();assert(not cd.cooldowntext.visible and not cd.hidden)
|
|
-- Legacy Models keep the old renderer, including alpha, expiry and clock wrap.
|
|
local model=newFrame(parent);set(model,100,20,1);assert(model.cooldowntext.visible)
|
|
model.alpha=.4;tick(model.cooldowntext,.1);assert(model.cooldowntext.alpha==.4)
|
|
now=121;tick(model.cooldowntext,.1);assert(not model.cooldowntext.visible)
|
|
local cycle=2^32/1000;now=1;set(model,cycle-2,10,1);tick(model.cooldowntext,.1)
|
|
assert(model.cooldowntext.text.value==reference.ShaguTweaks.TimeConvert(7))
|
|
-- Native numeric children optimize legacy Models without changing their sweep.
|
|
env.ShaguTweaks.API.nativecooldowns=true;env.createNative=native
|
|
local legacy=newFrame(parent);set(legacy,1,20,1)
|
|
local numbers=legacy.stCountdownNativeFrame
|
|
assert(numbers and not legacy.cooldowntext and not numbers.scripts.OnUpdate)
|
|
assert(numbers.parent==legacy and numbers.start==1 and numbers.duration==20)
|
|
assert(numbers.swipe==false and numbers.edge==false and numbers.bling==false)
|
|
local starts=numbers.starts;set(numbers,1,20,1)
|
|
assert(numbers.starts==starts,'native helper must not recursively decorate itself')
|
|
set(legacy,1,1,1);assert(not numbers.visible)
|
|
set(legacy,1,20,1);assert(numbers.visible)
|
|
cvar='0';watcher.scripts.OnEvent();assert(not numbers.visible and legacy.cooldowntext.visible)
|
|
cvar='1';watcher.scripts.OnEvent();assert(numbers.visible and not legacy.cooldowntext.visible)
|
|
assert(legacy.stCountdownNativeFrame==numbers)
|
|
legacy.noCooldownCount=true;set(legacy,1,20,1);assert(not numbers.visible)
|
|
-- A rejected native frame creation safely falls back and is not retried.
|
|
local attempts=0;env.createNative=function()attempts=attempts+1;error('unsupported frame')end
|
|
local unsupported=newFrame(parent);set(unsupported,1,20,1);set(unsupported,1,20,1)
|
|
assert(unsupported.cooldowntext.visible and attempts==1)
|
|
env.ShaguTweaks.API.nativecooldowns=false
|
|
-- Missing formatter APIs retain one renderer, suppressing native duplicates.
|
|
env.C_StringUtil.CreateNumericRuleFormatter=nil
|
|
local older=native();set(older,1,20,1)
|
|
assert(older.hidden and older.cooldowntext.visible)
|
|
env.C_StringUtil.CreateNumericRuleFormatter=nativeFactory
|
|
set(model,1,1,1);assert(not model.cooldowntext.visible)
|
|
model.noCooldownCount=true;set(model,1,20,1);assert(not model.cooldowntext.visible)
|
|
print('Cooldown numbers: shared native formatter, TimeConvert boundaries, global-CVar ownership/live changes, foreign flags, GCDs, legacy/older API fallback, alpha/expiry and clock wrap passed')
|