1package uv
2
3import (
4 "context"
5
6 "golang.org/x/sync/errgroup"
7)
8
9// Size represents the size of the terminal window.
10type Size struct {
11 Width int
12 Height int
13}
14
15// Bounds returns the bounds corresponding to the size.
16func (s Size) Bounds() Rectangle {
17 return Rect(0, 0, s.Width, s.Height)
18}
19
20// InputReceiver is an interface for receiving input events from an input source.
21type InputReceiver interface {
22 // ReceiveEvents read input events and channel them to the given event
23 // channel. The listener stops when either the context is done or an error
24 // occurs. Caller is responsible for closing the channels.
25 ReceiveEvents(ctx context.Context, events chan<- Event) error
26}
27
28// InputManager manages input events from multiple input sources. It listens
29// for input events from the registered input sources and combines them into a
30// single event channel. It also handles errors from the input sources and
31// sends them to the error channel.
32type InputManager struct {
33 receivers []InputReceiver
34}
35
36// NewInputManager creates a new InputManager with the input receivers.
37func NewInputManager(receivers ...InputReceiver) *InputManager {
38 im := &InputManager{
39 receivers: receivers,
40 }
41 return im
42}
43
44// RegisterReceiver registers a new input receiver with the input manager.
45func (im *InputManager) RegisterReceiver(r InputReceiver) {
46 im.receivers = append(im.receivers, r)
47}
48
49// ReceiveEvents starts receiving events from the registered input
50// receivers. It sends the events to the given event and error channels.
51func (im *InputManager) ReceiveEvents(ctx context.Context, events chan<- Event) error {
52 errg, ctx := errgroup.WithContext(ctx)
53 for _, r := range im.receivers {
54 errg.Go(func() error {
55 return r.ReceiveEvents(ctx, events)
56 })
57 }
58
59 // Wait for all receivers to finish
60 return errg.Wait()
61}