github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/event/filter/filter.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 12:09:39</date>
    10  //</624342639763787776>
    11  
    12  
    13  //包筛选器实现事件筛选器。
    14  package filter
    15  
    16  import "reflect"
    17  
    18  type Filter interface {
    19  	Compare(Filter) bool
    20  	Trigger(data interface{})
    21  }
    22  
    23  type FilterEvent struct {
    24  	filter Filter
    25  	data   interface{}
    26  }
    27  
    28  type Filters struct {
    29  	id       int
    30  	watchers map[int]Filter
    31  	ch       chan FilterEvent
    32  
    33  	quit chan struct{}
    34  }
    35  
    36  func New() *Filters {
    37  	return &Filters{
    38  		ch:       make(chan FilterEvent),
    39  		watchers: make(map[int]Filter),
    40  		quit:     make(chan struct{}),
    41  	}
    42  }
    43  
    44  func (f *Filters) Start() {
    45  	go f.loop()
    46  }
    47  
    48  func (f *Filters) Stop() {
    49  	close(f.quit)
    50  }
    51  
    52  func (f *Filters) Notify(filter Filter, data interface{}) {
    53  	f.ch <- FilterEvent{filter, data}
    54  }
    55  
    56  func (f *Filters) Install(watcher Filter) int {
    57  	f.watchers[f.id] = watcher
    58  	f.id++
    59  
    60  	return f.id - 1
    61  }
    62  
    63  func (f *Filters) Uninstall(id int) {
    64  	delete(f.watchers, id)
    65  }
    66  
    67  func (f *Filters) loop() {
    68  out:
    69  	for {
    70  		select {
    71  		case <-f.quit:
    72  			break out
    73  		case event := <-f.ch:
    74  			for _, watcher := range f.watchers {
    75  				if reflect.TypeOf(watcher) == reflect.TypeOf(event.filter) {
    76  					if watcher.Compare(event.filter) {
    77  						watcher.Trigger(event.data)
    78  					}
    79  				}
    80  			}
    81  		}
    82  	}
    83  }
    84  
    85  func (f *Filters) Match(a, b Filter) bool {
    86  	return reflect.TypeOf(a) == reflect.TypeOf(b) && a.Compare(b)
    87  }
    88  
    89  func (f *Filters) Get(i int) Filter {
    90  	return f.watchers[i]
    91  }
    92