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  }