From 301dbb6b94b564543d3200ea8cac88063259e7a9 Mon Sep 17 00:00:00 2001 From: Noah Metz Date: Sat, 3 Jun 2023 02:45:16 -0600 Subject: [PATCH] Added Trace to signal so that nodes can discard based on direction --- event.go | 6 +++--- graph.go | 13 +++++++++++++ resource.go | 10 ++++++---- vex.go | 27 +++++++++++++++++++-------- vex_test.go | 34 +++++++++++++++++----------------- 5 files changed, 58 insertions(+), 32 deletions(-) diff --git a/event.go b/event.go index 585c9a5..330a9da 100644 --- a/event.go +++ b/event.go @@ -12,12 +12,12 @@ import ( // Update the events listeners, and notify the parent to do the same func (event * BaseEvent) update(signal GraphSignal) { event.signal <- signal - + new_signal := signal.Trace(event.ID()) if event.parent != nil && signal.Type() != "abort"{ - SendUpdate(event.parent, signal) + SendUpdate(event.parent, new_signal) } else if signal.Type() == "abort" { for _, child := range(event.Children()) { - SendUpdate(child, signal) + SendUpdate(child, new_signal) } } } diff --git a/graph.go b/graph.go index 15ce817..92febc1 100644 --- a/graph.go +++ b/graph.go @@ -18,6 +18,8 @@ type GraphSignal interface { Type() string Description() string Time() time.Time + Last() string + Trace(id string) GraphSignal } type BaseSignal struct { @@ -25,6 +27,7 @@ type BaseSignal struct { signal_type string description string time time.Time + last_id string } func (signal BaseSignal) Time() time.Time { @@ -43,6 +46,16 @@ func (signal BaseSignal) Description() string { return signal.description } +func (signal BaseSignal) Trace(id string) GraphSignal { + new_signal := signal + new_signal.last_id = id + return new_signal +} + +func (signal BaseSignal) Last() string { + return signal.last_id +} + func NewSignal(source GraphNode, signal_type string) (BaseSignal) { signal := BaseSignal{ source: source, diff --git a/resource.go b/resource.go index 653673c..350b8e2 100644 --- a/resource.go +++ b/resource.go @@ -9,19 +9,21 @@ import ( // Resources propagate update up to multiple parents, and not downwards // (subscriber to team won't get update to alliance, but subscriber to alliance will get update to team) func (resource * BaseResource) update(signal GraphSignal) { + new_signal := signal.Trace(resource.ID()) if signal.Type() == "lock_changed" { for _, child := range resource.Children() { - SendUpdate(child, signal) + SendUpdate(child, new_signal) } } else { for _, parent := range resource.Parents() { - SendUpdate(parent, signal) + SendUpdate(parent, new_signal) } if resource.lock_holder != nil { - SendUpdate(resource.lock_holder, signal) + if resource.lock_holder.ID() != signal.Last() { + SendUpdate(resource.lock_holder, new_signal) + } } } - } // Resource is the interface that DAG nodes are made from diff --git a/vex.go b/vex.go index 8aa207c..3aa313f 100644 --- a/vex.go +++ b/vex.go @@ -64,13 +64,6 @@ func NewAlliance(team0 * Team, team1 * Team) * Alliance { return resource } -type Match struct { - BaseEvent - state string - control string - control_start time.Time -} - type Arena struct { BaseResource connected bool @@ -96,8 +89,9 @@ func (arena * Arena) lock(event Event) error { func (arena * Arena) update(signal GraphSignal) { log.Printf("ARENA_UPDATE: %s", arena.Name()) - arena.BaseResource.update(signal) arena.signal <- signal + new_signal := signal.Trace(arena.ID()) + arena.BaseResource.update(new_signal) } func (arena * Arena) Connect(abort chan error) bool { @@ -147,6 +141,22 @@ const start_slack = 3000 * time.Millisecond const TEMP_AUTON_TIME = time.Second * 3 const TEMP_DRIVE_TIME = time.Second * 5 +type Match struct { + BaseEvent + arena * Arena + state string + control string + control_start time.Time +} + +func (match * Match) update(signal GraphSignal) { + new_signal := signal.Trace(match.ID()) + match.BaseEvent.update(new_signal) + if match.arena.ID() != signal.Last() { + SendUpdate(match.arena, new_signal) + } +} + func NewMatch(alliance0 * Alliance, alliance1 * Alliance, arena * Arena) * Match { name := fmt.Sprintf("Match: %s vs. %s on %s", alliance0.Name(), alliance1.Name(), arena.Name()) description := "A vex match" @@ -156,6 +166,7 @@ func NewMatch(alliance0 * Alliance, alliance1 * Alliance, arena * Arena) * Match state: "init", control: "init", control_start: time.UnixMilli(0), + arena: arena, } match.actions["start"] = func() (string, error) { diff --git a/vex_test.go b/vex_test.go index 9456f6b..2b99666 100644 --- a/vex_test.go +++ b/vex_test.go @@ -131,9 +131,9 @@ func TestNewMatch(t *testing.T) { alliance_2 := NewAlliance(team_3, team_4) arena := NewVirtualArena(arena_name) + arena_c := arena.UpdateChannel() match := NewMatch(alliance_1, alliance_2, arena) - match_c := match.UpdateChannel() root_event := NewEventQueue("root_event", "", []Resource{}) r := root_event.DoneResource() @@ -148,34 +148,34 @@ func TestNewMatch(t *testing.T) { } }() - go func(match_c chan GraphSignal) { - (*graph_tester)(t).WaitForValue(match_c, "event_start", 1*time.Second, "no event_start") - (*graph_tester)(t).CheckForNone(match_c, "update to match after starting") + go func(arena_c chan GraphSignal) { + (*graph_tester)(t).WaitForValue(arena_c, "event_start", 1*time.Second, "no event_start") + (*graph_tester)(t).CheckForNone(arena_c, "update to match after starting") SendUpdate(arena, NewSignal(nil, "queue_autonomous")) - (*graph_tester)(t).WaitForValue(match_c, "autonomous_queued", 1*time.Second, "no autonomous_queued") - (*graph_tester)(t).CheckForNone(match_c, "update to match after queueing autonomous") + (*graph_tester)(t).WaitForValue(arena_c, "autonomous_queued", 1*time.Second, "no autonomous_queued") + (*graph_tester)(t).CheckForNone(arena_c, "update to match after queueing autonomous") auton_signal := NewSignal(nil, "start_autonomous") auton_signal.time = time.Now() SendUpdate(arena, auton_signal) - (*graph_tester)(t).WaitForValue(match_c, "autonomous_running", 1*time.Second, "no autonomous_running") - (*graph_tester)(t).CheckForNone(match_c, "update to match after starting autonomous") + (*graph_tester)(t).WaitForValue(arena_c, "autonomous_running", 1*time.Second, "no autonomous_running") + (*graph_tester)(t).CheckForNone(arena_c, "update to match after starting autonomous") time.Sleep(TEMP_AUTON_TIME) time.Sleep(time.Millisecond * 100) - (*graph_tester)(t).WaitForValue(match_c, "autonomous_done", 6*time.Second, "no autonomous_done") - (*graph_tester)(t).CheckForNone(match_c, "update to match after ending autonomous") + (*graph_tester)(t).WaitForValue(arena_c, "autonomous_done", 6*time.Second, "no autonomous_done") + (*graph_tester)(t).CheckForNone(arena_c, "update to match after ending autonomous") SendUpdate(arena, NewSignal(nil, "queue_driver")) - (*graph_tester)(t).WaitForValue(match_c, "driver_queued", 1*time.Second, "no driver_queued") - (*graph_tester)(t).CheckForNone(match_c, "update to match after queueing driver") + (*graph_tester)(t).WaitForValue(arena_c, "driver_queued", 1*time.Second, "no driver_queued") + (*graph_tester)(t).CheckForNone(arena_c, "update to match after queueing driver") driver_signal := NewSignal(nil, "start_driver") driver_signal.time = time.Now() SendUpdate(arena, driver_signal) - (*graph_tester)(t).WaitForValue(match_c, "driver_running", 1*time.Second, "no driver_running") - (*graph_tester)(t).CheckForNone(match_c, "update to match after starting driver") + (*graph_tester)(t).WaitForValue(arena_c, "driver_running", 1*time.Second, "no driver_running") + (*graph_tester)(t).CheckForNone(arena_c, "update to match after starting driver") time.Sleep(TEMP_DRIVE_TIME) time.Sleep(time.Millisecond * 100) - (*graph_tester)(t).WaitForValue(match_c, "driver_done", 1*time.Second, "no driver_done") - (*graph_tester)(t).CheckForNone(match_c, "update to match after game done 3") - }(match_c) + (*graph_tester)(t).WaitForValue(arena_c, "driver_done", 1*time.Second, "no driver_done") + (*graph_tester)(t).CheckForNone(arena_c, "update to match after game done 3") + }(arena_c) err := event_manager.Run() if err != nil {