lotrointerface.com
Search Downloads

LoTROInterface SVN SequenceBars

[/] [trunk/] [Thurallor/] [SequenceBars/] [Sequence.lua] - Rev 181

Compare with Previous | Blame | View Log

Sequence = class();

function Sequence:Constructor(bar, info, wantsMouseWheelEvents)
    self.bar = bar;
    self.wantsMouseWheelEvents = wantsMouseWheelEvents;
    self.manager = bar.manager;
    self.visibleItems = {};

    -- Callbacks
    self.ItemChanged = nil;
    
    if (not info) then
        info = {};
    end
    self:SetInfo(info);
end

function Sequence:SetInfo(newInfo)
    self.slots = {};
    self.events = {};
    self.slotIndexMap = {};
    self.includes = {};

    for i = 1, #newInfo, 1 do
        self.i = i;
        local info = newInfo[i];
        self:ProcessInfoItem(info);
    end
    
    self:ProcessConditionals();
end

function Sequence:ProcessInfoItem(info, includingBarID)
    local slot = Slot(info, self.wantsMouseWheelEvents);
    slot.i = self.i;
    slot.info = info;
    local barID = self.bar:GetID();
    if ((type(info) ~= "table") or not info.class) then
        -- Empty slot; discard
    elseif ((info.class == "Turbine.UI.Control") and (info.type == "Include")) then
        if (info.include ~= barID) then
            if (not self:IncludeSequence(info.include)) then
                info.include = nil;
                self.bar:SaveSettings(false);
            end
        end
    else
        table.insert(self.slots, slot);
        self.slotIndexMap[self.i] = #self.slots;
        if (info.class ~= "Turbine.UI.Control") then
            -- Standard quickslot; no further handling necessary
        else
            if (info.type == "GenerateEvent") then
                local eventInfo = self.events[info.eventName] or {};
                self.events[info.eventName] = eventInfo;
                eventInfo[includingBarID or barID] = true;
            end
            if (info.action) then
                slot.actionFunc = loadstring("setfenv(1, _G);" .. info.action);
            end
        end
    end
end

function Sequence:IncludeSequence(barID)
    local otherSettings = self.manager.settings.bars[barID];
    if (otherSettings and not otherSettings.deleted) then
        table.insert(self.includes, barID);
        local otherInfo = otherSettings.sequenceItemInfo;
        for i = 1, #otherInfo, 1 do
            local info = otherInfo[i];
            self:ProcessInfoItem(info, barID);
        end
        return true;
    else
        return false;
    end
end

function Sequence:GetIncludes()
    return self.includes;
end

-- Returns the new index of a slot after empty slots are removed
function Sequence:GetNewIndex(oldIndex)
    return self.slotIndexMap[oldIndex];
end

function Sequence:GetOldIndex(newIndex)
    return self.slots[newIndex].i;
end

function Sequence:GetSlots()
    return self.slots;
end

function Sequence:GetSlot(index)
    return self.slots[index];
end

function Sequence:GetEvents()
    return self.events;
end

