gitee.com/zhongguo168a/gocodes@v0.0.0-20230609140523-e1828349603f/myx/eventx/dispatcher.go (about)

     1  package eventx
     2  
     3  import (
     4  	"math"
     5  )
     6  
     7  func newDispatcher(event string) *Dispatcher {
     8  	dispatcher := &Dispatcher{}
     9  	dispatcher.eventName = event
    10  	dispatcher.listenerList = []*Event{}
    11  	dispatcher.bufList = []*Event{}
    12  	return dispatcher
    13  }
    14  
    15  type Dispatcher struct {
    16  	// 属主
    17  	eventName string
    18  	/// 事件的侦听列表
    19  	listenerList []*Event
    20  	/// 引入buf,避免创建太多的数组对象
    21  	bufList []*Event
    22  
    23  	lastEventOn *Event
    24  	//
    25  	idCount int
    26  }
    27  
    28  func (dispatcher *Dispatcher) Dispose() {
    29  	if dispatcher == nil {
    30  		return
    31  	}
    32  	dispatcher.OffAll()
    33  	dispatcher.lastEventOn = nil
    34  	dispatcher.bufList = nil
    35  	dispatcher.listenerList = nil
    36  }
    37  
    38  func (dispatcher *Dispatcher) OnKey(handlerKey string, priority int, params ...interface{}) (event *Event) {
    39  	handler := keyToHandler[handlerKey]
    40  	return dispatcher.createListener(handler, priority, false, params...)
    41  }
    42  
    43  // On 添加类型为[type],处理方法为[handler]的监听器,优先级[priority]的数值越大,越早触发
    44  func (dispatcher *Dispatcher) On(handler Handler, priority int, params ...interface{}) (event *Event) {
    45  	return dispatcher.createListener(handler, priority, false, params...)
    46  }
    47  
    48  func (dispatcher *Dispatcher) Once(handler Handler, priority int, params ...interface{}) (event *Event) {
    49  	return dispatcher.createListener(handler, priority, true, params...)
    50  }
    51  
    52  func (dispatcher *Dispatcher) createListener(handler Handler, priority int, once bool, params ...interface{}) (event *Event) {
    53  	if handler == nil {
    54  		panic("#GetDispatcher.On() error: handler is nil")
    55  	}
    56  
    57  	var list = dispatcher.listenerList
    58  	var item = &Event{}
    59  	item.dispatcher = dispatcher
    60  	dispatcher.idCount++
    61  	item.id = dispatcher.idCount
    62  	dispatcher.lastEventOn = item
    63  	item.priority = priority
    64  	item.handler = handler
    65  	item.OnParams = params
    66  	item.isOnce = once
    67  
    68  	var index = 0
    69  	for i := len(list) - 1; i >= 0; i-- {
    70  		if priority > list[i].priority {
    71  			index = i + 1
    72  			break
    73  		}
    74  	}
    75  
    76  	index = int(math.Max(float64(0), float64(index)))
    77  	list = append(list, nil)
    78  	copy(list[index+1:], list[index:])
    79  	list[index] = item
    80  	dispatcher.listenerList = list
    81  
    82  	return item
    83  }
    84  
    85  func (dispatcher *Dispatcher) Off(event *Event) {
    86  	var list = dispatcher.listenerList
    87  	if list == nil {
    88  		return
    89  	}
    90  	if len(list) == 0 {
    91  		return
    92  	}
    93  
    94  	var index = -1
    95  	var remove *Event
    96  	for i, e := range list {
    97  		if e.id == event.id {
    98  			index = i
    99  			remove = event
   100  			break
   101  		}
   102  	}
   103  	if index == -1 {
   104  		return
   105  	}
   106  
   107  	remove.isRemoved = true
   108  	remove.Reset()
   109  	dispatcher.listenerList = append(list[:index], list[index+1:]...)
   110  }
   111  
   112  func (dispatcher *Dispatcher) OffAll() {
   113  	if dispatcher == nil {
   114  		return
   115  	}
   116  	dispatcher.listenerList = []*Event{}
   117  }
   118  
   119  // Dispatch / 派发消息,实现了冒泡
   120  func (dispatcher *Dispatcher) Dispatch(params ...interface{}) (err error) {
   121  	return dispatcher.dispatchBubble(params)
   122  }
   123  
   124  /// 事件冒泡
   125  func (dispatcher *Dispatcher) dispatchBubble(params []interface{}) error {
   126  	var list = dispatcher.listenerList
   127  	if list != nil {
   128  		var buf = dispatcher.bufList
   129  		for {
   130  			if len(list) <= 0 {
   131  				break
   132  			}
   133  			var item = list[len(list)-1]
   134  			list = list[:len(list)-1]
   135  			// 如果事件已经标记删除,不触发事件处理,继续下一个
   136  			if item.isRemoved == true {
   137  				continue
   138  			}
   139  
   140  			item.DispatchParams = params
   141  			// 触发事件的处理函数
   142  			err := item.handler(item)
   143  			if err != nil {
   144  				return err
   145  			}
   146  
   147  			// 只执行一次
   148  			if item.isOnce {
   149  				dispatcher.Off(item)
   150  			}
   151  			// 避免内存泄漏
   152  			item.DispatchParams = nil
   153  			// 如果事件没有标记删除,添加到缓存中
   154  			if item.isRemoved == false {
   155  				buf = append(buf, nil)
   156  				copy(buf[1:], buf[0:])
   157  				buf[0] = item
   158  			}
   159  		}
   160  		// 设置事件kind指向缓存列表
   161  		dispatcher.listenerList = buf
   162  		// 旧的,已经遍历完成的当前列表,放入缓存中
   163  		dispatcher.bufList = list
   164  	}
   165  
   166  	return nil
   167  }