diff --git a/diagnoser/diagnoser.go b/diagnoser/diagnoser.go index 619427d..149197b 100644 --- a/diagnoser/diagnoser.go +++ b/diagnoser/diagnoser.go @@ -26,7 +26,8 @@ func Run(addr *net.TCPAddr, scrapeInterval time.Duration) error { if err != nil { return err } - return gui.Run(ctx, scrapeInterval, meta, statsCh) + g := gui.NewGUI(scrapeInterval, cancel, statsCh, meta) + return g.Run(ctx) } func startScraping(ctx context.Context, addr *net.TCPAddr, interval time.Duration, statsCh chan<- *stats.Stats) (*stats.Meta, error) { diff --git a/diagnoser/gui/drawer.go b/diagnoser/gui/drawer.go new file mode 100644 index 0000000..c13f656 --- /dev/null +++ b/diagnoser/gui/drawer.go @@ -0,0 +1,4 @@ +package gui + +type drawer struct { +} diff --git a/diagnoser/gui/gui.go b/diagnoser/gui/gui.go index 751ef3e..2603835 100644 --- a/diagnoser/gui/gui.go +++ b/diagnoser/gui/gui.go @@ -1,3 +1,4 @@ +// Package gui provides an ability to draw charts on the terminal. package gui import ( @@ -16,15 +17,38 @@ import ( ) const ( - // How often termdash redraws the screen. defaultRedrawInterval = time.Second rootID = "root" ) -type runner func(ctx context.Context, t terminalapi.Terminal, c *container.Container, opts ...termdash.Option) error +type GUI struct { + // How often termdash redraws the screen. + RedrawInterval time.Duration + // The function to quit the application. + Cancel context.CancelFunc + // A channel for receiving data sources to draw on the chart. + StatsCh <-chan *stats.Stats + // Metadata of the process where the agent runs on. + Metadata stats.Meta +} -// Run stats drawing charts, and blocks until the quit operation is performed. -func Run(ctx context.Context, redrawIntarval time.Duration, meta *stats.Meta, statsCh <-chan *stats.Stats) error { +func NewGUI(redrawInterval time.Duration, cancel context.CancelFunc, statsCh <-chan *stats.Stats, metadata *stats.Meta) *GUI { + if redrawInterval == 0 { + redrawInterval = defaultRedrawInterval + } + if statsCh == nil { + statsCh = make(<-chan *stats.Stats) + } + return &GUI{ + RedrawInterval: redrawInterval, + Cancel: cancel, + StatsCh: statsCh, + Metadata: *metadata, + } +} + +// Run starts drawing charts, and blocks until the quit operation is performed. +func (g *GUI) Run(ctx context.Context) error { var ( t terminalapi.Terminal err error @@ -38,9 +62,41 @@ func Run(ctx context.Context, redrawIntarval time.Duration, meta *stats.Meta, st return fmt.Errorf("failed to generate terminal interface: %w", err) } defer t.Close() - return run(ctx, t, termdash.Run) + return g.run(ctx, t, termdash.Run) +} + +type runner func(ctx context.Context, t terminalapi.Terminal, c *container.Container, opts ...termdash.Option) error + +func (g *GUI) run(ctx context.Context, t terminalapi.Terminal, r runner) error { + c, err := container.New(t, container.ID(rootID)) + if err != nil { + return fmt.Errorf("failed to generate container: %w", err) + } + + w, err := newWidgets() + if err != nil { + return fmt.Errorf("failed to generate widgets: %w", err) + } + + gridOpts, err := gridLayout(w) + if err != nil { + return fmt.Errorf("failed to build grid layout: %w", err) + } + + if err := c.Update(rootID, gridOpts.base...); err != nil { + return fmt.Errorf("failed to update container: %w", err) + } + k := keybinds(ctx, g.Cancel) + + return r(ctx, t, c, termdash.KeyboardSubscriber(k), termdash.RedrawInterval(g.RedrawInterval)) +} + +// gridOpts holds all options in our grid. It basically holds the container +// options (column, width, padding, etc) of our widgets. +type gridOpts struct { + base []container.Option } -func run(ctx context.Context, t terminalapi.Terminal, r runner) error { - return nil +func gridLayout(w *widgets) (*gridOpts, error) { + return nil, nil } diff --git a/diagnoser/gui/keybinds.go b/diagnoser/gui/keybinds.go new file mode 100644 index 0000000..2c8e09c --- /dev/null +++ b/diagnoser/gui/keybinds.go @@ -0,0 +1,11 @@ +package gui + +import ( + "context" + + "github.com/mum4k/termdash/terminal/terminalapi" +) + +func keybinds(ctx context.Context, cancel context.CancelFunc) func(*terminalapi.Keyboard) { + return nil +}