github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/event/filter/filter.go (about) 1 // Package filter implements event filters. 2 package filter 3 4 import "reflect" 5 6 type Filter interface { 7 Compare(Filter) bool 8 Trigger(data interface{}) 9 } 10 11 type FilterEvent struct { 12 filter Filter 13 data interface{} 14 } 15 16 type Filters struct { 17 id int 18 watchers map[int]Filter 19 ch chan FilterEvent 20 21 quit chan struct{} 22 } 23 24 func New() *Filters { 25 return &Filters{ 26 ch: make(chan FilterEvent), 27 watchers: make(map[int]Filter), 28 quit: make(chan struct{}), 29 } 30 } 31 32 func (self *Filters) Start() { 33 go self.loop() 34 } 35 36 func (self *Filters) Stop() { 37 close(self.quit) 38 } 39 40 func (self *Filters) Notify(filter Filter, data interface{}) { 41 self.ch <- FilterEvent{filter, data} 42 } 43 44 func (self *Filters) Install(watcher Filter) int { 45 self.watchers[self.id] = watcher 46 self.id++ 47 48 return self.id - 1 49 } 50 51 func (self *Filters) Uninstall(id int) { 52 delete(self.watchers, id) 53 } 54 55 func (self *Filters) loop() { 56 out: 57 for { 58 select { 59 case <-self.quit: 60 break out 61 case event := <-self.ch: 62 for _, watcher := range self.watchers { 63 if reflect.TypeOf(watcher) == reflect.TypeOf(event.filter) { 64 if watcher.Compare(event.filter) { 65 watcher.Trigger(event.data) 66 } 67 } 68 } 69 } 70 } 71 } 72 73 func (self *Filters) Match(a, b Filter) bool { 74 return reflect.TypeOf(a) == reflect.TypeOf(b) && a.Compare(b) 75 } 76 77 func (self *Filters) Get(i int) Filter { 78 return self.watchers[i] 79 }