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
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)
}
}
}

@ -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,

@ -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

@ -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) {

@ -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 {