github.com/GeniusesGroup/libgo@v0.0.0-20220929090155-5ff932cb408e/event/target.go (about)

     1  /* For license and copyright information please see LEGAL file in repository */
     2  
     3  package event
     4  
     5  import (
     6  	"sync"
     7  
     8  	"github.com/GeniusesGroup/libgo/protocol"
     9  )
    10  
    11  // EventTarget must declare separately for each protocol.EventMainType types.
    12  // otherwise need this struct that use 2KB for each instance.
    13  // 		cl   [256]*[]customListener // 256 is max protocol.EventMainType
    14  // Or use map but need some benchmarks to check performance.
    15  type EventTarget struct {
    16  	sync sync.Mutex
    17  	lls  *[]customListener
    18  }
    19  
    20  type customListener struct {
    21  	eventSubType  protocol.EventSubType
    22  	eventListener protocol.EventListener
    23  }
    24  
    25  //go:norace
    26  // TODO::: we know that race exist in line #44,#59 with #28,#40,#52, but it seems ok to have race there. Add atomic mechanism??
    27  func (et *EventTarget) DispatchEvent(event protocol.Event) {
    28  	var lls = *et.lls
    29  	var eventSubType = event.SubType()
    30  	for i := 0; i < len(lls); i++ {
    31  		var cl = lls[i]
    32  		if cl.eventSubType == protocol.EventSubType_Unset || cl.eventSubType == eventSubType {
    33  			cl.eventListener.EventHandler(event)
    34  		}
    35  	}
    36  }
    37  
    38  func (et *EventTarget) AddEventListener(mainType protocol.EventMainType, subType protocol.EventSubType, callback protocol.EventListener, options protocol.AddEventListenerOptions) {
    39  	et.sync.Lock()
    40  	var lls = *et.lls
    41  	var ln = len(lls)
    42  	var newLLS = make([]customListener, ln+1)
    43  	copy(newLLS, lls)
    44  	newLLS[ln-1] = customListener{subType, callback}
    45  	et.lls = &newLLS
    46  	// TODO::: handle options here or caller layer must handle it?
    47  	et.sync.Unlock()
    48  }
    49  
    50  func (et *EventTarget) RemoveEventListener(mainType protocol.EventMainType, subType protocol.EventSubType, callback protocol.EventListener, options protocol.EventListenerOptions) {
    51  	et.sync.Lock()
    52  	var lls = *et.lls
    53  	var ln = len(lls)
    54  	for i := 0; i < ln; i++ {
    55  		var cl = lls[i]
    56  		if cl.eventSubType == subType && cl.eventListener == callback {
    57  			var newLLS = make([]customListener, ln-1)
    58  			copy(newLLS, lls[:i])
    59  			copy(newLLS[i:], lls[i+1:])
    60  			et.lls = &newLLS
    61  			break
    62  		}
    63  	}
    64  	et.sync.Unlock()
    65  }