event_chan.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. package event
  2. import (
  3. "context"
  4. "fmt"
  5. "runtime/debug"
  6. "sync"
  7. "time"
  8. "bet24.com/log"
  9. )
  10. type IEventChan interface {
  11. OnEvent()
  12. //Dispatch(ch chan<- interface{})
  13. }
  14. type EventChan_base struct {
  15. EventFunc func(arg string)
  16. Arg string
  17. obj chan interface{}
  18. }
  19. func (e *EventChan_base) OnEvent() {
  20. if e.EventFunc != nil {
  21. e.EventFunc(e.Arg)
  22. }
  23. }
  24. func (ei *EventChan_base) isSame(ei2 *EventChan_base) bool {
  25. if ei2 == nil {
  26. return false
  27. }
  28. if fmt.Sprintf("%p", ei.obj) != fmt.Sprintf("%p", ei2.obj) {
  29. return false
  30. }
  31. return fmt.Sprintf("%p", ei.EventFunc) == fmt.Sprintf("%p", ei2.EventFunc)
  32. }
  33. func (ei *EventChan_base) isSameObject(obj interface{}) bool {
  34. if obj == nil {
  35. return false
  36. }
  37. return fmt.Sprintf("%p", ei.obj) == fmt.Sprintf("%p", obj)
  38. }
  39. type event_chan struct {
  40. sync.RWMutex
  41. events map[string][]EventChan_base
  42. }
  43. var g = newEvent()
  44. func newEvent() *event_chan {
  45. return &event_chan{
  46. events: make(map[string][]EventChan_base),
  47. }
  48. }
  49. func hasFunc(name string, ei *EventChan_base) bool {
  50. evt, ok := g.events[name]
  51. if !ok {
  52. return false
  53. }
  54. for _, f := range evt {
  55. if f.isSame(ei) {
  56. return true
  57. }
  58. }
  59. return false
  60. }
  61. func AddEvent(name string, obj chan interface{}, fn func(arg string)) {
  62. g.Lock()
  63. defer g.Unlock()
  64. if obj == nil || fn == nil {
  65. log.Release("AddEvent no obj or f %v", name)
  66. return
  67. }
  68. ei := EventChan_base{obj: obj, EventFunc: fn}
  69. if hasFunc(name, &ei) {
  70. log.Release("AddEvent same event %v", name)
  71. return
  72. }
  73. g.events[name] = append(g.events[name], ei)
  74. }
  75. func RemoveEvent(name string, obj chan interface{}, fn func(arg string)) {
  76. g.Lock()
  77. defer g.Unlock()
  78. if obj == nil || fn == nil {
  79. log.Release("RemoveEvent no obj or fn %v", name)
  80. return
  81. }
  82. evt, ok := g.events[name]
  83. if !ok {
  84. log.Release("RemoveEvent event name not found: %s", name)
  85. return
  86. }
  87. ei := EventChan_base{obj: obj, EventFunc: fn}
  88. //for k, f := range evt {
  89. for i := 0; i < len(evt); {
  90. if evt[i].isSame(&ei) {
  91. log.Debug("Removing Event %v,%v", name, evt[i])
  92. evt = append(evt[:i], evt[i+1:]...)
  93. } else {
  94. i++
  95. }
  96. }
  97. g.events[name] = evt
  98. //}
  99. if len(g.events[name]) == 0 {
  100. log.Debug("Remove name: %s", name)
  101. delete(g.events, name)
  102. }
  103. }
  104. // 删除对象所有事件
  105. func RemoveAllEvent(obj interface{}) {
  106. if obj == nil {
  107. log.Release("RemoveAllEvent no obj")
  108. return
  109. }
  110. g.Lock()
  111. for name, evt := range g.events {
  112. for i := 0; i < len(evt); {
  113. if evt[i].isSameObject(obj) {
  114. evt = append(evt[:i], evt[i+1:]...)
  115. } else {
  116. i++
  117. }
  118. }
  119. if len(evt) > 0 {
  120. g.events[name] = evt
  121. } else {
  122. delete(g.events, name)
  123. }
  124. }
  125. g.Unlock()
  126. }
  127. func DispatchEvent(eventName, eventArg string) {
  128. go func(n, a string) {
  129. g.RLock()
  130. fns := g.events[n]
  131. g.RUnlock()
  132. if len(fns) == 0 {
  133. return
  134. }
  135. defer func() {
  136. if err := recover(); err != nil {
  137. log.Release("DispatchEvent recover err %v", err)
  138. log.Release("%s", debug.Stack())
  139. }
  140. }()
  141. for i := len(fns) - 1; i >= 0; i-- {
  142. obj := fns[i]
  143. obj.Arg = a
  144. //log.Debug("Dispatching event %v:%v", eventName, obj)
  145. ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*500)
  146. select {
  147. case <-ctx.Done():
  148. //log.Release("Dispatch event timeout %v:%v", eventName, obj)
  149. //RemoveEvent(n, fns[i].obj, fns[i].EventFunc)
  150. break
  151. case fns[i].obj <- &(obj):
  152. break
  153. }
  154. cancel()
  155. }
  156. }(eventName, eventArg)
  157. }
  158. func Dump() {
  159. go func() {
  160. g.RLock()
  161. defer g.RUnlock()
  162. for name, fns := range g.events {
  163. log.Release("event name[%v],count[%d]", name, len(fns))
  164. for _, v := range fns {
  165. log.Release("event func %v", v)
  166. }
  167. }
  168. }()
  169. }