ffi_events: simplify removeEventListener with keepItIf

Replace the manual index-scan + delete with sequtils.keepItIf and a
length-delta check. keepItIf does the find-and-remove in one pass, so
the inner loop and the sentinel idx variable go away; comparing the
seq length before/after is enough to know whether this event held the
listener. Same prune-empty-key behaviour, less bookkeeping.

Addresses PR #70 review comment r3343439866.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Ivan FB 2026-06-02 21:54:43 +02:00
parent 8a3a438837
commit b277ebde75
No known key found for this signature in database
GPG Key ID: DF0C67A04C543270

View File

@ -17,7 +17,7 @@
{.pragma: callback, cdecl, raises: [], gcsafe.}
import std/[locks, tables]
import std/[locks, sequtils, tables]
import chronicles
import ./ffi_types, ./cbor_serial
@ -112,23 +112,20 @@ proc removeEventListener*(reg: var FFIEventRegistry, id: uint64): bool {.raises:
var removed = false
withLock reg.lock:
var emptyKey = ""
var prune = false
var
pruneKey = ""
prune = false
for key, listeners in reg.byEvent.mpairs:
var idx = -1
for i in 0 ..< listeners.len:
if listeners[i].id == id:
idx = i
break
if idx >= 0:
listeners.delete(idx)
let before = listeners.len
listeners.keepItIf(it.id != id)
if listeners.len < before:
removed = true
if listeners.len == 0:
emptyKey = key
pruneKey = key
prune = true
break
if prune:
reg.byEvent.del(emptyKey)
reg.byEvent.del(pruneKey)
return removed
proc removeAllEventListeners*(reg: var FFIEventRegistry) {.raises: [].} =