forked from chteufleur/go-xmpp
Keep filters in ordered list, with most recent at head.
This commit is contained in:
parent
c31efeffe5
commit
32bf10887c
|
|
@ -21,7 +21,7 @@ type XMPP struct {
|
||||||
// Incoming stanza filters.
|
// Incoming stanza filters.
|
||||||
filterLock sync.Mutex
|
filterLock sync.Mutex
|
||||||
nextFilterId FilterId
|
nextFilterId FilterId
|
||||||
filters map[FilterId]filter
|
filters []filter
|
||||||
}
|
}
|
||||||
|
|
||||||
func newXMPP(jid JID, stream *Stream) *XMPP {
|
func newXMPP(jid JID, stream *Stream) *XMPP {
|
||||||
|
|
@ -30,7 +30,6 @@ func newXMPP(jid JID, stream *Stream) *XMPP {
|
||||||
stream: stream,
|
stream: stream,
|
||||||
in: make(chan interface{}),
|
in: make(chan interface{}),
|
||||||
out: make(chan interface{}),
|
out: make(chan interface{}),
|
||||||
filters: make(map[FilterId]filter),
|
|
||||||
}
|
}
|
||||||
go x.sender()
|
go x.sender()
|
||||||
go x.receiver()
|
go x.receiver()
|
||||||
|
|
@ -76,34 +75,48 @@ func (x *XMPP) AddFilter(fn FilterFn) (FilterId, chan interface{}) {
|
||||||
|
|
||||||
// Protect against concurrent access.
|
// Protect against concurrent access.
|
||||||
x.filterLock.Lock()
|
x.filterLock.Lock()
|
||||||
defer x.filterLock.Lock()
|
defer x.filterLock.Unlock()
|
||||||
|
|
||||||
// Create filter chan and add to map.
|
// Allocate chan and id.
|
||||||
filterId := x.nextFilterId
|
|
||||||
x.nextFilterId ++
|
|
||||||
ch := make(chan interface{})
|
ch := make(chan interface{})
|
||||||
x.filters[filterId] = filter{fn, ch}
|
id := x.nextFilterId
|
||||||
|
x.nextFilterId ++
|
||||||
|
|
||||||
return filterId, ch
|
// Insert at head of filters list.
|
||||||
|
filters := make([]filter, len(x.filters)+1)
|
||||||
|
filters[0] = filter{id, fn, ch}
|
||||||
|
copy(filters[1:], x.filters)
|
||||||
|
x.filters = filters
|
||||||
|
|
||||||
|
return id, ch
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *XMPP) RemoveFilter(id FilterId) error {
|
func (x *XMPP) RemoveFilter(id FilterId) error {
|
||||||
|
|
||||||
// Protect against concurrent access.
|
// Protect against concurrent access.
|
||||||
x.filterLock.Lock()
|
x.filterLock.Lock()
|
||||||
defer x.filterLock.Lock()
|
defer x.filterLock.Unlock()
|
||||||
|
|
||||||
// Find filter.
|
// Find filter.
|
||||||
filter, ok := x.filters[id]
|
for i, f := range x.filters {
|
||||||
if !ok {
|
if f.id != id {
|
||||||
return id
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close filter channel and remove from map.
|
// Close the channel.
|
||||||
close(filter.ch)
|
close(f.ch)
|
||||||
delete(x.filters, id)
|
|
||||||
|
// Remove from list.
|
||||||
|
filters := make([]filter, len(x.filters)-1)
|
||||||
|
copy(filters, x.filters[:i])
|
||||||
|
copy(filters[i:], x.filters[i+1:])
|
||||||
|
x.filters = filters
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter not found.
|
||||||
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
func IqResult(id string) FilterFn {
|
func IqResult(id string) FilterFn {
|
||||||
|
|
@ -122,6 +135,7 @@ func IqResult(id string) FilterFn {
|
||||||
type FilterFn func(v interface{}) bool
|
type FilterFn func(v interface{}) bool
|
||||||
|
|
||||||
type filter struct {
|
type filter struct {
|
||||||
|
id FilterId
|
||||||
fn FilterFn
|
fn FilterFn
|
||||||
ch chan interface{}
|
ch chan interface{}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue