travelpath.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package main
  2. import (
  3. "fmt"
  4. "github.com/beanzilla/gonode"
  5. "golang.org/x/exp/slices"
  6. )
  7. type TravelPath struct {
  8. N_Path *gonode.Node `json:"-"`
  9. N_Destination *gonode.Node `json:"-"`
  10. Path []string `json:"path"`
  11. Destination string `json:"destination"`
  12. }
  13. func (t *TravelPath) String() string {
  14. result := ""
  15. for _, path := range t.Path {
  16. if result != "" {
  17. result += " > "
  18. }
  19. result += path
  20. }
  21. if result != "" {
  22. result += " >> "
  23. }
  24. result += t.Destination
  25. return result
  26. }
  27. func (t *TravelPath) Parse(n *gonode.Node) error {
  28. txt := fmt.Sprintf("%v", n.Data())
  29. switch Key(txt) {
  30. case "playtime":
  31. if !n.HasTag("insert", "travel") {
  32. n.AddTag("insert", "travel")
  33. }
  34. case "travel":
  35. if t.N_Path == nil {
  36. t.N_Path = n.Parent()
  37. }
  38. t.Path = append(t.Path, Value(txt))
  39. if !n.HasTag("replace", "travel") {
  40. n.AddTag("replace", "travel")
  41. }
  42. case "travel destination":
  43. t.N_Destination = n
  44. t.Destination = Value(txt)
  45. }
  46. return nil
  47. }
  48. func (t *TravelPath) Update() error {
  49. if t.N_Path == nil {
  50. return fmt.Errorf("missing node(s), can't update")
  51. }
  52. replaced := false
  53. // Replace nodes we've seen before (this takes care of if we didn't really change anything)
  54. // Problems: New items, less items
  55. for _, path := range t.Path {
  56. replaced = false
  57. idx := 0
  58. FIND_A_NODE:
  59. for kid := range t.N_Path.Iter() {
  60. if kid.HasTag("replace", "travel") {
  61. kid.SetData(fmt.Sprintf("travel %s", Format(path)))
  62. kid.RmTag("replace", "travel")
  63. replaced = true
  64. break FIND_A_NODE
  65. }
  66. idx += 1
  67. }
  68. if !replaced {
  69. t.N_Path.NewChildWithData(fmt.Sprintf("travel %s", Format(path)))
  70. }
  71. }
  72. // Cleanup less items (this will remove old/stale stuff)
  73. idxs := []int{}
  74. idx := 0
  75. for idx != -1 {
  76. idx = t.N_Path.ChildIndexByTag("replace", "travel")
  77. if !slices.Contains(idxs, idx) {
  78. idxs = append(idxs, idx)
  79. } else {
  80. break
  81. }
  82. }
  83. t.N_Path.RmChild(idxs...)
  84. // Update the destination
  85. if t.Destination != "" && t.N_Destination != nil {
  86. // We have a destination and a node for it
  87. t.N_Destination.SetData(fmt.Sprintf("%s %s", Format("travel destination"), Format(t.Destination)))
  88. } else if t.Destination == "" && t.N_Destination != nil {
  89. // We have no destination but a node
  90. t.N_Destination.Detach()
  91. t.N_Destination.Destroy()
  92. } else if t.Destination != "" && t.N_Destination == nil {
  93. // We have a destination but no node for it
  94. t.N_Path.NewChildWithData(fmt.Sprintf("%s %s", Format("travel destination"), Format(t.Destination)))
  95. }
  96. return nil
  97. }