WoWInterface SVN CooldownIconsRevamped

[/] [branches/] [CooldownIconsR_Compiler.lua] - Rev 36

Compare with Previous | Blame | View Log

local LCI = LibStub("LibCooldownIcons")
local CIR = CooldownIconsR
local CompileEnv = {format=format, tostring=tostring, getglobal=getglobal};
CIR.CompileEnv = CompileEnv
local tonumber, _G, pairs, unpack, tconcat, wipe, setfenv = tonumber, _G, pairs, unpack, table.concat, wipe, setfenv

CIR.comp={}

--creates a table of a table look-alike string
local function toTable(str)
  str=string.gsub(str,"(%{?)(%}?)", "")
  if str~="" and str~=nil then
    local rT = assert(loadstring("return {"..str.."}"))
    setfenv(rT, CIR.CompileEnv)
    return rT()
  else
    return {  }
  end
end

function CIR:CompileIcon(icon,text)
        CIR.comp[icon]={} --reset + init
        local filter = "(%w+)%(([%w%'%(%)%s]*)[%s]*%,?[%s]*(%w*)%=?([%{?%w%,%}?]*)[%s]*%,?[%s]*(%w*)%=?([%{?%w%,%}?]*)%)"
        string.gsub(text,filter,function(cmd,name,case1,case1_args,case2,case2_args)
                if not CIR.comp[icon][cmd] then
                  CIR.comp[icon][cmd]={}
--                CIR.comp[icon][cmd][0]=cmd
                end
                if not CIR.comp[icon][cmd][name] then
                  CIR.comp[icon][cmd][name]={}
--                CIR.comp[icon][cmd][name][0]=name
                end
                if not CIR.comp[icon][cmd][name][case1] then
                  CIR.comp[icon][cmd][name][case1]=toTable(case1_args)
--                CIR.comp[icon][cmd][name][case1][0]=case1
                end
                if not CIR.comp[icon][cmd][name][case2] then
                  CIR.comp[icon][cmd][name][case2]=toTable(case2_args)
--                CIR.comp[icon][cmd][name][case2][0]=case2
                end
        end)
        self:CompileLines(CIR.comp[icon],icon)
end

