package main import ( "fmt" "github.com/beanzilla/gonode" "golang.org/x/exp/slices" ) type TravelPath struct { N_Path *gonode.Node `json:"-"` N_Destination *gonode.Node `json:"-"` Path []string `json:"path"` Destination string `json:"destination"` } func (t *TravelPath) String() string { result := "" for _, path := range t.Path { if result != "" { result += " > " } result += path } if result != "" { result += " >> " } result += t.Destination return result } func (t *TravelPath) Parse(n *gonode.Node) error { txt := fmt.Sprintf("%v", n.Data()) switch Key(txt) { case "playtime": if !n.HasTag("insert", "travel") { n.AddTag("insert", "travel") } case "travel": if t.N_Path == nil { t.N_Path = n.Parent() } t.Path = append(t.Path, Value(txt)) if !n.HasTag("replace", "travel") { n.AddTag("replace", "travel") } case "travel destination": t.N_Destination = n t.Destination = Value(txt) } return nil } func (t *TravelPath) Update() error { if t.N_Path == nil { return fmt.Errorf("missing node(s), can't update") } replaced := false // Replace nodes we've seen before (this takes care of if we didn't really change anything) // Problems: New items, less items for _, path := range t.Path { replaced = false idx := 0 FIND_A_NODE: for kid := range t.N_Path.Iter() { if kid.HasTag("replace", "travel") { kid.SetData(fmt.Sprintf("travel %s", Format(path))) kid.RmTag("replace", "travel") replaced = true break FIND_A_NODE } idx += 1 } if !replaced { t.N_Path.NewChildWithData(fmt.Sprintf("travel %s", Format(path))) } } // Cleanup less items (this will remove old/stale stuff) idxs := []int{} idx := 0 for idx != -1 { idx = t.N_Path.ChildIndexByTag("replace", "travel") if !slices.Contains(idxs, idx) { idxs = append(idxs, idx) } else { break } } t.N_Path.RmChild(idxs...) // Update the destination if t.Destination != "" && t.N_Destination != nil { // We have a destination and a node for it t.N_Destination.SetData(fmt.Sprintf("%s %s", Format("travel destination"), Format(t.Destination))) } else if t.Destination == "" && t.N_Destination != nil { // We have no destination but a node t.N_Destination.Detach() t.N_Destination.Destroy() } else if t.Destination != "" && t.N_Destination == nil { // We have a destination but no node for it t.N_Path.NewChildWithData(fmt.Sprintf("%s %s", Format("travel destination"), Format(t.Destination))) } return nil }