go-vise

Constrained Size Output Virtual Machine
Info | Log | Files | Refs | README | LICENSE

sim.texi (5967B)


      1 @node sim
      2 @chapter An example vise implementation
      3 
      4 
      5 Consider the following interaction:
      6 
      7 @example
      8 This is the root page
      9 You have visited 1 time.
     10 0:foo
     11 1:bar
     12 
     13 $ 1
     14 Please visit foo first.
     15 Any input to return.
     16 
     17 $ x
     18 This is the root page.
     19 You have visited 2 times.
     20 0:foo
     21 1:bar
     22 
     23 $ 0
     24 Welcome to page foo.
     25 Please write seomthing.
     26 
     27 $ blah blah blah
     28 This is the root page.
     29 You have visited 3 times.
     30 0:foo
     31 1:bar
     32 
     33 $ 1
     34 Thanks for visiting foo and bar.
     35 You have written:
     36 blah blah blah
     37 @end example
     38 
     39 The simple interface above involves four different menu nodes.
     40 
     41 In order to engineer these using vise, three types of components are involved:
     42 
     43 @itemize
     44 @item An assembly-like menu handling script.
     45 @item A display template.
     46 @item External code handlers for the counter and the "something" input.
     47 @end itemize
     48 
     49 
     50 
     51 The nodes are:
     52 
     53 @table @code
     54 @item root
     55 The first page.
     56 @item foo
     57 The "foo" page.
     58 @item bar
     59 The "bar" page after "foo" has been visited.
     60 @item ouch
     61 The "bar" page before "foo" has been visited.
     62 @end table
     63 
     64 
     65 @section Templates
     66 
     67 Each page has a template that may or may not contain dynamic elements.
     68 
     69 In this example the @code{root} and @code{bar} nodes contains dynamic content.
     70 
     71 @subsection root
     72 
     73 @verbatim
     74 This is the root page
     75 You have visited {{.count}}.
     76 @end verbatim
     77 
     78 @subsection foo
     79 
     80 @verbatim
     81 Welcome to page foo.
     82 Please write something.
     83 @end verbatim
     84 
     85 @subsection bar
     86 
     87 @verbatim
     88 Thanks for visiting foo and bar.
     89 You wrote "{{.something}}" in foo.
     90 @end verbatim
     91 
     92 @subsection ouch
     93 
     94 @verbatim
     95 Please visit foo first.
     96 Any input to return.
     97 @end verbatim
     98 
     99 
    100 @section Scripts
    101 
    102 The scripts are responsible for defining menus, handling navigation flow control, and triggering external code handlers.
    103 
    104 @subsection root
    105 
    106 @verbatim
    107 LOAD count 8 		# trigger external code handler "count"
    108 LOAD something 0	# trigger external code handler "something"
    109 RELOAD count		# explicitly trigger "count" every time this code is executed.
    110 MAP count		# make the result from "count" available to the template renderer
    111 MOUT foo 0		# menu item
    112 MOUT bar 1		# menu item
    113 HALT			# render template and wait for input
    114 INCMP foo 0		# match menu selection 0, move to node "foo" on match
    115 INCMP bar 1		# match menu selection 1, move to node "bar" on match
    116 @end verbatim
    117 
    118 @subsection foo
    119 
    120 @verbatim
    121 HALT			# render template and wait for input
    122 RELOAD something    	# pass input to the "something" external code handler.
    123                     	# The input will be appended to the stored value. 
    124                     	# The "HAVESOMETHING" flag (8) will be set.
    125 MOVE _			# move up one level
    126 @end verbatim
    127 
    128 
    129 @subsection bar
    130 
    131 @verbatim
    132 CATCH ouch 8 0      	# if the "HAVESOMETHING" (8) flag has NOT (0) been set, move to "ouch"
    133 MNEXT next 11       	# menu choice to display for advancing one page
    134 MPREV back 22       	# menu choice to display for going back to the previous page
    135 MAP something       	# make the result from "something" available to the template renderer
    136 HALT                	# render template and wait for input
    137 INCMP > 11          	# handle the "next" menu choice
    138 INCMP < 22          	# handle to "back" menu choice
    139 INCMP _ *           	# move to the root node on any input
    140 @end verbatim
    141 
    142 
    143 @subsection ouch
    144 
    145 @verbatim
    146 HALT			# render template and wait for input
    147 INCMP ^ *		# move to the root node on any input
    148 @end verbatim
    149 
    150 
    151 @section External code handlers
    152 
    153 The script code contains @code{LOAD} instructions for two different methods. 
    154 
    155 @verbatim
    156 import (
    157 	"context"
    158 	"fmt"
    159 	"path"
    160 	"strings"
    161 
    162 
    163 	testdataloader "github.com/peteole/testdata-loader"
    164 
    165 	"git.defalsify.org/vise.git/state"
    166 	"git.defalsify.org/vise.git/resource"
    167 )
    168 
    169 const (
    170 	USERFLAG_HAVESOMETHING = iota + state.FLAG_USERSTART
    171 )
    172 
    173 var (
    174 	baseDir = testdataloader.GetBasePath()
    175 	scriptDir = path.Join(baseDir, "examples", "intro")
    176 )
    177 
    178 type introResource struct {
    179 	*resource.FsResource 
    180 	c int64
    181 	v []string
    182 }
    183 
    184 func newintroResource() introResource {
    185 	fs := resource.NewFsResource(scriptDir)
    186 	return introResource{fs, 0, []string{}}
    187 }
    188 
    189 // increment counter.
    190 // return a string representing the current value of the counter.
    191 func(c *introResource) count(ctx context.Context, sym string, input []byte) (resource.Result, error) {
    192 	s := "%v time"
    193 	if c.c != 1 {
    194 		s += "s"
    195 	}
    196 	r := resource.Result{
    197 		Content: fmt.Sprintf(s, c.c),
    198 	}
    199 	c.c += 1 
    200 	return  r, nil
    201 }
    202 
    203 // if input is suppled, append it to the stored string vector and set the HAVESOMETHING flag.
    204 // return the stored string vector value, one string per line.
    205 func(c *introResource) something(ctx context.Context, sym string, input []byte) (resource.Result, error) {
    206 	c.v = append(c.v, string(input))
    207 	r := resource.Result{
    208 		Content: strings.Join(c.v, "\n"),
    209 	}
    210 	if len(input) > 0 {
    211 		r.FlagSet = []uint32{USERFLAG_HAVESOMETHING}
    212 	}
    213 	return r, nil
    214 }
    215 @end verbatim
    216 
    217 
    218 @anchor{long_values}
    219 @section Handling long values
    220 
    221 In the above example, the more times the @code{foo} page is supplied with a value, the longer the vector of values that need to be displayed by the @code{bar} page will be.
    222 
    223 A core feature of @code{vise} is to magically create browseable pages from these values, from a pre-defined maximum output capacity for each page. 
    224 
    225 Consider the case where the contents of the @code{something} symbol has become:
    226 
    227 @verbatim
    228 foo bar
    229 baz bazbaz
    230 inky pinky
    231 blinky
    232 clyde
    233 @end verbatim
    234 
    235 Given a size constaint of 90 characters, the display will be split into two pages:
    236 
    237 @verbatim
    238 Thanks for visiting foo and bar.
    239 You have written:
    240 foo bar
    241 baz bazbaz
    242 11:next
    243 @end verbatim
    244 
    245 @verbatim
    246 Thanks for visiting foo and bar.
    247 You have written:
    248 inky pinky
    249 blinky
    250 clyde
    251 22:back
    252 @end verbatim
    253 
    254 
    255 @section Working example
    256 
    257 In the source code repository, a full working example of this menu can be found in @file{examples/intro}.
    258 
    259 To run it:
    260 
    261 @example
    262 make -B intro
    263 go run ./examples/intro
    264 @end example
    265 
    266 Use @code{go run -tags logtrace ...} to peek at what is going on under the hood.
    267 
    268 To play the @ref{long_values, Long Values} case above, limit the output size by adding @code{-s 90}.