input.go

 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}