203 lines
5.1 KiB
V
203 lines
5.1 KiB
V
module playbook
|
|
|
|
import freeflowuniverse.herolib.core.base
|
|
import freeflowuniverse.herolib.core.texttools
|
|
import freeflowuniverse.herolib.data.paramsparser
|
|
import crypto.blake2b
|
|
|
|
@[heap]
|
|
pub struct PlayBook {
|
|
pub mut:
|
|
actions []&Action
|
|
priorities map[int][]int // first key is the priority, the list of int's is position in list self.actions
|
|
othertext string // in case there is text outside of the actions
|
|
result string // if any result
|
|
nractions int
|
|
done []int // which actions did we already find/run?
|
|
session &base.Session
|
|
}
|
|
|
|
@[params]
|
|
pub struct ActionNewArgs {
|
|
pub mut:
|
|
cid string
|
|
name string
|
|
actor string
|
|
priority int = 10 // 0 is highest, do 10 as default
|
|
// run bool = true // certain actions can be defined but meant to be executed directly
|
|
actiontype ActionType
|
|
}
|
|
|
|
// add action to the book
|
|
fn (mut plbook PlayBook) action_new(args ActionNewArgs) &Action {
|
|
plbook.nractions += 1
|
|
mut a := Action{
|
|
id: plbook.nractions
|
|
cid: args.cid
|
|
name: args.name
|
|
actor: args.actor
|
|
priority: args.priority
|
|
// run: args.run
|
|
actiontype: args.actiontype
|
|
params: paramsparser.Params{}
|
|
result: paramsparser.Params{}
|
|
}
|
|
plbook.actions << &a
|
|
return &a
|
|
}
|
|
|
|
pub fn (mut plbook PlayBook) str() string {
|
|
return plbook.heroscript() or { 'Cannot visualize playbook properly.\n${plbook.actions}' }
|
|
}
|
|
|
|
@[params]
|
|
pub struct SortArgs {
|
|
pub mut:
|
|
prio_only bool // if true only show the actions which were prioritized before
|
|
}
|
|
|
|
// only return the actions which are not done yet
|
|
// if filtered is set, it means we only get the ones which were prioritized before
|
|
pub fn (mut plbook PlayBook) actions_sorted(args SortArgs) ![]&Action {
|
|
mut res := []&Action{}
|
|
mut nrs := plbook.priorities.keys()
|
|
nrs.sort()
|
|
if nrs.len == 0 {
|
|
// means sorting did not happen before
|
|
return plbook.actions
|
|
}
|
|
for nr in nrs {
|
|
if args.prio_only && nr > 49 {
|
|
continue
|
|
}
|
|
action_ids := plbook.priorities[nr] or { panic('bug') }
|
|
for id in action_ids {
|
|
mut a := plbook.action_get(id: id)!
|
|
res << a
|
|
}
|
|
}
|
|
return res
|
|
}
|
|
|
|
@[params]
|
|
pub struct HeroScriptArgs {
|
|
pub mut:
|
|
show_done bool = true
|
|
}
|
|
|
|
// serialize to heroscript
|
|
pub fn (mut plbook PlayBook) heroscript(args HeroScriptArgs) !string {
|
|
mut out := ''
|
|
for action in plbook.actions_sorted()! {
|
|
if args.show_done == false && action.done {
|
|
continue
|
|
}
|
|
out += '${action.heroscript()}\n'
|
|
}
|
|
if plbook.othertext.len > 0 {
|
|
out += '${plbook.othertext}'
|
|
}
|
|
out = texttools.remove_empty_js_blocks(out)
|
|
return out
|
|
}
|
|
|
|
// return list of names .
|
|
// the names are normalized (no special chars, lowercase, ... )
|
|
pub fn (mut plbook PlayBook) names() ![]string {
|
|
mut names := []string{}
|
|
for action in plbook.actions_sorted()! {
|
|
names << action.name
|
|
}
|
|
return names
|
|
}
|
|
|
|
@[params]
|
|
pub struct ActionGetArgs {
|
|
pub mut:
|
|
id int
|
|
actor string
|
|
name string
|
|
actiontype ActionType = .sal
|
|
}
|
|
|
|
// Find all actions based on ActionGetArgs
|
|
// - If id == 0, then matches all ids; when id is specified, can only return 1.
|
|
// - If actor == "", then matches all actors.
|
|
// - If name == "", then matches all actions from the defined actor (if defined).
|
|
// - If actiontype == .unknown, then matches all action types; when specified, filters by the action type, default .sal
|
|
pub fn (mut plbook PlayBook) actions_find(args ActionGetArgs) ![]&Action {
|
|
mut res := []&Action{}
|
|
for a in plbook.actions {
|
|
// If id is specified, return only the action with that id
|
|
if args.id != 0 {
|
|
if a.id == args.id {
|
|
return [a]
|
|
}
|
|
continue
|
|
}
|
|
// Filter by actor if specified
|
|
if args.actor.len > 0 && a.actor != args.actor {
|
|
continue
|
|
}
|
|
// Filter by name if specified
|
|
if args.name.len > 0 && a.name != args.name {
|
|
continue
|
|
}
|
|
// Filter by actiontype if specified
|
|
if args.actiontype != .unknown && a.actiontype != args.actiontype {
|
|
continue
|
|
}
|
|
// If the action passes all filters, add it to the result
|
|
res << a
|
|
}
|
|
return res
|
|
}
|
|
|
|
pub fn (mut plbook PlayBook) action_exists(args ActionGetArgs) bool {
|
|
// Use actions_find to get the filtered actions
|
|
actions := plbook.actions_find(args) or { return false }
|
|
if actions.len == 1 {
|
|
return true
|
|
} else if actions.len == 0 {
|
|
return false
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
|
|
pub fn (mut plbook PlayBook) action_get(args ActionGetArgs) !&Action {
|
|
// Use actions_find to get the filtered actions
|
|
actions := plbook.actions_find(args)!
|
|
if actions.len == 1 {
|
|
return actions[0]
|
|
} else if actions.len == 0 {
|
|
return error("couldn't find action with args: ${args}")
|
|
} else {
|
|
return error('multiple actions found with args: ${args}, expected only one')
|
|
}
|
|
}
|
|
|
|
pub fn (plbook PlayBook) hashkey() string {
|
|
mut out := []string{}
|
|
for action in plbook.actions {
|
|
out << action.hashkey()
|
|
}
|
|
txt := out.join_lines()
|
|
bs := blake2b.sum160(txt.bytes())
|
|
return bs.hex()
|
|
}
|
|
|
|
// check if playbook is empty,if not will give error, means there are actions left to be exected
|
|
pub fn (mut plbook PlayBook) empty_check() ! {
|
|
mut actions := []&Action{}
|
|
for a in plbook.actions {
|
|
if a.done == false {
|
|
actions << a
|
|
}
|
|
}
|
|
if actions.len > 0 {
|
|
msg := plbook.heroscript(show_done: false)!
|
|
return error('There are actions left to execute, see below:\n\n${msg}\n\n')
|
|
}
|
|
}
|