-- Populate the 'ifSlot', 'elseSlot', and 'endIfSlot' members of slots.
function Sequence:ProcessConditionals()
    local stack = { {} };
    local parentIfSlot, parentElseSlot = nil, nil;
    for s = 1, #self.slots, 1 do
        local slot = self.slots[s];
        local info = slot.info;
        slot.parentIfSlot, slot.parentElseSlot = parentIfSlot, parentElseSlot;
        if (info.type == "If") then
            slot.ifSlot, slot.elseSlot, slot.endIfSlot = nil, nil, nil;
            -- Do argument substitutions
            slot.condExpr = info.condExpr;
            if (info.condArgs) then
                for name, value in pairs(info.condArgs) do
                    slot.condExpr = string.gsub(slot.condExpr, "<" .. name .. ">", tostring(value));
                end
            end
            slot.condFunc = loadstring("setfenv(1, _G);" .. slot.condExpr);
            table.insert(stack, { info.type, s });
            parentIfSlot = s;
            parentElseSlot = nil;
        elseif (info.type == "Else") then
            local lastType, lastLoc = unpack(table.remove(stack));
            if (lastType == "If") then
                local ifItem = self.slots[lastLoc];
                ifItem.elseSlot = s;
                slot.ifSlot, slot.elseSlot, slot.endIfSlot = lastLoc, nil, nil;
                table.insert(stack, { info.type, s });
                slot.parentIfSlot, slot.parentElseSlot = ifItem.parentIfSlot, ifItem.parentElseSlot;
                parentIfSlot = nil;
                parentElseSlot = s;
            else -- Syntax error: Unmatched braces
                Puts("Error: \"Else\" at slot " .. tostring(slot.i) .. " has no matching \"If\".");
                table.insert(stack, { lastType, lastLoc });
            end
        elseif (info.type == "EndIf") then
            local lastType, lastLoc = unpack(table.remove(stack));
            if (lastType == "If") then
                local ifItem = self.slots[lastLoc];
                ifItem.endIfSlot = s;
                slot.ifSlot, slot.elseSlot, slot.endIfSlot = lastLoc, nil, nil;
                slot.parentIfSlot, slot.parentElseSlot = ifItem.parentIfSlot, ifItem.parentElseSlot;
                parentIfSlot, parentElseSlot = ifItem.parentIfSlot, ifItem.parentElseSlot;
            elseif (lastType == "Else") then
                local elseItem = self.slots[lastLoc];
                local ifItem = self.slots[elseItem.ifSlot];
                ifItem.endIfSlot = s;
                elseItem.endIfSlot = s;
                slot.ifSlot, slot.elseSlot, slot.endIfSlot = elseItem.ifSlot, lastLoc, nil;
                slot.parentIfSlot, slot.parentElseSlot = ifItem.parentIfSlot, ifItem.parentElseSlot;
                parentIfSlot, parentElseSlot = ifItem.parentIfSlot, ifItem.parentElseSlot;
            else -- Syntax error: Unmatched braces
                Puts("Error: \"EndIf\" at slot " .. tostring(slot.i) .. " has no matching \"If\".");
                table.insert(stack, { lastType, lastLoc });
            end
        end
    end
    while (#stack > 1) do
        local t, s = unpack(table.remove(stack));
        local slot = self.slots[s];
        Puts("Error: \"" .. t .. "\" at slot " .. tostring(slot.i) .. " has no matching \"EndIf\".");
    end
--for s = 1, #self.slots, 1 do
--    local slot = self.slots[s];
--    Puts(tostring(s) .. ". parentIfSlot/parentElseSlot/ifSlot/elseSlot/endIfSlot = " .. tostring(slot.parentIfSlot) .. "/" .. tostring(slot.parentElseSlot) .. "/" .. tostring(slot.ifSlot) .. "/" .. tostring(slot.elseSlot) .. "/" .. tostring(slot.endIfSlot) .. "; condExpr = " .. tostring(slot.info.condExpr) .. "; condFunc = " .. tostring(slot.condFunc));
--end
end

function Sequence:UnfoldAllSlots()
    for s = 1, #self.slots, 1 do
        self.slots[s].condResult = nil;
        self.slots[s].foldTime = nil;
    end
end

-- There is currently no reason to evaluate folding more than once at any given game time;
-- hence the gameTime argument equals the current game time, a cached folding value is returned.
function Sequence:SlotIsFolded(s, gameTime)
    local slot = self.slots[s];
    if (slot.foldTime == gameTime) then
        return slot.isFolded;
    end
    if (slot.parentIfSlot) then
        local ifSlot = self.slots[slot.parentIfSlot];
        slot.isFolded = self:SlotIsFolded(slot.parentIfSlot, gameTime) or (not ifSlot.condResult);
    elseif (slot.parentElseSlot) then
        local elseSlot = self.slots[slot.parentElseSlot];
        local ifSlot = self.slots[elseSlot.ifSlot];
        slot.isFolded = self:SlotIsFolded(slot.parentElseSlot, gameTime) or ifSlot.condResult;
    else
        slot.isFolded = false;
    end
    slot.foldTime = gameTime;
    return slot.isFolded;
end

Compare with Previous | Blame


All times are GMT -5. The time now is 04:14 PM.


Our Network
EQInterface | EQ2Interface | Minion | WoWInterface | ESOUI | LoTROInterface | MMOUI | Swtorui