Add stateful render method to vm
This commit is contained in:
parent
45de1f5c7a
commit
95bee7f8e0
@ -7,7 +7,6 @@ import (
|
||||
"log"
|
||||
|
||||
"git.defalsify.org/festive/cache"
|
||||
"git.defalsify.org/festive/render"
|
||||
"git.defalsify.org/festive/resource"
|
||||
"git.defalsify.org/festive/state"
|
||||
"git.defalsify.org/festive/vm"
|
||||
@ -23,7 +22,7 @@ type Engine struct {
|
||||
st *state.State
|
||||
rs resource.Resource
|
||||
ca cache.Memory
|
||||
pg render.Renderer
|
||||
vm *vm.Vm
|
||||
}
|
||||
|
||||
// NewEngine creates a new Engine
|
||||
@ -32,6 +31,7 @@ func NewEngine(st *state.State, rs resource.Resource, ca cache.Memory) Engine {
|
||||
st: st,
|
||||
rs: rs,
|
||||
ca: ca,
|
||||
vm: vm.NewVm(st, rs, ca, nil),
|
||||
}
|
||||
return engine
|
||||
}
|
||||
@ -40,15 +40,12 @@ func NewEngine(st *state.State, rs resource.Resource, ca cache.Memory) Engine {
|
||||
//
|
||||
// It loads and executes code for the start node.
|
||||
func(en *Engine) Init(sym string, ctx context.Context) error {
|
||||
mn := render.NewMenu()
|
||||
en.pg = render.NewPage(en.ca, en.rs).WithMenu(mn)
|
||||
vmi := vm.NewVm(en.st, en.rs, en.ca, mn, nil)
|
||||
err := en.st.SetInput([]byte{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b := vm.NewLine(nil, vm.MOVE, []string{sym}, nil, nil)
|
||||
b, err = vmi.Run(b, ctx)
|
||||
b, err = en.vm.Run(b, ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -75,9 +72,6 @@ func (en *Engine) Exec(input []byte, ctx context.Context) (bool, error) {
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
mn := render.NewMenu()
|
||||
en.pg = render.NewPage(en.ca, en.rs).WithMenu(mn)
|
||||
vmi := vm.NewVm(en.st, en.rs, en.ca, mn, en.pg)
|
||||
|
||||
log.Printf("new execution with input '%s' (0x%x)", input, input)
|
||||
code, err := en.st.GetCode()
|
||||
@ -87,7 +81,7 @@ func (en *Engine) Exec(input []byte, ctx context.Context) (bool, error) {
|
||||
if len(code) == 0 {
|
||||
return false, fmt.Errorf("no code to execute")
|
||||
}
|
||||
code, err = vmi.Run(code, ctx)
|
||||
code, err = en.vm.Run(code, ctx)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@ -120,27 +114,11 @@ func (en *Engine) Exec(input []byte, ctx context.Context) (bool, error) {
|
||||
// - the supplied writer fails to process the writes.
|
||||
func(en *Engine) WriteResult(w io.Writer) error {
|
||||
location, idx := en.st.Where()
|
||||
v, err := en.ca.Get()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// r, err := en.rs.RenderTemplate(location, v, idx, nil)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// m, err := en.rs.RenderMenu(idx)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// if len(m) > 0 {
|
||||
// r += "\n" + m
|
||||
// }
|
||||
r, err := en.pg.Render(location, v, idx)
|
||||
r, err := en.vm.Render()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c, err := io.WriteString(w, r)
|
||||
log.Printf("%v bytes written as result for %v", c, location)
|
||||
en.pg = nil
|
||||
log.Printf("%v bytes written as result for %v idx %v", c, location, idx)
|
||||
return err
|
||||
}
|
||||
|
@ -257,7 +257,9 @@ func(pg *Page) render(sym string, values map[string]string, idx uint16) (string,
|
||||
return "", err
|
||||
}
|
||||
log.Printf("rendered %v bytes for menu", len(s))
|
||||
r += "\n" + s
|
||||
if len(s) > 0 {
|
||||
r += "\n" + s
|
||||
}
|
||||
if pg.sizer != nil {
|
||||
_, ok = pg.sizer.Check(r)
|
||||
if !ok {
|
||||
@ -267,9 +269,14 @@ func(pg *Page) render(sym string, values map[string]string, idx uint16) (string,
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func(pg *Page) Render(sym string, values map[string]string, idx uint16) (string, error) {
|
||||
func(pg *Page) Render(sym string, idx uint16) (string, error) {
|
||||
var err error
|
||||
|
||||
values, err := pg.cache.Get()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
values, err = pg.prepare(sym, values, idx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
@ -1,7 +1 @@
|
||||
package render
|
||||
|
||||
type Renderer interface {
|
||||
Map(key string) error
|
||||
Render(sym string, values map[string]string, idx uint16) (string, error)
|
||||
Reset()
|
||||
}
|
||||
|
@ -29,11 +29,6 @@ func(szr *Sizer) WithMenuSize(menuSize uint16) *Sizer {
|
||||
}
|
||||
|
||||
func(szr *Sizer) Set(key string, size uint16) error {
|
||||
var ok bool
|
||||
_, ok = szr.memberSizes[key]
|
||||
if ok {
|
||||
return fmt.Errorf("already have key %s", key)
|
||||
}
|
||||
szr.memberSizes[key] = size
|
||||
if size == 0 {
|
||||
szr.sink = key
|
||||
|
@ -98,20 +98,13 @@ func TestSizeLimit(t *testing.T) {
|
||||
mn.Put("1", "foo the foo")
|
||||
mn.Put("2", "go to bar")
|
||||
|
||||
vals, err := ca.Get()
|
||||
var err error
|
||||
_, err = pg.Render("small", 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = pg.Render("small", vals, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
mn.Put("1", "foo the foo")
|
||||
mn.Put("2", "go to bar")
|
||||
|
||||
_, err = pg.Render("toobig", vals, 0)
|
||||
_, err = pg.Render("toobig", 0)
|
||||
if err == nil {
|
||||
t.Fatalf("expected size exceeded")
|
||||
}
|
||||
@ -138,15 +131,10 @@ func TestSizePages(t *testing.T) {
|
||||
pg.Map("baz")
|
||||
pg.Map("xyzzy")
|
||||
|
||||
vals, err := ca.Get()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
mn.Put("1", "foo the foo")
|
||||
mn.Put("2", "go to bar")
|
||||
|
||||
r, err := pg.Render("pages", vals, 0)
|
||||
r, err := pg.Render("pages", 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -163,7 +151,7 @@ lala poo
|
||||
if r != expect {
|
||||
t.Fatalf("expected:\n\t%s\ngot:\n\t%s\n", expect, r)
|
||||
}
|
||||
r, err = pg.Render("pages", vals, 1)
|
||||
r, err = pg.Render("pages", 1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -14,19 +14,29 @@ import (
|
||||
type Vm struct {
|
||||
st *state.State
|
||||
rs resource.Resource
|
||||
pg render.Renderer
|
||||
pg *render.Page
|
||||
ca cache.Memory
|
||||
mn *render.Menu
|
||||
sizer *render.Sizer
|
||||
}
|
||||
|
||||
|
||||
func NewVm(st *state.State, rs resource.Resource, ca cache.Memory, mn *render.Menu, pg render.Renderer) *Vm {
|
||||
return &Vm{
|
||||
func NewVm(st *state.State, rs resource.Resource, ca cache.Memory, sizer *render.Sizer) *Vm {
|
||||
vmi := &Vm{
|
||||
st: st,
|
||||
rs: rs,
|
||||
pg: pg,
|
||||
ca: ca,
|
||||
mn: mn,
|
||||
sizer: sizer,
|
||||
}
|
||||
vmi.Reset()
|
||||
return vmi
|
||||
}
|
||||
|
||||
func(vmi *Vm) Reset() {
|
||||
vmi.mn = render.NewMenu()
|
||||
vmi.pg = render.NewPage(vmi.ca, vmi.rs).WithMenu(vmi.mn)
|
||||
if vmi.sizer != nil {
|
||||
vmi.pg = vmi.pg.WithSizer(vmi.sizer)
|
||||
}
|
||||
}
|
||||
|
||||
@ -316,6 +326,16 @@ func(vm *Vm) RunMPrev(b []byte, ctx context.Context) ([]byte, error) {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func(vm *Vm) Render() (string, error) {
|
||||
sym, idx := vm.st.Where()
|
||||
r, err := vm.pg.Render(sym, idx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
vm.Reset()
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// retrieve data for key
|
||||
func refresh(key string, rs resource.Resource, ctx context.Context) (string, error) {
|
||||
fn, err := rs.FuncFor(key)
|
||||
@ -327,3 +347,4 @@ func refresh(key string, rs resource.Resource, ctx context.Context) (string, err
|
||||
}
|
||||
return fn(ctx)
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,8 @@ func (r TestResource) GetTemplate(sym string) (string, error) {
|
||||
return "inky pinky {{.baz}} blinky clyde", nil
|
||||
case "three":
|
||||
return "{{.one}} inky pinky {{.three}} blinky clyde {{.two}}", nil
|
||||
case "root":
|
||||
return "root", nil
|
||||
case "_catch":
|
||||
return "aiee", nil
|
||||
}
|
||||
@ -85,7 +87,7 @@ func TestRun(t *testing.T) {
|
||||
st := state.NewState(5)
|
||||
rs := TestResource{}
|
||||
ca := cache.NewCache()
|
||||
vm := NewVm(&st, &rs, ca, nil, nil)
|
||||
vm := NewVm(&st, &rs, ca, nil)
|
||||
|
||||
b := NewLine(nil, MOVE, []string{"foo"}, nil, nil)
|
||||
b = NewLine(b, HALT, nil, nil, nil)
|
||||
@ -105,59 +107,46 @@ func TestRunLoadRender(t *testing.T) {
|
||||
st := state.NewState(5)
|
||||
rs := TestResource{}
|
||||
ca := cache.NewCache()
|
||||
pg := render.NewPage(ca, rs)
|
||||
vm := NewVm(&st, &rs, ca, nil, pg)
|
||||
vm := NewVm(&st, &rs, ca, nil)
|
||||
|
||||
st.Down("barbarbar")
|
||||
st.Down("bar")
|
||||
|
||||
var err error
|
||||
b := NewLine(nil, LOAD, []string{"one"}, []byte{0x0a}, nil)
|
||||
b = NewLine(b, LOAD, []string{"two"}, []byte{0x0a}, nil)
|
||||
b = NewLine(b, HALT, nil, nil, nil)
|
||||
b, err = vm.Run(b, context.TODO())
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
m, err := ca.Get()
|
||||
r, err := vm.Render()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
r, err := pg.RenderTemplate("foo", m, 0)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
expect := "inky pinky blinky clyde"
|
||||
expect := "inky pinky one blinky two clyde"
|
||||
if r != expect {
|
||||
t.Errorf("Expected %v, got %v", []byte(expect), []byte(r))
|
||||
}
|
||||
|
||||
r, err = pg.RenderTemplate("bar", m, 0)
|
||||
if err == nil {
|
||||
t.Errorf("expected error for render of bar: %v" ,err)
|
||||
t.Fatalf("Expected\n\t%s\ngot\n\t%s\n", expect, r)
|
||||
}
|
||||
|
||||
b = NewLine(nil, LOAD, []string{"two"}, []byte{0x0a}, nil)
|
||||
b = NewLine(b, HALT, nil, nil, nil)
|
||||
b, err = vm.Run(b, context.TODO())
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
b = NewLine(nil, MAP, []string{"one"}, nil, nil)
|
||||
b = NewLine(b, HALT, nil, nil, nil)
|
||||
_, err = vm.Run(b, context.TODO())
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
m, err = ca.Get()
|
||||
r, err = vm.Render()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
r, err = pg.RenderTemplate("bar", m, 0)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
expect = "inky pinky one blinky two clyde"
|
||||
if r != expect {
|
||||
t.Errorf("Expected %v, got %v", expect, r)
|
||||
t.Fatalf("Expected %v, got %v", expect, r)
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,7 +154,7 @@ func TestRunMultiple(t *testing.T) {
|
||||
st := state.NewState(5)
|
||||
rs := TestResource{}
|
||||
ca := cache.NewCache()
|
||||
vm := NewVm(&st, &rs, ca, nil, nil)
|
||||
vm := NewVm(&st, &rs, ca, nil)
|
||||
|
||||
b := NewLine(nil, MOVE, []string{"test"}, nil, nil)
|
||||
b = NewLine(b, LOAD, []string{"one"}, []byte{0x00}, nil)
|
||||
@ -184,8 +173,8 @@ func TestRunReload(t *testing.T) {
|
||||
st := state.NewState(5)
|
||||
rs := TestResource{}
|
||||
ca := cache.NewCache()
|
||||
pg := render.NewPage(ca, rs)
|
||||
vm := NewVm(&st, &rs, ca, nil, pg)
|
||||
szr := render.NewSizer(128)
|
||||
vm := NewVm(&st, &rs, ca, szr)
|
||||
|
||||
b := NewLine(nil, MOVE, []string{"root"}, nil, nil)
|
||||
b = NewLine(b, LOAD, []string{"dyn"}, nil, []uint8{0})
|
||||
@ -195,12 +184,13 @@ func TestRunReload(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r, err := pg.Val("dyn")
|
||||
r, err := vm.Render()
|
||||
// r, err := pg.Val("dyn")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if r != "three" {
|
||||
t.Fatalf("expected result 'three', got %v", r)
|
||||
if r != "root" {
|
||||
t.Fatalf("expected result 'root', got %v", r)
|
||||
}
|
||||
dynVal = "baz"
|
||||
b = NewLine(nil, RELOAD, []string{"dyn"}, nil, nil)
|
||||
@ -209,21 +199,21 @@ func TestRunReload(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r, err = pg.Val("dyn")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
log.Printf("dun now %s", r)
|
||||
if r != "baz" {
|
||||
t.Fatalf("expected result 'baz', got %v", r)
|
||||
}
|
||||
// r, err = pg.Val("dyn")
|
||||
// if err != nil {
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
// log.Printf("dun now %s", r)
|
||||
// if r != "baz" {
|
||||
// t.Fatalf("expected result 'baz', got %v", r)
|
||||
// }
|
||||
}
|
||||
|
||||
func TestHalt(t *testing.T) {
|
||||
st := state.NewState(5)
|
||||
rs := TestResource{}
|
||||
ca := cache.NewCache()
|
||||
vm := NewVm(&st, &rs, ca, nil, nil)
|
||||
vm := NewVm(&st, &rs, ca, nil)
|
||||
|
||||
b := NewLine(nil, MOVE, []string{"root"}, nil, nil)
|
||||
b = NewLine(b, LOAD, []string{"one"}, nil, []uint8{0})
|
||||
@ -247,7 +237,7 @@ func TestRunArg(t *testing.T) {
|
||||
st := state.NewState(5)
|
||||
rs := TestResource{}
|
||||
ca := cache.NewCache()
|
||||
vm := NewVm(&st, &rs, ca, nil, nil)
|
||||
vm := NewVm(&st, &rs, ca, nil)
|
||||
|
||||
input := []byte("bar")
|
||||
_ = st.SetInput(input)
|
||||
@ -272,8 +262,7 @@ func TestRunInputHandler(t *testing.T) {
|
||||
st := state.NewState(5)
|
||||
rs := TestResource{}
|
||||
ca := cache.NewCache()
|
||||
pg := render.NewPage(ca, rs)
|
||||
vm := NewVm(&st, &rs, ca, nil, pg)
|
||||
vm := NewVm(&st, &rs, ca, nil)
|
||||
|
||||
_ = st.SetInput([]byte("baz"))
|
||||
|
||||
@ -300,8 +289,7 @@ func TestRunArgInvalid(t *testing.T) {
|
||||
st := state.NewState(5)
|
||||
rs := TestResource{}
|
||||
ca := cache.NewCache()
|
||||
mn := render.NewMenu()
|
||||
vm := NewVm(&st, &rs, ca, mn, nil)
|
||||
vm := NewVm(&st, &rs, ca, nil)
|
||||
|
||||
_ = st.SetInput([]byte("foo"))
|
||||
|
||||
@ -324,8 +312,7 @@ func TestRunMenu(t *testing.T) {
|
||||
st := state.NewState(5)
|
||||
rs := TestResource{}
|
||||
ca := cache.NewCache()
|
||||
mn := render.NewMenu()
|
||||
vm := NewVm(&st, &rs, ca, mn, nil)
|
||||
vm := NewVm(&st, &rs, ca, nil)
|
||||
|
||||
var err error
|
||||
|
||||
@ -343,11 +330,11 @@ func TestRunMenu(t *testing.T) {
|
||||
t.Errorf("expected empty remainder, got length %v: %v", l, b)
|
||||
}
|
||||
|
||||
r, err := mn.Render(0)
|
||||
r, err := vm.Render()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
expect := "0:one\n1:two"
|
||||
expect := "inky pinky blinky clyde\n0:one\n1:two"
|
||||
if r != expect {
|
||||
t.Fatalf("expected:\n\t%s\ngot:\n\t%s\n", expect, r)
|
||||
}
|
||||
@ -358,8 +345,7 @@ func TestRunMenuBrowse(t *testing.T) {
|
||||
st := state.NewState(5)
|
||||
rs := TestResource{}
|
||||
ca := cache.NewCache()
|
||||
mn := render.NewMenu()
|
||||
vm := NewVm(&st, &rs, ca, mn, nil)
|
||||
vm := NewVm(&st, &rs, ca, nil)
|
||||
|
||||
var err error
|
||||
|
||||
@ -377,11 +363,11 @@ func TestRunMenuBrowse(t *testing.T) {
|
||||
t.Errorf("expected empty remainder, got length %v: %v", l, b)
|
||||
}
|
||||
|
||||
r, err := mn.Render(0)
|
||||
r, err := vm.Render()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
expect := "0:one\n1:two"
|
||||
expect := "inky pinky blinky clyde\n0:one\n1:two"
|
||||
if r != expect {
|
||||
t.Fatalf("expected:\n\t%s\ngot:\n\t%s\n", expect, r)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user