dict_topic_sub.go 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. // package dict_topic_sub -- потокобезопасный словарь подписчиков локальной шины.
  2. package dict_topic_sub
  3. import (
  4. "gitp78su.ipnodns.ru/svi/kern/v4/d0"
  5. "gitp78su.ipnodns.ru/svi/kern/v4/d0/helpers"
  6. "gitp78su.ipnodns.ru/svi/kern/v4/d2/kern_ctx"
  7. "gitp78su.ipnodns.ru/svi/kern/v4/d2/lti/bus_ent"
  8. "gitp78su.ipnodns.ru/svi/kern/v4/d2/lti/bus_ent/topic"
  9. "gitp78su.ipnodns.ru/svi/kern/v4/d2/lti/bus_spec"
  10. "gitp78su.ipnodns.ru/svi/kern/v4/d2/lti/kbus/dict_sub_hook"
  11. )
  12. type tReadReq struct {
  13. topic *topic.LTopic
  14. binMsg []byte
  15. }
  16. // dictTopicSub -- потокобезопасный словарь подписчиков.
  17. type dictTopicSub struct {
  18. *d0.MSafeMutex
  19. kCtx *kern_ctx.KernCtx
  20. owner *d0.LOwner
  21. dictTopicHook map[bus_ent.ATopic]bus_spec.IDictSubHook
  22. }
  23. // NewDictTopicSub -- возвращает потокобезопасный словарь подписчиков.
  24. func NewDictTopicSub(owner *d0.LOwner) *dictTopicSub {
  25. sf := &dictTopicSub{
  26. MSafeMutex: d0.MutSafeMutex(),
  27. kCtx: kern_ctx.GetKernCtx(),
  28. owner: owner,
  29. dictTopicHook: map[bus_ent.ATopic]bus_spec.IDictSubHook{},
  30. }
  31. return sf
  32. }
  33. // Read -- вызывает обработчики при поступлении события.
  34. func (sf *dictTopicSub) Read(topic *topic.LTopic, binMsg []byte) {
  35. sf.RLock()
  36. defer sf.RUnlock()
  37. msg := &tReadReq{
  38. topic: topic,
  39. binMsg: binMsg,
  40. }
  41. dictHook := sf.dictTopicHook[msg.topic.Get()]
  42. if dictHook == nil {
  43. return
  44. }
  45. dictHook.Read(msg.binMsg)
  46. }
  47. // Subscribe -- подписывает обработчик на топик.
  48. func (sf *dictTopicSub) Subscribe(handler bus_spec.IBusHandlerSubscribe) {
  49. sf.Lock()
  50. defer sf.Unlock()
  51. d0.If(handler == nil).
  52. Hassert("dictTopicSub.Subscribe(): handler==nil")
  53. topic := handler.Topic()
  54. dictSubHook := sf.dictTopicHook[topic.Get()]
  55. if dictSubHook == nil {
  56. dictSubHook := dict_sub_hook.NewDictSubHook(sf.owner)
  57. sf.dictTopicHook[topic.Get()] = dictSubHook
  58. }
  59. dictSubHook.Subscribe(handler)
  60. }
  61. // Unsubscribe -- отписывает обработчик.
  62. func (sf *dictTopicSub) Unsubscribe(handler bus_spec.IBusHandlerSubscribe) {
  63. sf.Lock()
  64. defer sf.Unlock()
  65. helpers.If(handler == nil).Hassert("dictTopicSub.Unsubscribe(): handler==nil", []any{})
  66. topic := handler.Topic()
  67. dictSubHook := sf.dictTopicHook[topic.Get()]
  68. if dictSubHook == nil {
  69. return
  70. }
  71. dictSubHook.Unsubscribe(handler)
  72. }