Added Trace to signal so that nodes can discard based on direction

graph-rework
noah metz 2023-06-03 02:45:16 -06:00
parent a43310daad
commit 301dbb6b94
5 changed files with 58 additions and 32 deletions

@ -12,12 +12,12 @@ import (
// Update the events listeners, and notify the parent to do the same // Update the events listeners, and notify the parent to do the same
func (event * BaseEvent) update(signal GraphSignal) { func (event * BaseEvent) update(signal GraphSignal) {
event.signal <- signal event.signal <- signal
new_signal := signal.Trace(event.ID())
if event.parent != nil && signal.Type() != "abort"{ if event.parent != nil && signal.Type() != "abort"{
SendUpdate(event.parent, signal) SendUpdate(event.parent, new_signal)
} else if signal.Type() == "abort" { } else if signal.Type() == "abort" {
for _, child := range(event.Children()) { for _, child := range(event.Children()) {
SendUpdate(child, signal) SendUpdate(child, new_signal)
} }
} }
} }

@ -18,6 +18,8 @@ type GraphSignal interface {
Type() string Type() string
Description() string Description() string
Time() time.Time Time() time.Time
Last() string
Trace(id string) GraphSignal
} }
type BaseSignal struct { type BaseSignal struct {
@ -25,6 +27,7 @@ type BaseSignal struct {
signal_type string signal_type string
description string description string
time time.Time time time.Time
last_id string
} }
func (signal BaseSignal) Time() time.Time { func (signal BaseSignal) Time() time.Time {
@ -43,6 +46,16 @@ func (signal BaseSignal) Description() string {
return signal.description 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) { func NewSignal(source GraphNode, signal_type string) (BaseSignal) {
signal := BaseSignal{ signal := BaseSignal{
source: source, source: source,

@ -9,19 +9,21 @@ import (
// Resources propagate update up to multiple parents, and not downwards // 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) // (subscriber to team won't get update to alliance, but subscriber to alliance will get update to team)
func (resource * BaseResource) update(signal GraphSignal) { func (resource * BaseResource) update(signal GraphSignal) {
new_signal := signal.Trace(resource.ID())
if signal.Type() == "lock_changed" { if signal.Type() == "lock_changed" {
for _, child := range resource.Children() { for _, child := range resource.Children() {
SendUpdate(child, signal) SendUpdate(child, new_signal)
} }
} else { } else {
for _, parent := range resource.Parents() { for _, parent := range resource.Parents() {
SendUpdate(parent, signal) SendUpdate(parent, new_signal)
} }
if resource.lock_holder != nil { 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 // Resource is the interface that DAG nodes are made from

@ -64,13 +64,6 @@ func NewAlliance(team0 * Team, team1 * Team) * Alliance {
return resource return resource
} }
type Match struct {
BaseEvent
state string
control string
control_start time.Time
}
type Arena struct { type Arena struct {
BaseResource BaseResource
connected bool connected bool
@ -96,8 +89,9 @@ func (arena * Arena) lock(event Event) error {
func (arena * Arena) update(signal GraphSignal) { func (arena * Arena) update(signal GraphSignal) {
log.Printf("ARENA_UPDATE: %s", arena.Name()) log.Printf("ARENA_UPDATE: %s", arena.Name())
arena.BaseResource.update(signal)
arena.signal <- signal arena.signal <- signal
new_signal := signal.Trace(arena.ID())
arena.BaseResource.update(new_signal)
} }
func (arena * Arena) Connect(abort chan error) bool { 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_AUTON_TIME = time.Second * 3
const TEMP_DRIVE_TIME = time.Second * 5 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 { func NewMatch(alliance0 * Alliance, alliance1 * Alliance, arena * Arena) * Match {
name := fmt.Sprintf("Match: %s vs. %s on %s", alliance0.Name(), alliance1.Name(), arena.Name()) name := fmt.Sprintf("Match: %s vs. %s on %s", alliance0.Name(), alliance1.Name(), arena.Name())
description := "A vex match" description := "A vex match"
@ -156,6 +166,7 @@ func NewMatch(alliance0 * Alliance, alliance1 * Alliance, arena * Arena) * Match
state: "init", state: "init",
control: "init", control: "init",
control_start: time.UnixMilli(0), control_start: time.UnixMilli(0),
arena: arena,
} }
match.actions["start"] = func() (string, error) { match.actions["start"] = func() (string, error) {

@ -131,9 +131,9 @@ func TestNewMatch(t *testing.T) {
alliance_2 := NewAlliance(team_3, team_4) alliance_2 := NewAlliance(team_3, team_4)
arena := NewVirtualArena(arena_name) arena := NewVirtualArena(arena_name)
arena_c := arena.UpdateChannel()
match := NewMatch(alliance_1, alliance_2, arena) match := NewMatch(alliance_1, alliance_2, arena)
match_c := match.UpdateChannel()
root_event := NewEventQueue("root_event", "", []Resource{}) root_event := NewEventQueue("root_event", "", []Resource{})
r := root_event.DoneResource() r := root_event.DoneResource()
@ -148,34 +148,34 @@ func TestNewMatch(t *testing.T) {
} }
}() }()
go func(match_c chan GraphSignal) { go func(arena_c chan GraphSignal) {
(*graph_tester)(t).WaitForValue(match_c, "event_start", 1*time.Second, "no event_start") (*graph_tester)(t).WaitForValue(arena_c, "event_start", 1*time.Second, "no event_start")
(*graph_tester)(t).CheckForNone(match_c, "update to match after starting") (*graph_tester)(t).CheckForNone(arena_c, "update to match after starting")
SendUpdate(arena, NewSignal(nil, "queue_autonomous")) SendUpdate(arena, NewSignal(nil, "queue_autonomous"))
(*graph_tester)(t).WaitForValue(match_c, "autonomous_queued", 1*time.Second, "no autonomous_queued") (*graph_tester)(t).WaitForValue(arena_c, "autonomous_queued", 1*time.Second, "no autonomous_queued")
(*graph_tester)(t).CheckForNone(match_c, "update to match after queueing autonomous") (*graph_tester)(t).CheckForNone(arena_c, "update to match after queueing autonomous")
auton_signal := NewSignal(nil, "start_autonomous") auton_signal := NewSignal(nil, "start_autonomous")
auton_signal.time = time.Now() auton_signal.time = time.Now()
SendUpdate(arena, auton_signal) SendUpdate(arena, auton_signal)
(*graph_tester)(t).WaitForValue(match_c, "autonomous_running", 1*time.Second, "no autonomous_running") (*graph_tester)(t).WaitForValue(arena_c, "autonomous_running", 1*time.Second, "no autonomous_running")
(*graph_tester)(t).CheckForNone(match_c, "update to match after starting autonomous") (*graph_tester)(t).CheckForNone(arena_c, "update to match after starting autonomous")
time.Sleep(TEMP_AUTON_TIME) time.Sleep(TEMP_AUTON_TIME)
time.Sleep(time.Millisecond * 100) time.Sleep(time.Millisecond * 100)
(*graph_tester)(t).WaitForValue(match_c, "autonomous_done", 6*time.Second, "no autonomous_done") (*graph_tester)(t).WaitForValue(arena_c, "autonomous_done", 6*time.Second, "no autonomous_done")
(*graph_tester)(t).CheckForNone(match_c, "update to match after ending autonomous") (*graph_tester)(t).CheckForNone(arena_c, "update to match after ending autonomous")
SendUpdate(arena, NewSignal(nil, "queue_driver")) SendUpdate(arena, NewSignal(nil, "queue_driver"))
(*graph_tester)(t).WaitForValue(match_c, "driver_queued", 1*time.Second, "no driver_queued") (*graph_tester)(t).WaitForValue(arena_c, "driver_queued", 1*time.Second, "no driver_queued")
(*graph_tester)(t).CheckForNone(match_c, "update to match after queueing driver") (*graph_tester)(t).CheckForNone(arena_c, "update to match after queueing driver")
driver_signal := NewSignal(nil, "start_driver") driver_signal := NewSignal(nil, "start_driver")
driver_signal.time = time.Now() driver_signal.time = time.Now()
SendUpdate(arena, driver_signal) SendUpdate(arena, driver_signal)
(*graph_tester)(t).WaitForValue(match_c, "driver_running", 1*time.Second, "no driver_running") (*graph_tester)(t).WaitForValue(arena_c, "driver_running", 1*time.Second, "no driver_running")
(*graph_tester)(t).CheckForNone(match_c, "update to match after starting driver") (*graph_tester)(t).CheckForNone(arena_c, "update to match after starting driver")
time.Sleep(TEMP_DRIVE_TIME) time.Sleep(TEMP_DRIVE_TIME)
time.Sleep(time.Millisecond * 100) time.Sleep(time.Millisecond * 100)
(*graph_tester)(t).WaitForValue(match_c, "driver_done", 1*time.Second, "no driver_done") (*graph_tester)(t).WaitForValue(arena_c, "driver_done", 1*time.Second, "no driver_done")
(*graph_tester)(t).CheckForNone(match_c, "update to match after game done 3") (*graph_tester)(t).CheckForNone(arena_c, "update to match after game done 3")
}(match_c) }(arena_c)
err := event_manager.Run() err := event_manager.Run()
if err != nil { if err != nil {