---
--- Generated manually.
--- Created by liaogaocan.
--- DateTime: 2020-6-10 16:50:13
---


---@class EventDispatcher
EventDispatcher = EventDispatcher or class("EventDispatcher", nil);

function EventDispatcher:ctor(...)
    self.m_handlersDic = {};
    self.m_funcDataDecoder = nil;
end

function EventDispatcher:dtor()
    self.m_handlersDic = nil;
    self.m_funcDataDecoder = nil;
end

---@param evtType any
---@return table handlers
---@return number numHandlers
function EventDispatcher:getHandlersByEventType(evtType)
    if evtType == nil then
        return nil, 0;
    end

    local handlers = self.m_handlersDic[evtType];
    if handlers == nil then
        return nil, 0;
    end

    return handlers, #handlers;
end

---@param evtType any
---@param func function
---@param thisObj any
---@param where any
---@return boolean
function EventDispatcher:AddEventListener(evtType, func, thisObj, where)
    if evtType == nil or type(func) ~= "function" then
        return false;
    end

    local handlers = self.m_handlersDic[evtType] or {};
    
    if where == nil then
        local info = debug.getinfo(2);
        where = string.format("%s:%d", info.source, info.currentline);
    end

    local handler = {
        obj = thisObj,
        fn = func,
        from = where
    };
    table.insert(handlers, handler);
    self.m_handlersDic[evtType] = handlers;

    return true;
end

---@param evtType any
---@param func function
---@param thisObj any
---@return boolean
function EventDispatcher:RemoveEventListener(evtType, func, thisObj)
    local handlers, numHandler = self:getHandlersByEventType(evtType);
    if handlers == nil or numHandler == 0 then
        return false;
    end
    
    for i = numHandler, 1 do
        local handler = handlers[i];
        if handler.obj == thisObj and handler.fn == func then
            table.remove(handlers, i);
            break;
        end
    end

    return true;
end

---@param evtType any
---@param data any
---@return boolean
function EventDispatcher:DispatchEvent(evtType, data)
    local handlers, numHandler = self:getHandlersByEventType(evtType);
    if handlers == nil or numHandler == 0 then
        return false;
    end

    local dataDecoded = data;
    if self.m_funcDataDecoder then
        dataDecoded = self.m_funcDataDecoder(data);
    end

    for i = 1, numHandler do
        local handler = handlers[i];
        if handler.obj ~= nil then
            handler.fn(handler.obj, dataDecoded);
        else
            handler.fn(dataDecoded);
        end
    end

    return true;
end

---@param func function
function EventDispatcher:SetDataDecoder(func)
    if type(func) ~= "function" then
        return;
    end
    self.m_funcDataDecoder = func;
end

---@return function
function EventDispatcher:GetDataDecoder()
    return self.m_funcDataDecoder;
end











---@class EventDispatcherManager
local EventDispatcherManager = EventDispatcherManager or class("EventDispatcherManager", nil);

function EventDispatcherManager:ctor()
    self.m_dispatchers = {};
end

function EventDispatcherManager:dtor()
    self.m_dispatchers = nil;
end

---@param moduleName string
---@param dispatcher EventDispatcher
---@return boolean
function EventDispatcherManager:RegisterDispatcher(moduleName, dispatcher)
    if moduleName == nil or dispatcher == nil or type(dispatcher.DispatchEvent) ~= "function" then
        return false;
    end

    self.m_dispatchers[moduleName] = dispatcher;
    return true;
end

---@param moduleName string
---@return boolean
function EventDispatcherManager:UnregisterDispatcher(moduleName)
    if moduleName == nil then
        return false;
    end

    self.m_dispatchers[moduleName] = nil;
    return true;
end

---@param evtType any
---@param func function
---@param thisObj any
---@param where any
---@return boolean
function EventDispatcherManager:AddEventListener(moduleName, evtType, func, thisObj, where)
    if moduleName == nil or evtType == nil then
        return false;
    end

    ---@type EventDispatcher
    local dispatcher = self.m_dispatchers[moduleName];
    if dispatcher == nil then
        dispatcher = EventDispatcher:new();
        self.m_dispatchers[moduleName] = dispatcher;
    end

    if where == nil then
        local info = debug.getinfo(2);
        where = string.format("%s:%d", info.source, info.currentline);
    end

    return dispatcher:AddEventListener(evtType, func, thisObj, where);
end

---@param evtType any
---@param func function
---@param thisObj any
---@return boolean
function EventDispatcherManager:RemoveEventListener(moduleName, evtType, func, thisObj)
    if moduleName == nil or evtType == nil then
        return false;
    end

    ---@type EventDispatcher
    local dispatcher = self.m_dispatchers[moduleName];
    if dispatcher == nil then
        return false;
    end

    return dispatcher:RemoveEventListener(evtType, func, thisObj);
end

---@param moduleName string
---@param evtType any
---@param data any
---@return boolean
function EventDispatcherManager:DispatchEvent(moduleName, evtType, data)
    if moduleName == nil or evtType == nil then
        return false;
    end

    ---@type EventDispatcher
    local dispatcher = self.m_dispatchers[moduleName];
    if dispatcher == nil then
        return false;
    end

    return dispatcher:DispatchEvent(evtType, data);
end

_G.EventDispatcher = EventDispatcher;
---@type EventDispatcherManager
_G.g_EventDispatcherManager = EventDispatcherManager:new();

