github.com/amazechain/amc@v0.1.3/modules/event/v2/event.go (about) 1 // Copyright 2022 The AmazeChain Authors 2 // This file is part of the AmazeChain library. 3 // 4 // The AmazeChain library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The AmazeChain library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the AmazeChain library. If not, see <http://www.gnu.org/licenses/>. 16 17 package v2 18 19 import ( 20 "github.com/amazechain/amc/log" 21 "reflect" 22 "sync" 23 ) 24 25 var GlobalEvent Event 26 27 type Event struct { 28 once sync.Once 29 30 feeds map[string]*Feed 31 feedsLock sync.RWMutex 32 feedsScope map[string]*SubscriptionScope 33 } 34 35 func (e *Event) init() { 36 e.feeds = make(map[string]*Feed) 37 e.feedsScope = make(map[string]*SubscriptionScope) 38 39 } 40 41 func (e *Event) initKey(key string) { 42 e.feedsLock.Lock() 43 defer e.feedsLock.Unlock() 44 if _, ok := e.feeds[key]; !ok { 45 e.feeds[key] = new(Feed) 46 e.feedsScope[key] = new(SubscriptionScope) 47 } 48 } 49 50 func (e *Event) Subscribe(channel interface{}) Subscription { 51 e.once.Do(e.init) 52 53 key := reflect.TypeOf(channel).Elem().String() 54 e.initKey(key) 55 56 e.feedsLock.RLock() 57 defer e.feedsLock.RUnlock() 58 sub := e.feedsScope[key].Track(e.feeds[key].Subscribe(channel)) 59 60 return sub 61 } 62 63 func (e *Event) Send(value interface{}) int { 64 65 e.once.Do(e.init) 66 67 key := reflect.TypeOf(value).String() 68 e.initKey(key) 69 70 nsent := 0 71 72 e.feedsLock.RLock() 73 defer e.feedsLock.RUnlock() 74 75 log.Trace("GlobalEvent Send", "key", key) 76 if e.feedsScope[key].Count() == 0 { 77 return nsent 78 } 79 nsent = e.feeds[key].Send(value) 80 81 return nsent 82 } 83 84 func (e *Event) Close() { 85 e.feedsLock.Lock() 86 defer e.feedsLock.Unlock() 87 88 for _, scope := range e.feedsScope { 89 scope.Close() 90 } 91 }