src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

main.go (2263B)


      1 package main
      2 
      3 import (
      4 	"context"
      5 	"flag"
      6 	"os"
      7 	"os/signal"
      8 	"path/filepath"
      9 	"syscall"
     10 	"time"
     11 
     12 	"code.dwrz.net/src/pkg/log"
     13 	"code.dwrz.net/src/pkg/minotaur"
     14 	"code.dwrz.net/src/pkg/terminal"
     15 )
     16 
     17 var (
     18 	height = flag.Int("h", 0, "height")
     19 	width  = flag.Int("w", 0, "width")
     20 	tick   = flag.Int("t", 250, "ms between minotaur movement")
     21 )
     22 
     23 func main() {
     24 	var l = log.New(os.Stderr)
     25 
     26 	// Parse flags.
     27 	flag.Parse()
     28 	if *height < 0 {
     29 		l.Error.Fatalf("invalid height: %d", *height)
     30 	}
     31 	if *width < 0 {
     32 		l.Error.Fatalf("invalid width: %d", *width)
     33 	}
     34 	if *tick <= 0 {
     35 		l.Error.Fatalf("invalid tick: %d", *tick)
     36 	}
     37 
     38 	// Setup the main context.
     39 	ctx, cancel := context.WithCancel(context.Background())
     40 
     41 	// Setup workspace and log file.
     42 	cdir, err := os.UserCacheDir()
     43 	if err != nil {
     44 		l.Error.Fatalf(
     45 			"failed to determine user cache directory: %v", err,
     46 		)
     47 	}
     48 	wdir := filepath.Join(cdir, "minotaur")
     49 
     50 	if err := os.MkdirAll(wdir, os.ModeDir|0700); err != nil {
     51 		l.Error.Fatalf("failed to create tmp dir: %v", err)
     52 	}
     53 
     54 	f, err := os.Create(wdir + "/log")
     55 	if err != nil {
     56 		l.Error.Fatalf("failed to create log file: %v", err)
     57 	}
     58 	defer f.Close()
     59 
     60 	// Retrieve terminal info.
     61 	t, err := terminal.New(os.Stdin.Fd())
     62 	if err != nil {
     63 		l.Error.Fatalf("failed to get terminal attributes: %v", err)
     64 	}
     65 	size, err := t.Size()
     66 	if err != nil {
     67 		l.Error.Fatalf("failed to get terminal size: %v", err)
     68 	}
     69 	// If no dimensions were provided, use the terminal size.
     70 	if *height == 0 {
     71 		rows := int(size.Rows)
     72 		height = &rows
     73 	}
     74 	if *width == 0 {
     75 		cols := int(size.Columns)
     76 		width = &cols
     77 	}
     78 
     79 	// TODO: refactor; handle sigwinch.
     80 	go func() {
     81 		var signals = make(chan os.Signal, 1)
     82 		signal.Notify(signals, syscall.SIGTERM, syscall.SIGINT)
     83 
     84 		// Block until we receive a signal.
     85 		s := <-signals
     86 		l.Debug.Printf("received signal: %s", s)
     87 
     88 		cancel()
     89 	}()
     90 
     91 	// Setup the game.
     92 	game, err := minotaur.New(minotaur.Parameters{
     93 		Height:   *height,
     94 		In:       os.Stdin,
     95 		Log:      log.New(f),
     96 		Out:      os.Stdout,
     97 		Terminal: t,
     98 		Tick:     time.Duration(*tick) * time.Millisecond,
     99 		Width:    *width,
    100 	})
    101 	if err != nil {
    102 		l.Error.Fatalf("failed to create game: %v", err)
    103 	}
    104 
    105 	// Run the game.
    106 	if err := game.Run(ctx); err != nil {
    107 		l.Error.Fatal(err)
    108 	}
    109 }