lua-events icon indicating copy to clipboard operation
lua-events copied to clipboard

removeListener() executes the listener

Open AntonC9018 opened this issue 5 years ago • 5 comments

Quick test

> print(Emitter)
table: 008CB508
> e = Emitter()
> e:emit('test')
> function u() print('Hello') end
> e:on('test', u)
> e:emit('test')
Hello
> e:removeListener('test', u)
Hello

I looked into your code and in the function rmEntry() pred gets executed

local function rmEntry(tbl, pred)
    local x, len = 0, #tbl
    for i = 1, len do
        local trusy, idx = false, (i - x)
        if (type(pred) == 'function') then trusy = pred(tbl[idx]) -- this line
        else trusy = tbl[idx] == pred
        end

        if (tbl[idx] ~= nil and trusy) then
            tbl[idx] = nil
            table.remove(tbl, idx)
            x = x + 1
        end
    end
    return tbl
end

removeListener() calls rmEntry() like this: rmEntry(evtbl, listener), which causes the listener to get executed with parameters tbl[idx]. Is this behavior intended?

AntonC9018 avatar Aug 17 '19 13:08 AntonC9018

rmEntry(evtbl, function(v) return v == listener end) this would probably be the solution

AntonC9018 avatar Aug 17 '19 13:08 AntonC9018

Having changed that, I've started having another issue. I've been trying to debug my code for like 3 hours and it's probably related to this. One of my listeners would never get called, nor does it appear when I call emitter:listeners(ev). But, for some reason, after I bind another instance of that listener (not actually the same object, just the same local function redefined inside a scope) it shows back up. I'm going to trace this problem myself and report here on any updates.

AntonC9018 avatar Aug 17 '19 18:08 AntonC9018

I probably know what had happened! I was removing a listener off an event while inside such a listener (i.e. called by emitter:emit()). I got it only upon creating my own little emitter library, which I'm going to use from now on. Your code probably just loops from start to finish and lets removeListener() do its thing, effectively letting it potentially intervene with the normal execution procedure of events. Inspect my code if you'd like to know how I fixed this issue. So the initial issue posted above is not the root of this second one, this is another bug.

AntonC9018 avatar Aug 17 '19 22:08 AntonC9018

Duplicate of # same bug @AntonC9018 absolutely right rmEntry should not call listener looks like rmEntry(evtbl, function(v) return v == listener end) been writen that rmEntry(evtbl, listener )

flameleo11 avatar Jul 16 '20 16:07 flameleo11

Duplicate of # same bug @AntonC9018 absolutely right rmEntry should not call listener looks like rmEntry(evtbl, function(v) return v == listener end) been writen that rmEntry(evtbl, listener )

I met the same bug. However, I think trusy = tbl[idx] == pred in rmEntry should be called when callingremoveListener()

zoujiahuan avatar Apr 09 '21 10:04 zoujiahuan