From e63cc2b16a5065bdb9c5aa7d9b2d240c072d557c Mon Sep 17 00:00:00 2001 From: "Johnny C. Lam" Date: Tue, 15 Oct 2013 01:24:45 +0000 Subject: [PATCH] Implement time spans, which are continuous open intervals of time. Convert OvaleBestAction and OvaleCondition to use actual time spans instead of start/ending/nil to represent times. git-svn-id: svn://svn.curseforge.net/wow/ovale/mainline/trunk@1045 d5049fe3-3747-40f7-a4b5-f36d6801af5f --- Ovale.toc | 1 + OvaleBestAction.lua | 308 +++++++++++++++++---------------------------------- OvaleCondition.lua | 278 +++++++++++++++++++++------------------------- OvaleTimeSpan.lua | 96 ++++++++++++++++ compiler.pl | 7 ++ 5 files changed, 331 insertions(+), 359 deletions(-) create mode 100644 OvaleTimeSpan.lua diff --git a/Ovale.toc b/Ovale.toc index 294f457..69042a2 100644 --- a/Ovale.toc +++ b/Ovale.toc @@ -44,6 +44,7 @@ OvaleRecount.lua OvaleSkada.lua OvaleSpellBook.lua OvaleStance.lua +OvaleTimeSpan.lua # OvaleDamageTaken.lua OvalePaperDoll.lua diff --git a/OvaleBestAction.lua b/OvaleBestAction.lua index 5bfdec3..06b1fde 100644 --- a/OvaleBestAction.lua +++ b/OvaleBestAction.lua @@ -22,6 +22,7 @@ local OvalePower = Ovale.OvalePower local OvaleSpellBook = Ovale.OvaleSpellBook local OvaleStance = Ovale.OvaleStance local OvaleState = Ovale.OvaleState +local OvaleTimeSpan = Ovale.OvaleTimeSpan local floor = math.floor local ipairs = ipairs @@ -31,6 +32,11 @@ local select = select local strfind = string.find local tonumber = tonumber local tostring = tostring +local Complement = OvaleTimeSpan.Complement +local HasTime = OvaleTimeSpan.HasTime +local Intersect = OvaleTimeSpan.Intersect +local Measure = OvaleTimeSpan.Measure +local Union = OvaleTimeSpan.Union local API_GetActionCooldown = GetActionCooldown local API_GetActionTexture = GetActionTexture local API_GetItemIcon = GetItemIcon @@ -52,50 +58,6 @@ local self_serial = 0 -- -- -local function addTime(time1, duration) - if not time1 then - return nil - else - return time1 + duration - end -end - -local function isBeforeEqual(time1, time2) - return time1 and (not time2 or time1<=time2) -end - -local function isBefore(time1, time2) - return time1 and (not time2 or time1=time2) -end - -local function isAfter(time1, time2) - return not time1 or (time2 and time1>time2) -end - -local function minTime(time1, time2) - if isBefore(time1, time2) then - return time1 - else - return time2 - end -end - -local function isBetween(checkTime, startTime, endTime) - return isBeforeEqual(startTime, checkTime) and isAfterEqual(endTime, checkTime) -end - -local function maxTime(time1, time2) - if isAfter(time1, time2) then - return time1 - else - return time2 - end -end - local function PutValue(element, value, origin, rate) if not element.result then element.result = { type = "value" } @@ -111,36 +73,16 @@ local function ComputeAnd(element, atTime) Ovale:Logf("%s [%d]", element.type, element.nodeId) local self = OvaleBestAction local startA, endA = self:ComputeBool(element.a, atTime) - if not startA then - Ovale:Logf("%s return nil [%d]", element.type, element.nodeId) - return nil - end - if startA == endA then - Ovale:Logf("%s return startA=endA [%d]", element.type, element.nodeId) - return nil - end - local startB, endB, prioriteB, elementB - if element.type == "if" then - startB, endB, prioriteB, elementB = self:Compute(element.b, atTime) - else - startB, endB, prioriteB, elementB = self:ComputeBool(element.b, atTime) - end - -- If the "then" clause is a "wait" node, then only wait if the conditions are true. - if elementB and elementB.wait and not isBetween(atTime, startA, endA) then - elementB.wait = nil - end - if isAfter(startB, endA) or isAfter(startA, endB) then - Ovale:Logf("%s return nil [%d]", element.type, element.nodeId) + -- Short-circuit evaluation of left argument to AND. + if Measure(startA, endA) == 0 then + Ovale:Logf("%s return timespan with measure 0 [%d]", element.type, element.nodeId) return nil end - if isBefore(startB, startA) then - startB = startA - end - if isAfter(endB, endA) then - endB = endA - end - Ovale:Logf("%s return %s, %s [%d]", element.type, startB, endB, element.nodeId) - return startB, endB, prioriteB, elementB + local startB, endB = self:ComputeBool(element.b, atTime) + -- Take intersection of (startA, endA) and (startB, endB). + startA, endA = Intersect(startA, endA, startB, endB) + Ovale:Logf("%s returns %s, %s [%d]", element.type, startA, endA, element.nodeId) + return startA, endA end local function ComputeArithmetic(element, atTime) @@ -149,13 +91,9 @@ local function ComputeArithmetic(element, atTime) local startB, endB, _, elementB = self:Compute(element.b, atTime) -- Take intersection of (startA, endA) and (startB, endB) - if isBefore(startA, startB) then - startA = startB - end - if isAfter(endA, endB) then - endA = endB - end - if not isBefore(startA, endA) then + startA, endA = Intersect(startA, endA, startB, endB) + if Measure(startA, endA) == 0 then + Ovale:Logf("%s return timespan with measure 0 [%d]", element.type, element.nodeId) return nil end @@ -251,13 +189,8 @@ local function ComputeCompare(element, atTime) local startB, endB, _, elementB = self:Compute(element.b, atTime) -- Take intersection of (startA, endA) and (startB, endB) - if isBefore(startA, startB) then - startA = startB - end - if isAfter(endA, endB) then - endA = endB - end - if not isBefore(startA, endA) then + startA, endA = Intersect(startA, endA, startB, endB) + if Measure(startA, endA) == 0 then return nil end @@ -273,8 +206,9 @@ local function ComputeCompare(element, atTime) local x = elementB and elementB.value or 0 local y = elementB and elementB.origin or 0 local z = elementB and elementB.rate or 0 + local operator = element.operator - Ovale:Logf("%f+(t-%f)*%f %s %f+(t-%f)*%f [%d]", a, b, c, element.operator, x, y, z, element.nodeId) + Ovale:Logf("%f+(t-%f)*%f %s %f+(t-%f)*%f [%d]", a, b, c, operator, x, y, z, element.nodeId) --[[ A(t) = B(t) @@ -286,34 +220,30 @@ local function ComputeCompare(element, atTime) local A = a - b*c local B = x - y*z if c == z then - if (element.operator == "==" and A == B) - or (element.operator == "<" and A < B) - or (element.operator == "<=" and A <= B) - or (element.operator == ">" and A > B) - or (element.operator == ">=" and A >= B) then - return startA, endA + if not ((operator == "==" and A == B) + or (operator == "<" and A < B) + or (operator == "<=" and A <= B) + or (operator == ">" and A > B) + or (operator == ">=" and A >= B)) then + startA, endA = nil, nil end else local t = (B - A)/(c - z) - if (c > z and element.operator == "<") - or (c > z and element.operator == "<=") - or (c < z and element.operator == ">") - or (c < z and element.operator == ">=") then - -- (startA, endA) intersect (-inf, t) - endA = minTime(endA, t) - end - if (c < z and element.operator == "<") - or (c < z and element.operator == "<=") - or (c > z and element.operator == ">") - or (c > z and element.operator == ">=") then - -- (startA, endA) intersect (t, inf) - startA = maxTime(startA, t) + if (c > z and operator == "<") + or (c > z and operator == "<=") + or (c < z and operator == ">") + or (c < z and operator == ">=") then + startA, endA = Intersect(startA, endA, 0, t) end - if isBefore(startA, endA) then - return startA, endA + if (c < z and operator == "<") + or (c < z and operator == "<=") + or (c > z and operator == ">") + or (c > z and operator == ">=") then + startA, endA = Intersect(startA, endA, t, math.huge) end end - return nil + Ovale:Logf("compare %s returns %s, %s [%d]", operator, startA, endA, element.nodeId) + return startA, endA end local function ComputeCustomFunction(element, atTime) @@ -364,7 +294,9 @@ local function ComputeFunction(element, atTime) end if actionEnable and actionEnable > 0 then - local start + local start, ending = 0, math.huge + local priority = element.params.priority or OVALE_DEFAULT_PRIORITY + if actionCooldownDuration and actionCooldownStart and actionCooldownStart > 0 then start = actionCooldownDuration + actionCooldownStart else @@ -394,8 +326,7 @@ local function ComputeFunction(element, atTime) end end Ovale:Logf("Action %s can start at %f", element.params[1], start) - local priority = element.params.priority or OVALE_DEFAULT_PRIORITY - return start, nil, priority, element + return start, ending, priority, element else Ovale:Logf("Action %s not enabled", element.params[1]) end @@ -436,13 +367,9 @@ local function ComputeGroup(element, atTime) for k, v in ipairs(element.nodes) do local start, ending, priority, newElement = self:Compute(v, atTime) - - if start and start < atTime then - start = atTime - end - - if start and (not ending or start <= ending) then - -- The node has a valid time interval. + -- We only care about actions that are available at time t > atTime. + start, ending = Intersect(start, ending, atTime, math.huge) + if Measure(start, ending) > 0 then local castTime if newElement then castTime = newElement.castTime @@ -459,17 +386,17 @@ local function ComputeGroup(element, atTime) Ovale:Errorf("Internal error: bestPriority=nil and priority=%d", priority) return nil elseif priority and priority > bestPriority then - -- If the new spell has a higher priority than the previous one, then choose the + -- If the new spell has a higher priority than the best one found, then choose the -- higher priority spell if its cast is pushed back too far by the lower priority one. if newElement and newElement.params and newElement.params.wait then - if start and start - bestStart < newElement.params.wait then + if start - bestStart < newElement.params.wait then replace = true end elseif start - bestStart < bestCastTime * 0.75 then replace = true end elseif priority and priority < bestPriority then - -- If the new spell has a lower priority than the previous one, then choose the + -- If the new spell has a lower priority than the best one found, then choose the -- lower priority spell only if it doesn't push back the cast of the higher priority -- one by too much. if bestElement and bestElement.params and bestElement.params.wait then @@ -481,12 +408,11 @@ local function ComputeGroup(element, atTime) end else -- If the spells have the same priority, then pick the one with an earlier cast time. - -- TODO: why have a 0.01 second threshold here? if bestElement and bestElement.params and bestElement.params.wait then if bestStart - start > bestElement.params.wait then replace = true end - elseif bestStart - start > 0.01 then + elseif bestStart > start then replace = true end end @@ -504,7 +430,7 @@ local function ComputeGroup(element, atTime) end if not bestStart then - Ovale:Log("group return nil") + Ovale:Logf("group return nil [%d]", element.nodeId) return nil end @@ -513,107 +439,83 @@ local function ComputeGroup(element, atTime) if bestElement.params then id = bestElement.params[1] end - Ovale:Logf("group best action %s remains %s, %s [%d]", id, bestStart, bestEnding, element.nodeId) + Ovale:Logf("group best action %s remains %f, %f [%d]", id, bestStart, bestEnding, element.nodeId) else - Ovale:Logf("group no best action returns %s, %s [%d]", bestStart, bestEnding, element.nodeId) + Ovale:Logf("group no best action returns %f, %f [%d]", bestStart, bestEnding, element.nodeId) end return bestStart, bestEnding, bestPriority, bestElement end -local function ComputeLua(element, atTime) - local ret = loadstring(element.lua)() - Ovale:Logf("lua %s", ret) - return 0, nil, OVALE_DEFAULT_PRIORITY, PutValue(element, ret, 0, 0) -end - -local function ComputeNot(element, atTime) +local function ComputeIf(element, atTime) + Ovale:Logf("%s [%d]", element.type, element.nodeId) local self = OvaleBestAction + local startA, endA = self:ComputeBool(element.a, atTime) - --[[ - NOT start < t < ending ==> 0 < t < start OR ending < t < infinity - NOT start < t < infinity ==> 0 < t < start - NOT nil ==> 0 < t < infinity - ]]-- - if startA and endA then - -- TODO: This is not quite right since we ignore 0 < t < startA. - return endA, nil - elseif startA then - return 0, startA + -- "unless A B" is equivalent to "if (not A) B", so take the complement of A. + if element.type == "unless" then + startA, endA = Complement(startA, endA, atTime) + end + -- Short-circuit evaluation of left argument to AND. + if Measure(startA, endA) == 0 then + Ovale:Logf("%s return timespan with measure 0 [%d]", element.type, element.nodeId) + return nil + end + + local startB, endB, priorityB, elementB = self:Compute(element.b, atTime) + -- If the "then" clause is a "wait" node, then only wait if the conditions are true. + if elementB and elementB.wait and not HasTime(startA, endA, atTime) then + elementB.wait = nil + end + -- Take intersection of A and B. + startB, endB = Intersect(startA, endA, startB, endB) + if Measure(startB, endB) == 0 then + Ovale:Logf("%s return nil [%d]", element.type, element.nodeId) else - return 0, nil + Ovale:Logf("%s return %f, %f [%d]", element.type, startB, endB, element.nodeId) end + return startB, endB, priorityB, elementB end -local function ComputeOr(element, atTime) - Ovale:Log(element.type) +local function ComputeLua(element, atTime) + local ret = loadstring(element.lua)() + Ovale:Logf("lua %s [%d]", ret, element.nodeId) + return 0, math.huge, OVALE_DEFAULT_PRIORITY, PutValue(element, ret, 0, 0) +end + +local function ComputeNot(element, atTime) + Ovale:Logf("%s [%d]", element.type, element.nodeId) local self = OvaleBestAction local startA, endA = self:ComputeBool(element.a, atTime) - local startB, endB = self:ComputeBool(element.b, atTime) - - if isBefore(endA, atTime) then - return startB, endB - elseif isBefore(endB, atTime) then - return startA, endA - end - if isBefore(endA, startB) then - return startA, endA - elseif isBefore(endB, startA) then - return startB, endB - end - if isBefore(startA, startB) then - startB = startA - end - if isAfter(endA, endB) then - endB = endA - end - return startB, endB + startA, endA = Complement(startA, endA, atTime) + Ovale:Logf("%s returns %s, %s [%d]", element.type, startA, endA, element.nodeId) + return startA, endA end -local function ComputeUnless(element, atTime) +local function ComputeOr(element, atTime) Ovale:Logf("%s [%d]", element.type, element.nodeId) local self = OvaleBestAction local startA, endA = self:ComputeBool(element.a, atTime) - local startB, endB, prioriteB, elementB = self:Compute(element.b, atTime) - -- If the "then" clause is a "wait" node, then only wait if the conditions are false. - if elementB and elementB.wait and isBetween(atTime, startA, endA) then - elementB.wait = nil - end - -- unless {t: startA < t < endA} then {t: startB < t < endB} - -- if not {t: startA < t < endA} then {t: startB < t < endB} - -- if {t: t < startA} or {t: t > endA} then {t: startB < t < endB} - -- {t: t < startA and startB < t < endB} or {t: startB < t < endB and endA < t} - if isBeforeEqual(startA, startB) and isAfterEqual(endA, endB) then - Ovale:Logf("%s return nil [%d]", element.type, element.nodeId) - return nil - end - if isAfterEqual(startA, startB) and isBefore(endA, endB) then - Ovale:Logf("%s return %s, %s [%d]", element.type, endA, endB, element.nodeId) - return endA, endB, prioriteB, elementB - end - if isAfter(startA, startB) and isBefore(startA, endB) then - endB = startA - end - if isAfter(endA, startB) and isBefore(endA, endB) then - startB = endA - end - Ovale:Logf("%s return %s, %s [%d]", element.type, startB, endB, element.nodeId) - return startB, endB, prioriteB, elementB + local startB, endB = self:ComputeBool(element.b, atTime) + -- Take union of (startA, endA) and (startB, endB) + startA, endA = Union(startA, endA, startB, endB) + Ovale:Logf("%s returns %s, %s [%d]", element.type, startA, endA, element.nodeId) + return startA, endA end local function ComputeValue(element, atTime) Ovale:Logf("value %s", element.value) - return 0, nil, OVALE_DEFAULT_PRIORITY, element + return 0, math.huge, OVALE_DEFAULT_PRIORITY, element end local function ComputeWait(element, atTime) Ovale:Logf("%s [%d]", element.type, element.nodeId) local self = OvaleBestAction - local startA, endA, prioriteA, elementA = self:Compute(element.a, atTime) + local startA, endA, priorityA, elementA = self:Compute(element.a, atTime) if elementA then elementA.wait = true - Ovale:Logf("%s return %s, %s [%d]", element.type, startA, endA, element.nodeId) + Ovale:Logf("%s return %f, %f [%d]", element.type, startA, endA, element.nodeId) end - return startA, endA, prioriteA, elementA + return startA, endA, priorityA, elementA end -- @@ -626,11 +528,11 @@ local OVALE_COMPUTE_VISITOR = ["customfunction"] = ComputeCustomFunction, ["function"] = ComputeFunction, ["group"] = ComputeGroup, - ["if"] = ComputeAnd, + ["if"] = ComputeIf, ["lua"] = ComputeLua, ["not"] = ComputeNot, ["or"] = ComputeOr, - ["unless"] = ComputeUnless, + ["unless"] = ComputeIf, ["value"] = ComputeValue, ["wait"] = ComputeWait, } @@ -649,16 +551,12 @@ function OvaleBestAction:GetActionInfo(element) end local spellId = element.params[1] + local target = element.params.target or OvaleCondition.defaultTarget local action local actionTexture, actionInRange, actionCooldownStart, actionCooldownDuration, actionUsable, actionShortcut, actionIsCurrent, actionEnable - local target = element.params.target - if (not target) then - target = OvaleCondition.defaultTarget - end - - if (element.func == "spell" ) then + if (element.func == "spell") then action = OvaleActionBar:GetForSpell(spellId) if not OvaleSpellBook:IsKnownSpell(spellId) and not action then Ovale:Logf("Spell %s not learnt", spellId) @@ -774,7 +672,7 @@ function OvaleBestAction:ComputeBool(element, atTime) if element and element.type == "value" and element.value == 0 and element.rate == 0 then return nil else - return start, ending, priority, element + return start, ending end end -- diff --git a/OvaleCondition.lua b/OvaleCondition.lua index e0535cd..471841c 100644 --- a/OvaleCondition.lua +++ b/OvaleCondition.lua @@ -138,47 +138,24 @@ local function TimeWithHaste(time1, haste) end end --- Return time1 + duration. -local function AddToTime(time1, duration) - if not time1 or not duration then - -- time1 or duration is infinite. - return nil - else - return time1 + duration - end -end - --- Return time2 - time1 -local function DiffTime(time1, time2) - if not time1 then - -- time1 is infinite, so return the lowest possible time (zero). - return 0 - elseif not time2 then - -- time2 is infinite. - return nil - else - return time2 - time1 - end -end - local function Compare(a, comparison, b) if not comparison then - return 0, nil, a, 0, 0 -- this is not a compare, returns the value a + return 0, math.huge, a, 0, 0 -- this is not a compare, returns the value a elseif comparison == "more" then - if (not b or (a~=nil and a>b)) then - return 0 + if not b or (a and a > b) then + return 0, math.huge else return nil end elseif comparison == "equal" then if b == a then - return 0 + return 0, math.huge else return nil end elseif comparison == "less" then - if (not a or (b~=nil and a limit then return 0 else return nil end - elseif comparator == "less" then - if value < limit then return 0 else return nil end - else - Ovale:Errorf("Unknown operator %s", comparator) - return nil - end + local start, ending = 0, math.huge + if comparator == "more" and rate == 0 then + if value <= limit then return nil end + elseif comparator == "less" and rate == 0 then + if value >= limit then return nil end elseif (comparator == "more" and rate > 0) or (comparator == "less" and rate < 0) then - return (limit - value) / rate + atTime + start = (limit - value)/rate + atTime elseif (comparator == "more" and rate < 0) or (comparator == "less" and rate > 0) then - return 0, (limit - value) / rate + atTime + ending = (limit - value)/rate + atTime else Ovale:Errorf("Unknown operator %s", comparator) return nil end + return start, ending end end @@ -471,18 +445,16 @@ OvaleCondition.defaultTarget = "target" or operations. The endpoint of a time interval must be between 0 and infinity, where - infinity is represented by "nil". Time is a value such as returned by + infinity is represented by math.huge. Time is a value such as returned by the API function GetTime(). Examples: - (1) (0, nil) means the condition is always true. This can be shortened - to just return 0. + (1) (0, math.huge) means the condition is always true. - (2) (nil, nil) means the condition is always false. This can be shortened - to just return nil. + (2) nil is the empty set and means the condition is always false. - (3) (0, nil, constant, 0, 0) means the condition has a constant value. + (3) (0, math.huge, constant, 0, 0) means the condition has a constant value. (4) (start, ending, ending - start, start, -1) means the condition has a value of f(t) = ending - t, at time t between start and ending. This @@ -569,7 +541,7 @@ OvaleCondition.conditions.buffattackpower = function(condition) if start and ending and start <= ending then return start, ending, attackPower, start, 0 else - return 0, nil, 0, 0, 0 + return 0, math.huge, 0, 0, 0 end end OvaleCondition.conditions.debuffattackpower = OvaleCondition.conditions.buffattackpower @@ -594,7 +566,7 @@ OvaleCondition.conditions.buffrangedattackpower = function(condition) if start and ending and start <= ending then return start, ending, rangedAttackPower, start, 0 else - return 0, nil, 0, 0, 0 + return 0, math.huge, 0, 0, 0 end end OvaleCondition.conditions.debuffrangedattackpower = OvaleCondition.conditions.buffrangedattackpower @@ -618,7 +590,7 @@ OvaleCondition.conditions.buffcombopoints = function(condition) if start and ending and start <= ending then return start, ending, comboPoints, start, 0 else - return 0, nil, 0, 0, 0 + return 0, math.huge, 0, 0, 0 end end OvaleCondition.conditions.debuffcombopoints = OvaleCondition.conditions.buffcombopoints @@ -644,7 +616,7 @@ OvaleCondition.conditions.buffdamagemultiplier = function(condition) if start and ending and start <= ending then return start, ending, baseDamageMultiplier * damageMultiplier, start, 0 else - return 0, nil, 0, 0, 0 + return 0, math.huge, 0, 0, 0 end end OvaleCondition.conditions.debuffdamagemultiplier = OvaleCondition.conditions.buffdamagemultiplier @@ -674,7 +646,7 @@ OvaleCondition.conditions.buffmeleecritchance = function(condition) if start and ending and start <= ending then return start, ending, critChance, start, 0 else - return 0, nil, 0, 0, 0 + return 0, math.huge, 0, 0, 0 end end OvaleCondition.conditions.debuffmeleecritchance = OvaleCondition.conditions.buffmeleecritchance @@ -705,7 +677,7 @@ OvaleCondition.conditions.buffrangedcritchance = function(condition) if start and ending and start <= ending then return start, ending, critChance, start, 0 else - return 0, nil, 0, 0, 0 + return 0, math.huge, 0, 0, 0 end end OvaleCondition.conditions.debuffrangedcritchance = OvaleCondition.conditions.buffrangedcritchance @@ -735,7 +707,7 @@ OvaleCondition.conditions.buffspellcritchance = function(condition) if start and ending and start <= ending then return start, ending, critChance, start, 0 else - return 0, nil, 0, 0, 0 + return 0, math.huge, 0, 0, 0 end end OvaleCondition.conditions.debuffspellcritchance = OvaleCondition.conditions.buffspellcritchance @@ -759,7 +731,7 @@ OvaleCondition.conditions.buffmastery = function(condition) if start and ending and start <= ending then return start, ending, masteryEffect, start, 0 else - return 0, nil, 0, 0, 0 + return 0, math.huge, 0, 0, 0 end end OvaleCondition.conditions.debuffmastery = OvaleCondition.conditions.buffmastery @@ -783,7 +755,7 @@ OvaleCondition.conditions.buffspellpower = function(condition) if start and ending and start <= ending then return start, ending, spellBonusDamage, start, 0 else - return 0, nil, 0, 0, 0 + return 0, math.huge, 0, 0, 0 end end OvaleCondition.conditions.debuffspellpower = OvaleCondition.conditions.buffspellpower @@ -807,7 +779,7 @@ OvaleCondition.conditions.buffspellhaste = function(condition) if start and ending and start <= ending then return start, ending, spellHaste, start, 0 else - return 0, nil, 0, 0, 0 + return 0, math.huge, 0, 0, 0 end end OvaleCondition.conditions.debuffspellhaste = OvaleCondition.conditions.buffspellhaste @@ -856,7 +828,8 @@ OvaleCondition.conditions.debuffcount = OvaleCondition.conditions.buffcount OvaleCondition.conditions.buffduration = function(condition) local start, ending = GetAura(condition) start = start or 0 - return Compare(DiffTime(start, ending), condition[2], condition[3]) + ending = ending or math.huge + return Compare(ending - start, condition[2], condition[3]) end OvaleCondition.conditions.debuffduration = OvaleCondition.conditions.buffduration @@ -887,10 +860,10 @@ OvaleCondition.conditions.buffexpires = function(condition) local start, ending = GetAura(condition) local timeBefore = TimeWithHaste(condition[2], condition.haste) if not start then - ending = 0 + return 0, math.huge end Ovale:Logf("timeBefore = %s, ending = %s", timeBefore, ending) - return AddToTime(ending, -timeBefore) + return ending - timeBefore, math.huge end OvaleCondition.conditions.debuffexpires = OvaleCondition.conditions.buffexpires @@ -915,7 +888,7 @@ OvaleCondition.conditions.buffremains = function(condition) if start and ending and start <= ending then return start, ending, ending - start, start, -1 else - return 0, nil, 0, 0, 0 + return 0, math.huge, 0, 0, 0 end end OvaleCondition.conditions.debuffremains = OvaleCondition.conditions.buffremains @@ -929,7 +902,7 @@ OvaleCondition.conditions.buffgain = function(condition) Ovale:Error("not implemented") if true then return nil end local gain = select(4, GetAura(condition)) or 0 - return 0, nil, 0, 0, 1 + return 0, math.huge, 0, 0, 1 end OvaleCondition.conditions.debuffgain = OvaleCondition.conditions.buffgain @@ -962,7 +935,7 @@ OvaleCondition.conditions.buffpresent = function(condition) return nil end local timeBefore = TimeWithHaste(condition[2], condition.haste) - return start, AddToTime(ending, -timeBefore) + return start, ending - timeBefore end OvaleCondition.conditions.debuffpresent = OvaleCondition.conditions.buffpresent @@ -987,6 +960,7 @@ OvaleCondition.conditions.debuffpresent = OvaleCondition.conditions.buffpresent OvaleCondition.conditions.buffstacks = function(condition) local start, ending, stacks = GetAura(condition) start = start or 0 + ending = ending or math.huge stacks = stacks or 0 return start, ending, stacks, 0, 0 end @@ -1023,22 +997,16 @@ OvaleCondition.conditions.burningembers = function(condition) return TestValue(condition[1], condition[2], OvaleState.state.burningembers, OvaleState.currentTime, OvaleState.powerRate.burningembers) end - -- Check if the player can cast (cooldown is down) - -- 1: spellId - -- returns: bool +--- Check if the player can cast the given spell (not on cooldown). +-- @name CanCast +-- @paramsig boolean +-- @param id The spell ID to check. +-- @return True if the spell cast be cast; otherwise, false. + OvaleCondition.conditions.cancast = function(condition) local spellId = condition[1] local actionCooldownStart, actionCooldownDuration = OvaleState:GetComputedSpellCD(spellId) - local startCast = actionCooldownStart + actionCooldownDuration - if startCast < OvaleState.currentTime then - startCast = OvaleState.currentTime - end - --TODO why + castTime? - local castTime - if spellId then - castTime = select(7, API_GetSpellInfo(spellId)) - end - return startCast + castTime/1000 + return actionCooldownStart + actionCooldownDuration, math.huge end --- Test if the target is casting the given spell. @@ -1171,7 +1139,7 @@ OvaleCondition.conditions.checkboxoff = function(condition) return nil end end - return 0 + return 0, math.huge end --- Test if all of the listed checkboxes are on. @@ -1191,7 +1159,7 @@ OvaleCondition.conditions.checkboxon = function(condition) return nil end end - return 0 + return 0, math.huge end --- Get the current amount of stored Chi for monks. @@ -1225,8 +1193,8 @@ end -- if target.Class(PRIEST) Spell(cheap_shot) OvaleCondition.conditions.class = function(condition) - local loc, noloc = API_UnitClass(GetTarget(condition)) - return TestBoolean(noloc == condition[1], condition[2]) + local class, classToken = API_UnitClass(GetTarget(condition)) + return TestBoolean(classToken == condition[1], condition[2]) end --- Test whether the target's classification matches the given classification. @@ -1247,17 +1215,17 @@ end OvaleCondition.conditions.classification = function(condition) local classification local target = GetTarget(condition) - if API_UnitLevel(target) == -1 then + if API_UnitLevel(target) < 0 then classification = "worldboss" else - classification = API_UnitClassification(target); - if (classification == "rareelite") then + classification = API_UnitClassification(target) + if classification == "rareelite" then classification = "elite" - elseif (classification == "rare") then + elseif classification == "rare" then classification = "normal" end end - return TestBoolean(condition[1]==classification, condition[2]) + return TestBoolean(classification == condition[1], condition[2]) end --- Get the number of combo points on the currently selected target for a feral druid or a rogue. @@ -1311,7 +1279,8 @@ end -- Spell(hibernate) OvaleCondition.conditions.creaturefamily = function(condition) - return TestBoolean(API_UnitCreatureFamily(GetTarget(condition)) == LBCT[condition[1]], condition[2]) + local family = API_UnitCreatureFamily(GetTarget(condition)) + return TestBoolean(family == LBCT[condition[1]], condition[2]) end --- Test if the target is any of the listed creature types. @@ -1330,9 +1299,9 @@ end OvaleCondition.conditions.creaturetype = function(condition) local creatureType = API_UnitCreatureType(GetTarget(condition)) - for _,v in pairs(condition) do - if (creatureType == LBCT[v]) then - return 0 + for _, v in pairs(condition) do + if creatureType == LBCT[v] then + return 0, math.huge end end return nil @@ -1352,7 +1321,7 @@ OvaleCondition.conditions.critdamage = function(condition) -- TODO: Need to account for increased crit effect from meta-gems. local critFactor = 2 local start, ending, value, origin, rate = OvaleCondition.conditions.damage(condition) - return start, ending, critFactor * value, critFactor * origin, critFactor * rate + return start, ending, critFactor * value, origin, critFactor * rate end --- Get the current estimated damage of a spell on the target. @@ -1377,7 +1346,7 @@ OvaleCondition.conditions.damage = function(condition) local spellId = condition[1] local value, origin, rate = ComputeFunctionParam(spellId, "damage") if value then - return 0, nil, value, origin, rate + return 0, math.huge, value, origin, rate else local ap = OvalePaperDoll.stat.attackPower local sp = OvalePaperDoll.stat.spellBonusDamage @@ -1385,7 +1354,7 @@ OvaleCondition.conditions.damage = function(condition) local oh = OvalePaperDoll.stat.offHandWeaponDamage local bdm = OvalePaperDoll.stat.baseDamageMultiplier local dm = OvaleState:GetDamageMultiplier(spellId) - return 0, nil, OvaleData:GetDamage(spellId, ap, sp, mh, oh, combo) * bdm * dm, 0, 0 + return 0, math.huge, OvaleData:GetDamage(spellId, ap, sp, mh, oh, combo) * bdm * dm, 0, 0 end end @@ -1404,7 +1373,7 @@ OvaleCondition.conditions.damagemultiplier = function(condition) local spellId = condition[1] local bdm = OvalePaperDoll.stat.baseDamageMultiplier local dm = OvaleState:GetDamageMultiplier(spellId) - return 0, nil, bdm * dm, 0, 0 + return 0, math.huge, bdm * dm, 0, 0 end --- Get the damage taken by the player in the previous time interval. @@ -1424,7 +1393,7 @@ OvaleCondition.conditions.damagetaken = function(condition) if interval > 0 then damage = OvaleDamageTaken:GetRecentDamage(interval) end - return 0, nil, damage, 0, 0 + return 0, math.huge, damage, 0, 0 end OvaleCondition.conditions.incomingdamage = OvaleCondition.conditions.damagetaken @@ -1867,7 +1836,7 @@ end OvaleCondition.conditions.itemcooldown = function(condition) local actionCooldownStart, actionCooldownDuration, actionEnable = API_GetItemCooldown(condition[1]) - return 0, nil, actionCooldownDuration, actionCooldownStart, -1 + return 0, math.huge, actionCooldownDuration, actionCooldownStart, -1 end --- Get the current number of the given item in the player's inventory. @@ -2085,7 +2054,7 @@ OvaleCondition.conditions.lastestimateddamage = function(condition) local combo = OvaleFuture:GetLastSpellInfo(guid, spellId, "comboPoints") or 1 local bdm = OvaleFuture:GetLastSpellInfo(guid, spellId, "baseDamageMultiplier") or 1 local dm = OvaleFuture:GetLastSpellInfo(guid, spellId, "damageMultiplier") or 1 - return 0, nil, OvaleData:GetDamage(spellId, ap, sp, mh, oh, combo) * bdm * dm, 0, 0 + return 0, math.huge, OvaleData:GetDamage(spellId, ap, sp, mh, oh, combo) * bdm * dm, 0, 0 end OvaleCondition.conditions.lastspellestimateddamage = OvaleCondition.conditions.lastestimateddamage @@ -2305,7 +2274,7 @@ OvaleCondition.conditions.lastspellrangedcritchance = OvaleCondition.conditions. -- @see NextSwing OvaleCondition.conditions.lastswing = function(condition) - return 0, nil, 0, OvaleSwing:GetLast(condition[1]), 1 + return 0, math.huge, 0, OvaleSwing:GetLast(condition[1]), 1 end --- Get the most recent estimate of roundtrip latency in milliseconds. @@ -2320,7 +2289,7 @@ end -- if Latency(more 1000) Spell(sinister_strike) OvaleCondition.conditions.latency = function(condition) - return 0, nil, OvaleLatency:GetLatency() * 1000, 0, 0 + return 0, math.huge, OvaleLatency:GetLatency() * 1000, 0, 0 end --- Get the level of the target. @@ -2358,9 +2327,9 @@ end -- if List(opt_curse coe) Spell(curse_of_the_elements) OvaleCondition.conditions.list = function(condition) - if (condition[1]) then - if (Ovale:GetListValue(condition[1]) == condition[2]) then - return 0 + if condition[1] then + if Ovale:GetListValue(condition[1]) == condition[2] then + return 0, math.huge end end return nil @@ -2692,7 +2661,7 @@ end -- @see LastSwing OvaleCondition.conditions.nextswing = function(condition) - return 0, nil, 0, OvaleSwing:GetNext(condition[1]), 0, -1 + return 0, math.huge, OvaleSwing:GetNext(condition[1]), 0, -1 end --- Get the number of seconds until the next tick of a periodic aura on the target. @@ -2716,7 +2685,7 @@ OvaleCondition.conditions.nexttick = function(condition) while ending - tick > OvaleState.currentTime do ending = ending - tick end - return 0, nil, 0, ending, -1 + return 0, math.huge, 0, ending, -1 end return nil end @@ -2740,10 +2709,10 @@ OvaleCondition.conditions.otherdebuffexpires = function(condition) local start, ending = GetAuraOnAnyTarget(condition, "target") local timeBefore = TimeWithHaste(condition[2], condition.haste) if not start then - ending = 0 + return nil end Ovale:Logf("timeBefore = %s, ending = %s", timeBefore, ending) - return AddToTime(ending, -timeBefore) + return ending - timeBefore, math.huge end OvaleCondition.conditions.otherbuffexpires = OvaleCondition.conditions.otherdebuffexpires @@ -2768,7 +2737,7 @@ OvaleCondition.conditions.otherdebuffpresent = function(condition) return nil end local timeBefore = TimeWithHaste(condition[2], condition.haste) - return start, AddToTime(ending, -timeBefore) + return start, ending - timeBefore end OvaleCondition.conditions.otherbuffpresent = OvaleCondition.conditions.otherdebuffpresent @@ -2790,7 +2759,7 @@ OvaleCondition.conditions.otherdebuffremains = function(condition) if start and ending and start <= ending then return start, ending, ending - start, start, -1 else - return 0, nil, 0, 0, 0 + return 0, math.huge, 0, 0, 0 end end OvaleCondition.conditions.otherbuffremains = OvaleCondition.conditions.otherdebuffremains @@ -2807,7 +2776,7 @@ OvaleCondition.conditions.otherbuffremains = OvaleCondition.conditions.otherdebu OvaleCondition.conditions.powercost = function(condition) local cost = select(4, API_GetSpellInfo(condition[1])) or 0 - return 0, nil, cost, 0, 0 + return 0, math.huge, cost, 0, 0 end OvaleCondition.conditions.energycost = OvaleCondition.conditions.powercost OvaleCondition.conditions.focuscost = OvaleCondition.conditions.powercost @@ -2966,7 +2935,7 @@ OvaleCondition.conditions.remainingcasttime = function(condition) if not endTime then return nil end - return 0, nil, 0, endTime/1000, -1 + return 0, math.huge, 0, endTime/1000, -1 end --- Test if the current rune count meets the minimum rune requirements set out in the parameters. @@ -3003,7 +2972,7 @@ end -- Spell(obliterate) OvaleCondition.conditions.runecount = function(condition) - return 0, nil, GetRuneCount(condition[1], condition.death) + return 0, math.huge, GetRuneCount(condition[1], condition.death) end --- Get the number of seconds before the rune conditions are met. @@ -3031,7 +3000,7 @@ OvaleCondition.conditions.runescooldown = function(condition) if ret < OvaleState.maintenant then ret = OvaleState.maintenant end - return 0, nil, 0, ret, -1 + return 0, math.huge, 0, ret, -1 end --- Get the current amount of runic power for death knights. @@ -3194,9 +3163,9 @@ OvaleCondition.spellbookConditions.spellcharges = true OvaleCondition.conditions.spellchargecooldown = function(condition) local charges, maxCharges, cooldownStart, cooldownDuration = API_GetSpellCharges(condition[1]) if charges < maxCharges then - return 0, nil, cooldownDuration, cooldownStart, -1 + return 0, math.huge, cooldownDuration, cooldownStart, -1 else - return 0, nil, 0, 0, 0 + return 0, math.huge, 0, 0, 0 end end OvaleCondition.spellbookConditions.spellchargecooldown = true @@ -3215,15 +3184,15 @@ OvaleCondition.conditions.spellcooldown = function(condition) if type(spellId) == "string" then local sharedCd = OvaleState.state.cd[spellId] if sharedCd then - return 0, nil, sharedCd.duration, sharedCd.start, -1 + return 0, math.huge, sharedCd.duration, sharedCd.start, -1 else return nil end elseif not OvaleSpellBook:IsKnownSpell(spellId) then - return 0, nil, 0, OvaleState.currentTime + 3600, -1 + return 0, math.huge, 0, OvaleState.currentTime + 3600, -1 else local actionCooldownStart, actionCooldownDuration, actionEnable = OvaleState:GetComputedSpellCD(spellId) - return 0, nil, actionCooldownDuration, actionCooldownStart, -1 + return 0, math.huge, actionCooldownDuration, actionCooldownStart, -1 end end -- OvaleCondition.spellbookConditions.spellcooldown = true / may be a sharedcd @@ -3244,7 +3213,7 @@ OvaleCondition.conditions.spelldata = function(condition) if si then local ret = si[condition[2]] if ret then - return 0, nil, ret, 0, 0 + return 0, math.huge, ret, 0, 0 end end return nil @@ -3293,7 +3262,7 @@ OvaleCondition.conditions.staggerremains = function(condition) local stagger = API_UnitStagger(target) return start, ending, 0, ending, -1 * stagger / (ending - start) else - return 0, nil, 0, 0, 0 + return 0, math.huge, 0, 0, 0 end end @@ -3307,7 +3276,7 @@ end OvaleCondition.conditions.stance = function(condition) if OvaleStance:IsStance(condition[1]) then - return 0 + return 0, math.huge else return nil end @@ -3448,7 +3417,7 @@ end -- @return The number of added ticks. OvaleCondition.conditions.ticksadded = function(condition) - return 0, nil, 0, 0, 0 + return 0, math.huge, 0, 0, 0 end --- Get the remaining number of ticks of a periodic aura on a target. @@ -3472,9 +3441,9 @@ OvaleCondition.conditions.ticksremain = function(condition) local start, ending = GetAura(condition, self_auraFound) local tick = self_auraFound.tick if ending and tick and tick > 0 then - return 0, nil, 1, ending, -1/tick + return 0, math.huge, 1, ending, -1/tick end - return 0, nil, 0, 0, 0 + return 0, math.huge, 0, 0, 0 end --- Get the number of seconds between ticks of a periodic aura on a target. @@ -3534,7 +3503,7 @@ end OvaleCondition.conditions.timetodie = function(condition) local timeToDie = TimeToDie(GetTarget(condition)) - return 0, nil, timeToDie, OvaleState.maintenant, -1 + return 0, math.huge, timeToDie, OvaleState.maintenant, -1 end OvaleCondition.conditions.deadin = OvaleCondition.conditions.timetodie @@ -3556,9 +3525,9 @@ OvaleCondition.conditions.timetohealthpercent = function(condition) local healthPercent = health / maxHealth * 100 if healthPercent >= percent then local t = timeToDie * (healthPercent - percent) / healthPercent - return 0, nil, t, OvaleState.maintenant, -1 + return 0, math.huge, t, OvaleState.maintenant, -1 end - return 0, nil, 0, 0, 0 + return 0, math.huge, 0, 0, 0 end OvaleCondition.conditions.timetolifepercent = OvaleCondition.conditions.timetohealthpercent @@ -3578,12 +3547,12 @@ OvaleCondition.conditions.timetopowerfor = function(condition) if currentPower < cost then if powerRate > 0 then local t = OvaleState.currentTime + (cost - currentPower) / powerRate - return 0, nil, 0, t, -1 + return 0, math.huge, 0, t, -1 else - return 0, nil, OvaleState.currentTime + 3600, 0, 0 + return 0, math.huge, OvaleState.currentTime + 3600, 0, 0 end else - return 0, nil, 0, 0, 0 + return 0, math.huge, 0, 0, 0 end end OvaleCondition.conditions.timetoenergyfor = OvaleCondition.conditions.timetopowerfor @@ -3603,7 +3572,7 @@ OvaleCondition.spellbookConditions.timetopowerfor = true OvaleCondition.conditions.timetomaxenergy = function(condition) local maxEnergy = OvalePower.maxPower.energy or 0 local t = OvaleState.currentTime + (maxEnergy - OvaleState.state.energy) / OvaleState.powerRate.energy - return 0, nil, 0, t, -1 + return 0, math.huge, 0, t, -1 end --- Get the time scaled by the specified haste type, defaulting to spell haste. @@ -3621,7 +3590,7 @@ end OvaleCondition.conditions.timewithhaste = function(condition) haste = condition.haste or "spell" - return 0, nil, TimeWithHaste(condition[1], haste), 0, 0 + return 0, math.huge, TimeWithHaste(condition[1], haste), 0, 0 end --- Test if the totem for shamans, the ghoul for death knights, or the statue for monks has expired. @@ -3640,18 +3609,19 @@ end -- if TotemPresent(water totem=healing_stream_totem) and TotemExpires(water 3) Spell(totemic_recall) OvaleCondition.conditions.totemexpires = function(condition) - if type(condition[1]) ~= "number" then - condition[1] = OVALE_TOTEMTYPE[condition[1]] + local totemId = condition[1] + local seconds = condition[2] or 0 + if type(totemId) ~= "number" then + totemId = OVALE_TOTEMTYPE[totemId] end - - local haveTotem, totemName, startTime, duration = API_GetTotemInfo(condition[1]) + local haveTotem, totemName, startTime, duration = API_GetTotemInfo(totemId) if not startTime then - return 0 + return 0, math.huge end if condition.totem and OvaleSpellBook:GetSpellName(condition.totem) ~= totemName then - return 0 + return 0, math.huge end - return AddToTime(startTime + duration, -(condition[2] or 0)) + return startTime + duration - seconds, math.huge end --- Test if the totem for shamans, the ghoul for death knights, or the statue for monks is present. @@ -3668,11 +3638,11 @@ end -- if TotemPresent(water totem=healing_stream_totem) and TotemExpires(water 3) Spell(totemic_recall) OvaleCondition.conditions.totempresent = function(condition) - if type(condition[1]) ~= "number" then - condition[1] = OVALE_TOTEMTYPE[condition[1]] + local totemId = condition[1] + if type(totemId) ~= "number" then + totemId = OVALE_TOTEMTYPE[totemId] end - - local haveTotem, totemName, startTime, duration = API_GetTotemInfo(condition[1]) + local haveTotem, totemName, startTime, duration = API_GetTotemInfo(totemId) if not startTime then return nil end @@ -3705,7 +3675,7 @@ end -- @return A boolean value. OvaleCondition.conditions["true"] = function(condition) - return 0, nil + return TestBoolean(true) end --- Test if the weapon imbue on the given weapon has expired or will expire after a given number of seconds. @@ -3723,23 +3693,23 @@ OvaleCondition.conditions.weaponenchantexpires = function(condition) local hasMainHandEnchant, mainHandExpiration, mainHandCharges, hasOffHandEnchant, offHandExpiration, offHandCharges = API_GetWeaponEnchantInfo() if (condition[1] == "mainhand") then if (not hasMainHandEnchant) then - return 0 + return 0, math.huge end mainHandExpiration = mainHandExpiration/1000 if ((condition[2] or 0) >= mainHandExpiration) then - return 0 + return 0, math.huge else - return OvaleState.maintenant + mainHandExpiration - (condition[2] or 60) + return OvaleState.maintenant + mainHandExpiration - (condition[2] or 60), math.huge end else if (not hasOffHandEnchant) then - return 0 + return 0, math.huge end offHandExpiration = offHandExpiration/1000 if ((condition[2] or 0) >= offHandExpiration) then - return 0 + return 0, math.huge else - return OvaleState.maintenant + offHandExpiration - (condition[2] or 60) + return OvaleState.maintenant + offHandExpiration - (condition[2] or 60), math.huge end end end @@ -3764,6 +3734,6 @@ OvaleCondition.conditions.weapondamage = function(condition) else -- if hand == "mainhand" or hand == "main" then damage = OvalePaperDoll.stat.mainHandWeaponDamage end - return 0, nil, damage, 0, 0 + return 0, math.huge, damage, 0, 0 end -- diff --git a/OvaleTimeSpan.lua b/OvaleTimeSpan.lua new file mode 100644 index 0000000..acb1e19 --- /dev/null +++ b/OvaleTimeSpan.lua @@ -0,0 +1,96 @@ +--[[-------------------------------------------------------------------- + Ovale Spell Priority + Copyright (C) 2013 Johnny C. Lam + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License in the LICENSE + file accompanying this program. +--]]-------------------------------------------------------------------- + +--[[ + Time spans are continuous open intervals (start, ending) that are subsets of (0, infinity). + + Infinity is represented by math.huge. + Point sets are considered empty. + "nil" time spans are considered empty. +--]] + +local _, Ovale = ... +local OvaleTimeSpan = {} +Ovale.OvaleTimeSpan = OvaleTimeSpan + +-- +function OvaleTimeSpan.Complement(startA, endA, atTime) + -- The complement of an interval is actually the union of two intervals. + -- If the point of interest (atTime) lies in the left interval, then return it. + -- Otherwise, return the right interval. + if not startA or not endA then + return 0, math.huge + elseif 0 < startA and atTime <= startA then + return 0, startA + else + return endA, math.huge + end +end + +function OvaleTimeSpan.HasTime(start, ending, atTime) + if not start or not ending then + return nil + else + return start <= atTime and atTime <= ending + end +end + +function OvaleTimeSpan.Intersect(startA, endA, startB, endB) + -- If either (startA, endA) or (startB, endB) are the empty set, then return the empty set. + if not startA or not endA or not startB or not endB then + return nil + end + -- If the two time spans don't overlap, then return the empty set. + if endB <= startA or endA <= startB then + return nil + end + -- Take the rightmost left endpoint. + if startA < startB then + startA = startB + end + -- Take the leftmost right endpoint. + if endA > endB then + endA = endB + end + -- Sanity check that it's a valid time span, otherwise, return the empty set. + if startA >= endA then + return nil + end + return startA, endA +end + +function OvaleTimeSpan.Measure(startA, endA) + if not startA or not endA then + return 0 + elseif startA >= endA then + return 0 + else + return endA - startA + end +end + +function OvaleTimeSpan.Union(startA, endA, startB, endB) + -- TODO: this assumes that (startA, endA) and (startB, endB) overlap. + -- If either (startA, endA) or (startB, endB) are the empty set, then return the other time span. + if not startA or not endA then + return startB, endB + elseif not startB or not endB then + return startA, endA + end + -- Take the leftmost left endpoint. + if startA > startB then + startA = startB + end + -- Take the rightmost right endpoint. + if endA < endB then + endA = endB + end + return startA, endA +end +-- diff --git a/compiler.pl b/compiler.pl index f843410..23315b3 100644 --- a/compiler.pl +++ b/compiler.pl @@ -98,6 +98,7 @@ $sp{Ovale}{OvalePool} = true; $sp{Ovale}{OvalePoolGC} = true; $sp{Ovale}{OvaleSkada} = true; $sp{Ovale}{OvaleState} = true; +$sp{Ovale}{OvaleTimeSpan} = true; $sp{OvaleQueue}{Front} = true; $sp{OvaleQueue}{FrontToBackIterator} = true; @@ -106,6 +107,12 @@ $sp{OvaleQueue}{InsertFront} = true; $sp{OvaleQueue}{NewDeque} = true; $sp{OvaleQueue}{RemoveFront} = true; +$sp{OvaleTimeSpan}{Complement} = true; +$sp{OvaleTimeSpan}{HasTime} = true; +$sp{OvaleTimeSpan}{Intersect} = true; +$sp{OvaleTimeSpan}{Measure} = true; +$sp{OvaleTimeSpan}{Union} = true; + opendir(DIR, "."); while (defined($r = readdir(DIR))) { -- 1.7.9.5