go-vise

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

main.go (2881B)


      1 // Example: Asynchronous state persistence.
      2 //
      3 // TODO: this example is broken after change to loop
      4 package main
      5 
      6 import (
      7 	"context"
      8 	"flag"
      9 	"fmt"
     10 	"io/ioutil"
     11 	"os"
     12 	"path"
     13 
     14 	"git.defalsify.org/vise.git/resource"
     15 	"git.defalsify.org/vise.git/state"
     16 	"git.defalsify.org/vise.git/engine"
     17 	"git.defalsify.org/vise.git/persist"
     18 	"git.defalsify.org/vise.git/logging"
     19 	fsdb "git.defalsify.org/vise.git/db/fs"
     20 )
     21 
     22 const (
     23 	USERFLAG_ONE = iota + state.FLAG_USERSTART
     24 	USERFLAG_TWO
     25 	USERFLAG_THREE
     26 	USERFLAG_DONE
     27 )
     28 
     29 var (
     30 	logg = logging.NewVanilla()
     31 )
     32 
     33 type fsData struct {
     34 	path string
     35 	persister *persist.Persister
     36 }
     37 
     38 func (fsd *fsData) peek(ctx context.Context, sym string, input []byte) (resource.Result, error) {
     39 	res := resource.Result{}
     40 	fp := fsd.path + "_data"
     41 	f, err := os.Open(fp)
     42 	if err != nil {
     43 		return res, err
     44 	}
     45 	r, err := ioutil.ReadAll(f)
     46 	if err != nil {
     47 		return res, err
     48 	}
     49 	res.Content = string(r)
     50 	return res, nil
     51 }
     52 
     53 func (fsd *fsData) poke(ctx context.Context, sym string, input []byte) (resource.Result, error) {
     54 	res := resource.Result{}
     55 	fp := fsd.path + "_data"
     56 	f, err := os.OpenFile(fp, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
     57 	if err != nil {
     58 		return res, err
     59 	}
     60 	f.Write([]byte("*"))
     61 	f.Close()
     62 
     63 	st := fsd.persister.GetState()
     64 	for i := 8; i < 12; i++ {
     65 		v := uint32(i)
     66 		logg.DebugCtxf(ctx, "checking flag", "flag", v)
     67 		if st.MatchFlag(v, true) {
     68 			logg.DebugCtxf(ctx, "match on flag", "flag", v)
     69 			res.FlagReset = append(res.FlagReset, v)
     70 			res.FlagSet = append(res.FlagSet, v + 1)
     71 			break
     72 		}
     73 	}
     74 	if len(res.FlagSet) == 0 {
     75 		res.FlagSet = append(res.FlagSet, 8)
     76 	}
     77 	return res, nil
     78 }
     79 
     80 func main() {
     81 	var dir string
     82 	var root string
     83 	var size uint
     84 	var sessionId string
     85 	flag.StringVar(&dir, "d", ".", "resource dir to read from")
     86 	flag.UintVar(&size, "s", 0, "max size of output")
     87 	flag.StringVar(&root, "root", "root", "entry point symbol")
     88 	flag.StringVar(&sessionId, "session-id", "default", "session id")
     89 	flag.Parse()
     90 	fmt.Fprintf(os.Stderr, "starting session at symbol '%s' using resource dir: %s\n", root, dir)
     91 
     92 	ctx := context.Background()
     93 	rsStore := fsdb.NewFsDb()
     94 	err := rsStore.Connect(ctx, dir)
     95 	if err != nil {
     96 		panic(err)
     97 	}
     98 	rs := resource.NewDbResource(rsStore)
     99 	cfg := engine.Config{
    100 		Root: "root",
    101 		SessionId: sessionId,
    102 		FlagCount: 4,
    103 	}
    104 
    105 	dp := path.Join(dir, ".state")
    106 	store := fsdb.NewFsDb()
    107 	err = store.Connect(ctx, dp)
    108 	if err != nil {
    109 		fmt.Fprintf(os.Stderr, "db connect fail: %s", err)
    110 		os.Exit(1)
    111 	}
    112 	pr := persist.NewPersister(store)
    113 
    114 	en := engine.NewEngine(cfg, rs)
    115 	en = en.WithPersister(pr)
    116 
    117 	fp := path.Join(dp, sessionId)
    118 	aux := &fsData{
    119 		path: fp,
    120 		persister: pr,
    121 	}
    122 	rs.AddLocalFunc("poke", aux.poke)
    123 	rs.AddLocalFunc("peek", aux.peek)
    124 
    125 	err = engine.Loop(ctx, en, os.Stdin, os.Stdout, nil)
    126 	if err != nil {
    127 		fmt.Fprintf(os.Stderr, "loop exited with error: %v\n", err)
    128 		os.Exit(1)
    129 	}
    130 }