-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathevent.go
118 lines (99 loc) · 2.72 KB
/
event.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package bubbly
import (
tea "github.com/charmbracelet/bubbletea"
"github.com/wagoodman/go-partybus"
)
var (
_ EventHandler = (*EventDispatcher)(nil)
_ interface {
EventHandler
MessageListener
HandleWaiter
} = (*HandlerCollection)(nil)
)
type EventHandlerFn func(partybus.Event) ([]tea.Model, tea.Cmd)
type EventHandler interface {
partybus.Responder
// Handle optionally generates new models and commands in response to the given event. It might be that the event
// has an effect on the system, but the model is managed by a sub-component, in which case no new model would be
// returned but the Init() call on the managed model would return commands that should be executed in the context
// of the application lifecycle.
Handle(partybus.Event) ([]tea.Model, tea.Cmd)
}
type MessageListener interface {
OnMessage(tea.Msg)
}
type HandleWaiter interface {
Wait()
}
type EventDispatcher struct {
dispatch map[partybus.EventType]EventHandlerFn
types []partybus.EventType
}
func NewEventDispatcher() *EventDispatcher {
return &EventDispatcher{
dispatch: map[partybus.EventType]EventHandlerFn{},
}
}
func (d *EventDispatcher) AddHandlers(handlers map[partybus.EventType]EventHandlerFn) {
for t, h := range handlers {
d.AddHandler(t, h)
}
}
func (d *EventDispatcher) AddHandler(t partybus.EventType, fn EventHandlerFn) {
d.dispatch[t] = fn
d.types = append(d.types, t)
}
func (d EventDispatcher) RespondsTo() []partybus.EventType {
return d.types
}
func (d EventDispatcher) Handle(e partybus.Event) ([]tea.Model, tea.Cmd) {
if fn, ok := d.dispatch[e.Type]; ok {
return fn(e)
}
return nil, nil
}
type HandlerCollection struct {
handlers []EventHandler
}
func NewHandlerCollection(handlers ...EventHandler) *HandlerCollection {
return &HandlerCollection{
handlers: handlers,
}
}
func (h *HandlerCollection) Append(handlers ...EventHandler) {
h.handlers = append(h.handlers, handlers...)
}
func (h HandlerCollection) RespondsTo() []partybus.EventType {
var ret []partybus.EventType
for _, handler := range h.handlers {
ret = append(ret, handler.RespondsTo()...)
}
return ret
}
func (h HandlerCollection) Handle(event partybus.Event) ([]tea.Model, tea.Cmd) {
var (
newModels []tea.Model
newCmd tea.Cmd
)
for _, handler := range h.handlers {
mods, cmd := handler.Handle(event)
newModels = append(newModels, mods...)
newCmd = tea.Batch(newCmd, cmd)
}
return newModels, newCmd
}
func (h HandlerCollection) OnMessage(msg tea.Msg) {
for _, handler := range h.handlers {
if listener, ok := handler.(MessageListener); ok {
listener.OnMessage(msg)
}
}
}
func (h HandlerCollection) Wait() {
for _, handler := range h.handlers {
if listener, ok := handler.(HandleWaiter); ok {
listener.Wait()
}
}
}