function CIR:CompileLines(lines,icon)
        local stack={}
        for cmd,cmdT in pairs(lines) do
                stack[#stack+1]=cmd -- stack[1] = cmd
                for name,nameT in pairs(cmdT) do
                        stack[#stack+1]=name -- stack[2] = name,flag,id
                        for case,caseT in pairs(nameT) do
                        stack[#stack+1]=case --stack[n>=3 ,odd(n) ] = case (stance,talentgroup), "unlimited" cases addable
                        stack[#stack+1]=caseT --stack[n>=4,even(n)] = casei_args , args are tables!
                        end
                        --Until here 1code-line is finished -> compile (+reset) stack
                        CIR:CompileStack(stack,icon)
                        --table.foreach(stack,print)
                        stack={}
                        stack[#stack+1]=cmd
                end
        end
end
function CIR:CompileStack(stack,icon)
        --check and manipulate stack
        local stack_size=#stack
        local i=1
        while (1==1) do
                if i<=stack_size then
                        local v = stack[i]
                        if type(v)~='table' and v=="" then
                                tremove(stack,i)
                        elseif type(v)=='table' and #v==0 then
                                tremove(stack,i) --remove empty cases to easier case detection
                        else
                                i=i+1
                        end
                else
                        break
                end
        end
        --table.foreach(stack,print)
        --[[
        stack[1] spell
        stack[2] Tricks of the Trade
        stack[3] case1
        stack[4] {tbl}
        stack[5] case2
        stack[6] {tbl}
        ..
        stack[N] caseN
        stack[N+1] {tbl}
        ]]
        if #stack>2 and #stack%2==0 then --has still args and even number of args (2+((case+case_args)*n)) n<-N\{0}
                local precond=true
                for i=3,#stack,2 do --i & i+1 <- 1case
                        if #stack[i+1]>0 then
                                local conditional,event = LCI:GetConditionalByCase(stack[i])
                                precond=precond and LCI:inTable(conditional,stack[i+1])
                                --CIR.eventTable=LCI:RegisterFrameForEvent(icon,event,CIR.eventTable)
                                if precond and not stack[i+2] then --true & last iteration
                                        CIR.icons[icon]:Show()
                                        CIR.icons[icon].cmd=stack[1]
                                        CIR.icons[icon].watch=stack[2]
                                        CIR.icons[icon].tex:SetTexture(CIR:SetTextureByCmd(stack[1],stack[2]) or CIR.Icon_Nil)
                                        CIR.eventTable=LCI:RegisterFrameForEvent(icon,event,CIR.eventTable)
                                elseif not precond and not stack[i+2] then
                                        if not CIR.db.char.config then
                                                CIR:DEBUG(icon.." hide.")
                                                CIR.icons[icon].tex:SetTexture(CIR.Icon_Nil)
                                                CIR.icons[icon].watch=nil
                                                CIR.icons[icon].cmd=stack[1]
                                                CIR.icons[icon]:Hide()
                                        else
                                                CIR:DEBUG(icon.." show.")
                                                CIR.icons[icon].tex:SetTexture(CIR.Icon_Nil)
                                                CIR.icons[icon].watch=nil
                                                CIR.icons[icon].cmd=stack[1]
                                                CIR.icons[icon]:Show()
                                        end
                                        CIR.eventTable=LCI:RegisterFrameForEvent(icon,event,CIR.eventTable)
                                end
                        else
                                CIR.icons[icon].cmd=stack[1]
                                CIR.icons[icon].watch=stack[2]
                                --CIR.eventTable=LCI:UnregisterFrameForEvent(icon,event,CIR.eventTable)
                                --error("There are no arguments for case "..stack[i]..". \nCheck input: "..CIR.db.icondb[icon].options.script) 
                                --No arguments => all allowed / but will listen to it, - but simply it could be "ignored"
                        end
                end
                --print(tostring(precond))
        else
                LCI:UnregisterFrameForAllEvents(icon,CIR.eventTable)
                CIR.icons[icon]:Show()
                CIR.icons[icon].cmd=stack[1]
                CIR.icons[icon].watch=stack[2]
                CIR.icons[icon].tex:SetTexture(CIR:SetTextureByCmd(stack[1],stack[2]) or CIR.Icon_Nil)
        end
end

--[[
function CIR:AddScript(icon,compileTable)
        print(#compileTable)
        local i = #compileTable
        for k=1,i do
                local case=compileTable[k][4]
                local case_args=compileTable[k][3]
                if case=='stance' then
                        local form = GetShapeshiftForm()
                        if LCI:inTable(form,case_args) then 
                                CIR.icons[icon].tex:SetTexture(CIR:SetTextureByCmd(compileTable[k][1],compileTable[k][2]) or CIR.Icon_Nil)
                        end
                        CIR:RegisterEvent("UPDATE_SHAPESHIFT_FORM")
                elseif case=='talentgroup' then
                        local tg = GetActiveTalentGroup()
                        if LCI:inTable(tg,case_args) then 
                                CIR.icons[icon].tex:SetTexture(CIR:SetTextureByCmd(compileTable[k][1],compileTable[k][2]) or CIR.Icon_Nil)
                        end
                        CIR:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED")
                end
        end
end


function CIR:CompileIcon(icon,text)
        local filter="(%w+)%(([^,%)]+),?%s*([^,%)]*),?%s*([^,%)]*)%)+"
        local i=0
        CIR.compiled[icon]={}
        string.gsub(text,filter,function(a,b,c,d)
                i=i+1
                CIR.compiled[icon][i]={}
                CIR.compiled[icon][i][#CIR.compiled[icon][i]+1]=a
                CIR.compiled[icon][i][#CIR.compiled[icon][i]+1]=b
                CIR.compiled[icon][i][#CIR.compiled[icon][i]+1]=c
                CIR.compiled[icon][i][#CIR.compiled[icon][i]+1]=d
        end)
        --UnregisterAllEvents
        for j=1,i do
                CIR.compiled[icon][j][3]=string.gsub(CIR.compiled[icon][j][3],"%-", "%,")
                local case_arg_table=loadstring("return {"..CIR.compiled[icon][j][3].."}")
                CIR.compiled[icon][j][3] = case_arg_table()
        end
        self:AddScript(icon,CIR.compiled[icon])
end


]]
function CIR:SetTextureByCmd(cmd,spell)
        local texture=nil
        if cmd=='spell' then
                texture=select(3,GetSpellInfo(spell))
        elseif cmd=='item' then
                texture=GetItemIcon(spell)
        elseif cmd=='flag' then
                texture=GetInventoryItemTexture("player",self:FlagToEquip(spell))
        end
        return (texture)
end

Compare with Previous | Blame