github.com/dfklegend/cell2/utils@v0.0.0-20240402033734-a0a9f3d9335d/event/light/lighteventcenter.go (about)

     1  package light
     2  
     3  import (
     4  	"log"
     5  
     6  	"github.com/dfklegend/cell2/utils/common"
     7  	"github.com/dfklegend/cell2/utils/logger"
     8  )
     9  
    10  /*
    11   * 非线程安全
    12   * Sub/Unsubscribe, 如果是对象,请传入对象实例
    13   * SubscribeWithReceiver
    14   * (TODO: 如果反射可以分析出func是对象的method,并获取receiver,可以简化接口)
    15   */
    16  
    17  type CBFunc func(args ...interface{})
    18  
    19  type EventCenter struct {
    20  	idService *common.SerialIdService64
    21  	events    map[string]*ListenerList
    22  
    23  	running bool
    24  }
    25  
    26  func NewEventCenter() *EventCenter {
    27  	return &EventCenter{
    28  		idService: common.NewSerialIdService64(),
    29  		events:    make(map[string]*ListenerList),
    30  		running:   true,
    31  	}
    32  }
    33  
    34  func (c *EventCenter) allocId() uint64 {
    35  	return c.idService.AllocId()
    36  }
    37  
    38  func (c *EventCenter) Clear() {
    39  	c.running = false
    40  	c.events = make(map[string]*ListenerList)
    41  }
    42  
    43  func (c *EventCenter) getListener(eventName string, createIfMiss bool) *ListenerList {
    44  	v, ok := c.events[eventName]
    45  	if !ok {
    46  		if !createIfMiss {
    47  			return nil
    48  		}
    49  		v = NewListenerList()
    50  
    51  		if c.running {
    52  			c.events[eventName] = v
    53  		}
    54  	}
    55  	return v
    56  }
    57  
    58  func (c *EventCenter) subscribeCheck(checkCB bool, eventName string, cb CBFunc, args ...interface{}) uint64 {
    59  	if !c.running {
    60  		return 0
    61  	}
    62  	list := c.getListener(eventName, true)
    63  
    64  	if checkCB {
    65  		id := list.FindId(cb)
    66  		if id != 0 {
    67  			// already subscribe
    68  			logger.L.Warnf("already register %v with this CB", eventName)
    69  			return 0
    70  		}
    71  	}
    72  
    73  	l := NewEventListener(c.allocId())
    74  	l.Args = args
    75  	l.CB = cb
    76  	list.Add(l)
    77  
    78  	return l.Id
    79  }
    80  
    81  func (c *EventCenter) SubscribeNoCheck(eventName string, cb CBFunc, args ...interface{}) uint64 {
    82  	return c.subscribeCheck(false, eventName, cb, args...)
    83  }
    84  
    85  func (c *EventCenter) Subscribe(eventName string, cb CBFunc, args ...interface{}) uint64 {
    86  	return c.subscribeCheck(true, eventName, cb, args...)
    87  }
    88  
    89  // SubscribeWithReceiver receiver必须是指针对象
    90  func (c *EventCenter) SubscribeWithReceiver(eventName string, receiver any, cb CBFunc, args ...interface{}) uint64 {
    91  	if !c.running {
    92  		return 0
    93  	}
    94  	list := c.getListener(eventName, true)
    95  
    96  	id := list.FindIdWithReceiver(receiver, cb)
    97  	if id != 0 {
    98  		// already subscribe
    99  		log.Printf("already register %v with this receiver and CB", eventName)
   100  		return 0
   101  	}
   102  
   103  	l := NewEventListener(c.allocId())
   104  	l.Args = args
   105  	l.CB = cb
   106  
   107  	l.Receiver = receiver
   108  	list.Add(l)
   109  
   110  	return l.Id
   111  }
   112  
   113  func (c *EventCenter) UnsubscribeById(eventName string, id uint64) {
   114  	list := c.getListener(eventName, false)
   115  	if list == nil {
   116  		return
   117  	}
   118  	list.Del(id)
   119  }
   120  
   121  func (c *EventCenter) Unsubscribe(eventName string, cb CBFunc) {
   122  	list := c.getListener(eventName, false)
   123  	if list == nil {
   124  		return
   125  	}
   126  	id := list.FindId(cb)
   127  	if id == 0 {
   128  		return
   129  	}
   130  	list.Del(id)
   131  }
   132  
   133  func (c *EventCenter) UnsubscribeWithReceiver(eventName string, receiver any, cb CBFunc) {
   134  	list := c.getListener(eventName, false)
   135  	if list == nil {
   136  		return
   137  	}
   138  	id := list.FindIdWithReceiver(receiver, cb)
   139  	if id == 0 {
   140  		return
   141  	}
   142  	list.Del(id)
   143  }
   144  
   145  func (c *EventCenter) Publish(eventName string, args ...interface{}) {
   146  	c.dispatch(eventName, args...)
   147  }
   148  
   149  func (c *EventCenter) dispatch(eventName string, args ...interface{}) {
   150  	ll := c.getListener(eventName, false)
   151  	if ll == nil {
   152  		return
   153  	}
   154  	listeners := ll.Listeners
   155  
   156  	for _, v := range listeners {
   157  		if len(v.Args) > 0 {
   158  			finalArgs := append(v.Args, args...)
   159  			v.CB(finalArgs...)
   160  		} else {
   161  			v.CB(args...)
   162  		}
   163  
   164  	}
   165  }
   166  
   167  // GetSubscribeNum 订阅事件的个数
   168  func (c *EventCenter) GetSubscribeNum(eventName string) int {
   169  	ll := c.getListener(eventName, false)
   170  	if ll == nil {
   171  		return 0
   172  	}
   173  	return ll.GetSize()
   174  }
   175  
   176  func (c *EventCenter) HasSubscribers(eventName string) bool {
   177  	return c.GetSubscribeNum(eventName) > 0
   178  }
   179  
   180  func (c *EventCenter) DumpInfo(eventName string) {
   181  	ll := c.getListener(eventName, false)
   182  	if ll == nil {
   183  		return
   184  	}
   185  
   186  	logger.L.Infof("%v size:%v", eventName, ll.GetSize())
   187  }