refactor repl

This commit is contained in:
Josh Deprez 2021-08-27 13:08:04 +10:00
parent eecff52520
commit a19cdfdf6f

View file

@ -15,11 +15,11 @@ func (g *Game) REPL(src io.Reader, dst io.Writer, assets fs.FS) error {
fmt.Fprint(dst, "game>") fmt.Fprint(dst, "game>")
sc := bufio.NewScanner(src) sc := bufio.NewScanner(src)
for sc.Scan() { for sc.Scan() {
tok := strings.Split(sc.Text(), " ") argv := strings.Split(sc.Text(), " ")
if len(tok) == 0 { if len(argv) == 0 {
continue continue
} }
switch tok[0] { switch argv[0] {
case "quit": case "quit":
os.Exit(0) os.Exit(0)
case "pause": case "pause":
@ -27,62 +27,68 @@ func (g *Game) REPL(src io.Reader, dst io.Writer, assets fs.FS) error {
case "resume", "unpause": case "resume", "unpause":
g.Enable() g.Enable()
case "save": case "save":
if len(tok) != 2 { g.cmdSave(dst, argv)
fmt.Fprintln(dst, "Usage: save ID") case "reload":
break g.cmdReload(dst, assets)
case "tree":
g.cmdTree(dst, argv)
} }
id := tok[1] fmt.Fprint(dst, "game>")
}
return sc.Err()
}
func (g *Game) cmdSave(dst io.Writer, argv []string) {
if len(argv) != 2 {
fmt.Fprintln(dst, "Usage: save ID")
return
}
id := argv[1]
c := g.Component(id) c := g.Component(id)
if c == nil { if c == nil {
fmt.Fprintf(dst, "Component %q not found\n", id) fmt.Fprintf(dst, "Component %q not found\n", id)
break return
} }
s, ok := c.(Saver) s, ok := c.(Saver)
if !ok { if !ok {
fmt.Fprintf(dst, "Component %q not a Saver (type %T)\n", id, c) fmt.Fprintf(dst, "Component %q not a Saver (type %T)\n", id, c)
break return
} }
if err := s.Save(); err != nil { if err := s.Save(); err != nil {
fmt.Fprintf(dst, "Couldn't save %q: %v\n", id, err) fmt.Fprintf(dst, "Couldn't save %q: %v\n", id, err)
} }
case "reload": }
func (g *Game) cmdReload(dst io.Writer, assets fs.FS) {
g.Disable() g.Disable()
g.Hide() g.Hide()
if err := g.Load(assets); err != nil { if err := g.Load(assets); err != nil {
fmt.Fprintf(dst, "Couldn't load: %v\n", err) fmt.Fprintf(dst, "Couldn't load: %v\n", err)
break return
} }
g.Prepare() g.Prepare()
g.Enable() g.Enable()
g.Show() g.Show()
case "tree": }
if len(tok) < 1 || len(tok) > 2 {
func (g *Game) cmdTree(dst io.Writer, argv []string) {
if len(argv) < 1 || len(argv) > 2 {
fmt.Println(dst, "Usage: tree [ID]") fmt.Println(dst, "Usage: tree [ID]")
} }
var c interface{} = g var c interface{} = g
if len(tok) == 2 { if len(argv) == 2 { // subtree
// subtree id := argv[1]
id := tok[1]
c = g.Component(id) c = g.Component(id)
if c == nil { if c == nil {
fmt.Fprintf(dst, "Component %q not found\n", id) fmt.Fprintf(dst, "Component %q not found\n", id)
break return
} }
} }
type item struct { var walk func(interface{}, int)
c interface{} walk = func(c interface{}, depth int) {
depth int
}
stack := []item{{c, 0}}
for len(stack) > 0 {
tail := len(stack) - 1
x := stack[tail]
stack = stack[:tail]
c := x.c
indent := "" indent := ""
if x.depth > 0 { if depth > 0 {
indent = strings.Repeat(" ", x.depth-1) + "↳ " indent = strings.Repeat(" ", depth-1) + "↳ "
} }
i, ok := c.(Identifier) i, ok := c.(Identifier)
if ok { if ok {
@ -90,15 +96,11 @@ func (g *Game) REPL(src io.Reader, dst io.Writer, assets fs.FS) error {
} else { } else {
fmt.Fprintf(dst, "%s%T\n", indent, c) fmt.Fprintf(dst, "%s%T\n", indent, c)
} }
if s, ok := c.(Scanner); ok { if s, ok := c.(Scanner); ok {
for _, y := range s.Scan() { for _, d := range s.Scan() {
stack = append(stack, item{y, x.depth + 1}) walk(d, depth+1)
} }
} }
} }
} walk(c, 0)
fmt.Fprint(dst, "game>")
}
return sc.Err()
} }