diff --git a/cmd/life/main.go b/cmd/life/main.go index fdab71c..9f05475 100644 --- a/cmd/life/main.go +++ b/cmd/life/main.go @@ -22,20 +22,29 @@ var ( ) func main() { + flag.Parse() + var log = slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{ AddSource: true, Level: slog.LevelDebug, })) - if err := run(log); err != nil { + // Setup the main context. + // The context cancels on SIGINT or SIGTERM. + ctx, stop := signal.NotifyContext( + context.Background(), + syscall.SIGINT, + syscall.SIGTERM, + ) + defer stop() + + if err := run(ctx, log); err != nil { log.Error("failed", slog.Any("error", err)) os.Exit(1) } } -func run(log *slog.Logger) error { - // Parse flags. - flag.Parse() +func run(ctx context.Context, log *slog.Logger) error { if *height < 0 { return fmt.Errorf("invalid height: %d", *height) } @@ -46,10 +55,6 @@ func run(log *slog.Logger) error { return fmt.Errorf("invalid tick: %d", *tick) } - // Setup the main context. - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - // Setup workspace and log file. cdir, err := os.UserCacheDir() if err != nil { @@ -92,18 +97,6 @@ func run(log *slog.Logger) error { width = &cols } - // TODO: refactor; handle sigwinch. - go func() { - var signals = make(chan os.Signal, 1) - signal.Notify(signals, syscall.SIGTERM, syscall.SIGINT) - - // Block until we receive a signal. - s := <-signals - log.Debug("received signal", slog.Any("signal", s)) - - cancel() - }() - // Setup the game. var game = life.New(life.Parameters{ Height: *height, diff --git a/internal/life/life.go b/internal/life/life.go index d17167f..c6caa93 100644 --- a/internal/life/life.go +++ b/internal/life/life.go @@ -120,6 +120,7 @@ func (l *Life) Run(ctx context.Context) error { }() // Main loop. + // TODO: handle sigwinch; resize the world on terminal resize. for { select { case <-ctx.Done():