github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/event/filter/filter.go (about) 1 // This file is part of the go-sberex library. The go-sberex library is 2 // free software: you can redistribute it and/or modify it under the terms 3 // of the GNU Lesser General Public License as published by the Free 4 // Software Foundation, either version 3 of the License, or (at your option) 5 // any later version. 6 // 7 // The go-sberex library is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 10 // General Public License <http://www.gnu.org/licenses/> for more details. 11 12 // Package filter implements event filters. 13 package filter 14 15 import "reflect" 16 17 type Filter interface { 18 Compare(Filter) bool 19 Trigger(data interface{}) 20 } 21 22 type FilterEvent struct { 23 filter Filter 24 data interface{} 25 } 26 27 type Filters struct { 28 id int 29 watchers map[int]Filter 30 ch chan FilterEvent 31 32 quit chan struct{} 33 } 34 35 func New() *Filters { 36 return &Filters{ 37 ch: make(chan FilterEvent), 38 watchers: make(map[int]Filter), 39 quit: make(chan struct{}), 40 } 41 } 42 43 func (self *Filters) Start() { 44 go self.loop() 45 } 46 47 func (self *Filters) Stop() { 48 close(self.quit) 49 } 50 51 func (self *Filters) Notify(filter Filter, data interface{}) { 52 self.ch <- FilterEvent{filter, data} 53 } 54 55 func (self *Filters) Install(watcher Filter) int { 56 self.watchers[self.id] = watcher 57 self.id++ 58 59 return self.id - 1 60 } 61 62 func (self *Filters) Uninstall(id int) { 63 delete(self.watchers, id) 64 } 65 66 func (self *Filters) loop() { 67 out: 68 for { 69 select { 70 case <-self.quit: 71 break out 72 case event := <-self.ch: 73 for _, watcher := range self.watchers { 74 if reflect.TypeOf(watcher) == reflect.TypeOf(event.filter) { 75 if watcher.Compare(event.filter) { 76 watcher.Trigger(event.data) 77 } 78 } 79 } 80 } 81 } 82 } 83 84 func (self *Filters) Match(a, b Filter) bool { 85 return reflect.TypeOf(a) == reflect.TypeOf(b) && a.Compare(b) 86 } 87 88 func (self *Filters) Get(i int) Filter { 89 return self.watchers[i] 90 }