Add code comment documentation
This commit is contained in:
parent
91ee0568ca
commit
e340210d8f
@ -17,10 +17,12 @@ import (
|
||||
)
|
||||
|
||||
|
||||
// Asm assembles bytecode from the festive assembly mini-language.
|
||||
type Asm struct {
|
||||
Instructions []*Instruction `@@*`
|
||||
}
|
||||
|
||||
// Arg holds all parsed argument elements of a single line of assembly code.
|
||||
type Arg struct {
|
||||
Sym *string `(@Sym Whitespace?)?`
|
||||
Size *uint32 `(@Size Whitespace?)?`
|
||||
@ -214,6 +216,7 @@ func parseOne(op vm.Opcode, instruction *Instruction, w io.Writer) (int, error)
|
||||
return flush(b, w)
|
||||
}
|
||||
|
||||
// String implements the String interface.
|
||||
func (a Arg) String() string {
|
||||
s := "[Arg]"
|
||||
if a.Sym != nil {
|
||||
@ -235,12 +238,14 @@ func (a Arg) String() string {
|
||||
return fmt.Sprintf(s)
|
||||
}
|
||||
|
||||
// Instruction represents one full line of assembly code.
|
||||
type Instruction struct {
|
||||
OpCode string `@Ident`
|
||||
OpArg Arg `(Whitespace @@)?`
|
||||
Comment string `Comment? EOL`
|
||||
}
|
||||
|
||||
// String implement the String interface.
|
||||
func (i Instruction) String() string {
|
||||
return fmt.Sprintf("%s %s", i.OpCode, i.OpArg)
|
||||
}
|
||||
@ -303,17 +308,20 @@ func writeSize(w *bytes.Buffer, n uint32) (int, error) {
|
||||
return w.Write(bn[c:])
|
||||
}
|
||||
|
||||
// Batcher handles assembly commands that generates multiple instructions, such as menu navigation commands.
|
||||
type Batcher struct {
|
||||
menuProcessor MenuProcessor
|
||||
inMenu bool
|
||||
}
|
||||
|
||||
// NewBatcher creates a new Batcher objcet.
|
||||
func NewBatcher(mp MenuProcessor) Batcher {
|
||||
return Batcher{
|
||||
menuProcessor: NewMenuProcessor(),
|
||||
}
|
||||
}
|
||||
|
||||
// MenuExit generates the instructions for the batch and writes them to the given io.Writer.
|
||||
func(bt *Batcher) MenuExit(w io.Writer) (int, error) {
|
||||
if !bt.inMenu {
|
||||
return 0, nil
|
||||
@ -323,6 +331,7 @@ func(bt *Batcher) MenuExit(w io.Writer) (int, error) {
|
||||
return w.Write(b)
|
||||
}
|
||||
|
||||
// MenuAdd adds a new menu instruction to the batcher.
|
||||
func(bt *Batcher) MenuAdd(w io.Writer, code string, arg Arg) (int, error) {
|
||||
bt.inMenu = true
|
||||
var selector string
|
||||
@ -343,10 +352,12 @@ func(bt *Batcher) MenuAdd(w io.Writer, code string, arg Arg) (int, error) {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// Exit is a synonym for MenuExit
|
||||
func(bt *Batcher) Exit(w io.Writer) (int, error) {
|
||||
return bt.MenuExit(w)
|
||||
}
|
||||
|
||||
// Parse one or more lines of assembly code, and write assembled bytecode to the provided writer.
|
||||
func Parse(s string, w io.Writer) (int, error) {
|
||||
rd := strings.NewReader(s)
|
||||
ast, err := asmParser.Parse("file", rd)
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"git.defalsify.org/festive/vm"
|
||||
)
|
||||
|
||||
// BatchCode defines quasi-opcodes that expand to mulitple individual vm instructions.
|
||||
type BatchCode uint16
|
||||
|
||||
const (
|
||||
@ -32,15 +33,22 @@ type menuItem struct {
|
||||
target string
|
||||
}
|
||||
|
||||
// MenuProcessor handles code lines with BatchCode quasi-opcodes that control menu generation.
|
||||
//
|
||||
// It creates vm instructions for display of menu and handling of input on either size of a vm.HALT instruction.
|
||||
type MenuProcessor struct {
|
||||
items []menuItem
|
||||
size uint32
|
||||
}
|
||||
|
||||
// NewMenuProcessor creates a new MenuProcessor object.
|
||||
func NewMenuProcessor() MenuProcessor {
|
||||
return MenuProcessor{}
|
||||
}
|
||||
|
||||
// Add a menu batch instruction to be processed.
|
||||
//
|
||||
// Instructions will be rendered in the order in which they have been added.
|
||||
func(mp *MenuProcessor) Add(bop string, choice string, display string, target string) error {
|
||||
bopCode := batchCode[bop]
|
||||
if bopCode == 0 {
|
||||
@ -59,6 +67,7 @@ func(mp *MenuProcessor) Add(bop string, choice string, display string, target st
|
||||
return nil
|
||||
}
|
||||
|
||||
// ToLines returns the generated bytecode from the added menu batch instructions.
|
||||
func (mp *MenuProcessor) ToLines() []byte {
|
||||
preLines := []byte{}
|
||||
postLines := []byte{}
|
||||
|
11
go/cache/cache.go
vendored
11
go/cache/cache.go
vendored
@ -5,14 +5,12 @@ import (
|
||||
"log"
|
||||
)
|
||||
|
||||
// Cache stores loaded content, enforcing size limits and keeping track of size usage.
|
||||
type Cache struct {
|
||||
CacheSize uint32 // Total allowed cumulative size of values (not code) in cache
|
||||
CacheUseSize uint32 // Currently used bytes by all values (not code) in cache
|
||||
Cache []map[string]string // All loaded cache items
|
||||
//CacheMap map[string]string // Mapped
|
||||
//outputSize uint32 // Max size of output
|
||||
sizes map[string]uint16 // Size limits for all loaded symbols.
|
||||
//sink *string
|
||||
}
|
||||
|
||||
// NewCache creates a new ready-to-use cache object
|
||||
@ -21,7 +19,6 @@ func NewCache() *Cache {
|
||||
Cache: []map[string]string{make(map[string]string)},
|
||||
sizes: make(map[string]uint16),
|
||||
}
|
||||
//ca.resetCurrent()
|
||||
return ca
|
||||
}
|
||||
|
||||
@ -97,9 +94,6 @@ func(ca *Cache) Update(key string, value string) error {
|
||||
r := ca.Cache[checkFrame][key]
|
||||
l := uint32(len(r))
|
||||
ca.Cache[checkFrame][key] = ""
|
||||
//if ca.CacheMap[key] != "" {
|
||||
// ca.CacheMap[key] = value
|
||||
//}
|
||||
ca.CacheUseSize -= l
|
||||
sz := ca.checkCapacity(value)
|
||||
if sz == 0 {
|
||||
@ -113,6 +107,9 @@ func(ca *Cache) Update(key string, value string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get the content currently loaded for a single key, loaded at any level.
|
||||
//
|
||||
// Fails if key has not been loaded.
|
||||
func(ca *Cache) Get(key string) (string, error) {
|
||||
i := ca.frameOf(key)
|
||||
r, ok := ca.Cache[i][key]
|
||||
|
1
go/cache/memory.go
vendored
1
go/cache/memory.go
vendored
@ -1,5 +1,6 @@
|
||||
package cache
|
||||
|
||||
// Memory defines the interface for store of a symbol mapped content store.
|
||||
type Memory interface {
|
||||
Add(key string, val string, sizeLimit uint16) error
|
||||
Update(key string, val string) error
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"git.defalsify.org/festive/state"
|
||||
)
|
||||
|
||||
// NewDefaultEngine is a convenience function to instantiate a filesystem-backed engine with no output constraints.
|
||||
func NewDefaultEngine(dir string) Engine {
|
||||
st := state.NewState(0)
|
||||
rs := resource.NewFsResource(dir)
|
||||
@ -13,6 +14,7 @@ func NewDefaultEngine(dir string) Engine {
|
||||
return NewEngine(Config{}, &st, &rs, ca)
|
||||
}
|
||||
|
||||
// NewSizedEngine is a convenience function to instantiate a filesystem-backed engine with a specified output constraint.
|
||||
func NewSizedEngine(dir string, size uint32) Engine {
|
||||
st := state.NewState(0)
|
||||
rs := resource.NewFsResource(dir)
|
||||
|
@ -13,13 +13,12 @@ import (
|
||||
"git.defalsify.org/festive/vm"
|
||||
)
|
||||
|
||||
// Config globally defines behavior of all components driven by the engine.
|
||||
type Config struct {
|
||||
OutputSize uint32
|
||||
// FlagCount uint32
|
||||
// CacheSize uint32
|
||||
OutputSize uint32 // Maximum size of output from a single rendered page
|
||||
}
|
||||
|
||||
// Engine is an execution engine that handles top-level errors when running user inputs against currently exposed bytecode.
|
||||
// Engine is an execution engine that handles top-level errors when running client inputs against code in the bytecode buffer.
|
||||
type Engine struct {
|
||||
st *state.State
|
||||
rs resource.Resource
|
||||
|
@ -2,7 +2,6 @@ package engine
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
// "bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
@ -10,17 +9,26 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Loop starts an engine execution loop with the given symbol as the starting node.
|
||||
//
|
||||
// The root reads inputs from the provided reader, one line at a time.
|
||||
//
|
||||
// It will execute until running out of bytecode in the buffer.
|
||||
//
|
||||
// Any error not handled by the engine will terminate the oop and return an error.
|
||||
//
|
||||
// Rendered output is written to the provided writer.
|
||||
func Loop(en *Engine, startSym string, ctx context.Context, reader io.Reader, writer io.Writer) error {
|
||||
err := en.Init(startSym, ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot init: %v\n", err)
|
||||
}
|
||||
|
||||
//b := bytes.NewBuffer(nil)
|
||||
//en.WriteResult(b, ctx)
|
||||
en.WriteResult(writer, ctx)
|
||||
err = en.WriteResult(writer, ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
writer.Write([]byte{0x0a})
|
||||
//fmt.Println(b.String())
|
||||
|
||||
running := true
|
||||
bufReader := bufio.NewReader(reader)
|
||||
|
@ -4,11 +4,13 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// BrowseError is raised when browsing outside the page range of a rendered node.
|
||||
type BrowseError struct {
|
||||
Idx uint16
|
||||
PageCount uint16
|
||||
}
|
||||
|
||||
// Error implements the Error interface.
|
||||
func(err *BrowseError) Error() string {
|
||||
return fmt.Sprintf("index is out of bounds: %v", err.Idx)
|
||||
}
|
||||
@ -35,13 +37,14 @@ func DefaultBrowseConfig() BrowseConfig {
|
||||
}
|
||||
}
|
||||
|
||||
// Menu renders menus. May be included in a Page object to render menus for pages.
|
||||
type Menu struct {
|
||||
menu [][2]string
|
||||
browse BrowseConfig
|
||||
pageCount uint16
|
||||
canNext bool
|
||||
canPrevious bool
|
||||
outputSize uint16
|
||||
menu [][2]string // selector and title for menu items.
|
||||
browse BrowseConfig // browse definitions.
|
||||
pageCount uint16 // number of pages the menu should represent.
|
||||
canNext bool // availability flag for the "next" browse option.
|
||||
canPrevious bool // availability flag for the "previous" browse option.
|
||||
outputSize uint16 // maximum size constraint for the menu.
|
||||
}
|
||||
|
||||
// NewMenu creates a new Menu with an explicit page count.
|
||||
@ -83,6 +86,11 @@ func(m *Menu) Put(selector string, title string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReservedSize returns the maximum render byte size of the menu.
|
||||
func(m *Menu) ReservedSize() uint16 {
|
||||
return m.outputSize
|
||||
}
|
||||
|
||||
// Render returns the full current state of the menu as a string.
|
||||
//
|
||||
// After this has been executed, the state of the menu will be empty.
|
||||
@ -160,6 +168,7 @@ func(m *Menu) shiftMenu() (string, string, error) {
|
||||
return r[0], r[1], nil
|
||||
}
|
||||
|
||||
// prepare menu object for re-use.
|
||||
func(m *Menu) reset() {
|
||||
if m.browse.NextAvailable {
|
||||
m.canNext = true
|
||||
@ -170,6 +179,3 @@ func(m *Menu) reset() {
|
||||
}
|
||||
|
||||
|
||||
func(m *Menu) ReservedSize() uint16 {
|
||||
return m.outputSize
|
||||
}
|
||||
|
@ -11,16 +11,17 @@ import (
|
||||
"git.defalsify.org/festive/resource"
|
||||
)
|
||||
|
||||
// Page exectues output rendering into pages constrained by size.
|
||||
type Page struct {
|
||||
cacheMap map[string]string // Mapped
|
||||
cache cache.Memory
|
||||
resource resource.Resource
|
||||
menu *Menu
|
||||
sink *string
|
||||
sinkSize uint16
|
||||
sizer *Sizer
|
||||
cacheMap map[string]string // Mapped content symbols
|
||||
cache cache.Memory // Content store.
|
||||
resource resource.Resource // Symbol resolver.
|
||||
menu *Menu // Menu rendererer.
|
||||
sink *string // Content symbol rendered by dynamic size.
|
||||
sizer *Sizer // Process size constraints.
|
||||
}
|
||||
|
||||
// NewPage creates a new Page object.
|
||||
func NewPage(cache cache.Memory, rs resource.Resource) *Page {
|
||||
return &Page{
|
||||
cache: cache,
|
||||
@ -29,6 +30,7 @@ func NewPage(cache cache.Memory, rs resource.Resource) *Page {
|
||||
}
|
||||
}
|
||||
|
||||
// WithMenu sets a menu renderer for the page.
|
||||
func(pg *Page) WithMenu(menu *Menu) *Page {
|
||||
pg.menu = menu
|
||||
if pg.sizer != nil {
|
||||
@ -37,6 +39,7 @@ func(pg *Page) WithMenu(menu *Menu) *Page {
|
||||
return pg
|
||||
}
|
||||
|
||||
// WithSizer sets a size constraints definition for the page.
|
||||
func(pg *Page) WithSizer(sizer *Sizer) *Page {
|
||||
pg.sizer = sizer
|
||||
if pg.menu != nil {
|
||||
@ -45,7 +48,7 @@ func(pg *Page) WithSizer(sizer *Sizer) *Page {
|
||||
return pg
|
||||
}
|
||||
|
||||
// Size returns size used by values and menu, and remaining size available
|
||||
// Usage returns size used by values and menu, and remaining size available
|
||||
func(pg *Page) Usage() (uint32, uint32, error) {
|
||||
var l int
|
||||
var c uint16
|
||||
@ -97,6 +100,8 @@ func(pg *Page) Map(key string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Val gets the mapped content for the given symbol.
|
||||
//
|
||||
// Fails if key is not mapped.
|
||||
func(pg *Page) Val(key string) (string, error) {
|
||||
r := pg.cacheMap[key]
|
||||
@ -106,7 +111,7 @@ func(pg *Page) Val(key string) (string, error) {
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// Moved from cache, MAP should hook to this object
|
||||
// Sizes returned the actual used bytes by each mapped symbol.
|
||||
func(pg *Page) Sizes() (map[string]uint16, error) {
|
||||
sizes := make(map[string]uint16)
|
||||
var haveSink bool
|
||||
@ -121,12 +126,11 @@ func(pg *Page) Sizes() (map[string]uint16, error) {
|
||||
}
|
||||
haveSink = true
|
||||
}
|
||||
pg.sinkSize = l
|
||||
}
|
||||
return sizes, nil
|
||||
}
|
||||
|
||||
// DefaultRenderTemplate is an adapter to implement the builtin golang text template renderer as resource.RenderTemplate.
|
||||
// RenderTemplate is an adapter to implement the builtin golang text template renderer as resource.RenderTemplate.
|
||||
func(pg *Page) RenderTemplate(sym string, values map[string]string, idx uint16) (string, error) {
|
||||
tpl, err := pg.resource.GetTemplate(sym)
|
||||
if err != nil {
|
||||
@ -156,6 +160,26 @@ func(pg *Page) RenderTemplate(sym string, values map[string]string, idx uint16)
|
||||
return b.String(), err
|
||||
}
|
||||
|
||||
// Render renders the current mapped content and menu state against the template associated with the symbol.
|
||||
func(pg *Page) Render(sym string, idx uint16) (string, error) {
|
||||
var err error
|
||||
|
||||
values, err := pg.prepare(sym, pg.cacheMap, idx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return pg.render(sym, values, idx)
|
||||
}
|
||||
|
||||
// Reset prepared the Page object for re-use.
|
||||
//
|
||||
// It clears mappings and removes the sink definition.
|
||||
func(pg *Page) Reset() {
|
||||
pg.sink = nil
|
||||
pg.cacheMap = make(map[string]string)
|
||||
}
|
||||
|
||||
// render menu and all syms except sink, split sink into display chunks
|
||||
// TODO: Function too long, split up
|
||||
func(pg *Page) prepare(sym string, values map[string]string, idx uint16) (map[string]string, error) {
|
||||
@ -279,6 +303,7 @@ func(pg *Page) prepare(sym string, values map[string]string, idx uint16) (map[st
|
||||
return noSinkValues, nil
|
||||
}
|
||||
|
||||
// render template, menu (if it exists), and audit size constraint (if it exists).
|
||||
func(pg *Page) render(sym string, values map[string]string, idx uint16) (string, error) {
|
||||
var ok bool
|
||||
r := ""
|
||||
@ -309,19 +334,3 @@ func(pg *Page) render(sym string, values map[string]string, idx uint16) (string,
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func(pg *Page) Render(sym string, idx uint16) (string, error) {
|
||||
var err error
|
||||
|
||||
values, err := pg.prepare(sym, pg.cacheMap, idx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return pg.render(sym, values, idx)
|
||||
}
|
||||
|
||||
func(pg *Page) Reset() {
|
||||
pg.sink = nil
|
||||
pg.sinkSize = 0
|
||||
pg.cacheMap = make(map[string]string)
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
package render
|
@ -7,15 +7,17 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Sizer splits dynamic contents into individual segments for browseable pages.
|
||||
type Sizer struct {
|
||||
outputSize uint32
|
||||
menuSize uint16
|
||||
memberSizes map[string]uint16
|
||||
totalMemberSize uint32
|
||||
crsrs []uint32
|
||||
sink string
|
||||
outputSize uint32 // maximum output for a single page.
|
||||
menuSize uint16 // actual menu size for the dynamic page being sized
|
||||
memberSizes map[string]uint16 // individual byte sizes of all content to be rendered by template.
|
||||
totalMemberSize uint32 // total byte size of all content to be rendered by template (sum of memberSizes)
|
||||
crsrs []uint32 // byte offsets in the sink content for browseable pages indices.
|
||||
sink string // sink symbol.
|
||||
}
|
||||
|
||||
// NewSizer creates a new Sizer object with the given output size constraint.
|
||||
func NewSizer(outputSize uint32) *Sizer {
|
||||
return &Sizer{
|
||||
outputSize: outputSize,
|
||||
@ -23,11 +25,13 @@ func NewSizer(outputSize uint32) *Sizer {
|
||||
}
|
||||
}
|
||||
|
||||
// WithMenuSize sets the size of the menu being used in the rendering context.
|
||||
func(szr *Sizer) WithMenuSize(menuSize uint16) *Sizer {
|
||||
szr.menuSize = menuSize
|
||||
return szr
|
||||
}
|
||||
|
||||
// Set adds a content symbol in the state it will be used by the renderer.
|
||||
func(szr *Sizer) Set(key string, size uint16) error {
|
||||
szr.memberSizes[key] = size
|
||||
if size == 0 {
|
||||
@ -37,6 +41,7 @@ func(szr *Sizer) Set(key string, size uint16) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check audits whether the rendered string is within the output size constraint of the sizer.
|
||||
func(szr *Sizer) Check(s string) (uint32, bool) {
|
||||
l := uint32(len(s))
|
||||
if szr.outputSize > 0 {
|
||||
@ -49,6 +54,7 @@ func(szr *Sizer) Check(s string) (uint32, bool) {
|
||||
return l, true
|
||||
}
|
||||
|
||||
// String implements the String interface.
|
||||
func(szr *Sizer) String() string {
|
||||
var diff uint32
|
||||
if szr.outputSize > 0 {
|
||||
@ -57,6 +63,9 @@ func(szr *Sizer) String() string {
|
||||
return fmt.Sprintf("output: %v, member: %v, menu: %v, diff: %v", szr.outputSize, szr.totalMemberSize, szr.menuSize, diff)
|
||||
}
|
||||
|
||||
// Size gives the byte size of content for a single symbol.
|
||||
//
|
||||
// Fails if the symbol has not been registered using Set
|
||||
func(szr *Sizer) Size(s string) (uint16, error) {
|
||||
r, ok := szr.memberSizes[s]
|
||||
if !ok {
|
||||
@ -65,15 +74,20 @@ func(szr *Sizer) Size(s string) (uint16, error) {
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// Menusize returns the currently defined menu size.
|
||||
func(szr *Sizer) MenuSize() uint16 {
|
||||
return szr.menuSize
|
||||
}
|
||||
|
||||
// AddCursor adds a pagination cursor for the paged sink content.
|
||||
func(szr *Sizer) AddCursor(c uint32) {
|
||||
log.Printf("added cursor: %v", c)
|
||||
szr.crsrs = append(szr.crsrs, c)
|
||||
}
|
||||
|
||||
// GetAt the paged symbols for the current page index.
|
||||
//
|
||||
// Fails if index requested is out of range.
|
||||
func(szr *Sizer) GetAt(values map[string]string, idx uint16) (map[string]string, error) {
|
||||
if szr.sink == "" {
|
||||
return values, nil
|
||||
|
10
go/testdata/testdata.go
vendored
10
go/testdata/testdata.go
vendored
@ -72,7 +72,6 @@ func foo() error {
|
||||
b = vm.NewLine(b, vm.INCMP, []string{"0", "_"}, nil, nil)
|
||||
b = vm.NewLine(b, vm.INCMP, []string{"1", "baz"}, nil, nil)
|
||||
b = vm.NewLine(b, vm.INCMP, []string{"2", "long"}, nil, nil)
|
||||
//b = vm.NewLine(b, vm.CATCH, []string{"_catch"}, []byte{1}, []uint8{1})
|
||||
|
||||
data := make(map[string]string)
|
||||
data["inky"] = "one"
|
||||
@ -164,6 +163,9 @@ func generate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Generate outputs bytecode, templates and content symbols to a temporary directory.
|
||||
//
|
||||
// This directory can in turn be used as data source for the the resource.FsResource object.
|
||||
func Generate() (string, error) {
|
||||
dir, err := ioutil.TempDir("", "festive_testdata_")
|
||||
if err != nil {
|
||||
@ -175,6 +177,12 @@ func Generate() (string, error) {
|
||||
return dir, err
|
||||
}
|
||||
|
||||
|
||||
// Generate outputs bytecode, templates and content symbols to a specified directory.
|
||||
//
|
||||
// The directory must exist, and must not have been used already in the same code execution.
|
||||
//
|
||||
// This directory can in turn be used as data source for the the resource.FsResource object.
|
||||
func GenerateTo(dir string) error {
|
||||
if dirLock {
|
||||
return fmt.Errorf("directory already overridden")
|
||||
|
@ -11,16 +11,17 @@ import (
|
||||
"git.defalsify.org/festive/state"
|
||||
)
|
||||
|
||||
// Vm holds sub-components mutated by the vm execution.
|
||||
type Vm struct {
|
||||
st *state.State
|
||||
rs resource.Resource
|
||||
pg *render.Page
|
||||
ca cache.Memory
|
||||
mn *render.Menu
|
||||
sizer *render.Sizer
|
||||
st *state.State // Navigation and error states.
|
||||
rs resource.Resource // Retrieves content, code, and templates for symbols.
|
||||
ca cache.Memory // Loaded content.
|
||||
mn *render.Menu // Menu component of page.
|
||||
sizer *render.Sizer // Apply size constraints to output.
|
||||
pg *render.Page // Render outputs with menues to size constraints.
|
||||
}
|
||||
|
||||
|
||||
// NewVm creates a new Vm.
|
||||
func NewVm(st *state.State, rs resource.Resource, ca cache.Memory, sizer *render.Sizer) *Vm {
|
||||
vmi := &Vm{
|
||||
st: st,
|
||||
@ -33,17 +34,16 @@ func NewVm(st *state.State, rs resource.Resource, ca cache.Memory, sizer *render
|
||||
return vmi
|
||||
}
|
||||
|
||||
// Reset re-initializes sub-components for output rendering.
|
||||
func(vmi *Vm) Reset() {
|
||||
vmi.mn = render.NewMenu()
|
||||
vmi.pg.Reset()
|
||||
vmi.pg = vmi.pg.WithMenu(vmi.mn) //render.NewPage(vmi.ca, vmi.rs).WithMenu(vmi.mn)
|
||||
vmi.pg = vmi.pg.WithMenu(vmi.mn)
|
||||
if vmi.sizer != nil {
|
||||
vmi.pg = vmi.pg.WithSizer(vmi.sizer)
|
||||
}
|
||||
}
|
||||
|
||||
//type Runner func(instruction []byte, st state.State, rs resource.Resource, ctx context.Context) (state.State, []byte, error)
|
||||
|
||||
// Run extracts individual op codes and arguments and executes them.
|
||||
//
|
||||
// Each step may update the state.
|
||||
@ -394,6 +394,7 @@ func(vm *Vm) RunMPrev(b []byte, ctx context.Context) ([]byte, error) {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// Render wraps output rendering, and handles error when attempting to browse beyond the rendered page count.
|
||||
func(vm *Vm) Render(ctx context.Context) (string, error) {
|
||||
changed, err := vm.st.ResetFlag(state.FLAG_DIRTY)
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user