diff --git a/event.go b/event.go index 691fa73..083ce11 100644 --- a/event.go +++ b/event.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "log" "errors" graphql "github.com/graph-gophers/graphql-go" "reflect" @@ -73,7 +74,7 @@ type BaseEvent struct { required_resources []Resource children []Event child_info map[Event]EventInfo - actions map[string]func(Event) (string, error) + actions map[string]func() (string, error) parent Event signal chan string abort chan string @@ -138,7 +139,7 @@ func (event * BaseEvent) Run() error { } // Run the edge function - next_action, err = action(event) + next_action, err = action() if err != nil { return err } else if next_action == "wait" { @@ -184,7 +185,7 @@ func NewBaseEvent(name string, description string, required_resources []Resource child_info: map[Event]EventInfo{}, done_resource: done_resource, required_resources: required_resources, - actions: map[string]func(Event)(string, error){}, + actions: map[string]func()(string, error){}, signal: make(chan string, 10), abort: make(chan string, 1), } @@ -199,7 +200,7 @@ func NewEvent(name string, description string, required_resources []Resource) (* // Lock the done_resource by default event.LockDone() - event_ptr.actions["start"] = func(event Event) (string, error) { + event_ptr.actions["start"] = func() (string, error) { return "", nil } @@ -214,11 +215,13 @@ func NewEventQueue(name string, description string, required_resources []Resourc // Need to lock it with th BaseEvent since Unlock is implemented on the BaseEvent queue.LockDone() - queue.actions["start"] = func(queue Event) (string, error) { + queue.actions["start"] = func() (string, error) { + log.Printf("Starting Event Queue") return "queue_event", nil } - queue.actions["queue_event"] = func(queue Event) (string, error) { + queue.actions["queue_event"] = func() (string, error) { + log.Printf("Queueing events") // Copy the events to sort the list copied_events := make([]Event, len(queue.Children())) copy(copied_events, queue.Children()) @@ -260,11 +263,18 @@ func NewEventQueue(name string, description string, required_resources []Resourc } } - queue.actions["event_done"] = func(queue Event) (string, error) { + queue.actions["event_done"] = func() (string, error) { + log.Printf("event_done") return "queue_event", nil } - queue.actions["resource_available"] = func(queue Event) (string, error) { + queue.actions["resource_available"] = func() (string, error) { + log.Printf("resources_available") + return "queue_event", nil + } + + queue.actions["event_added"] = func() (string, error) { + log.Printf("event_added") return "queue_event", nil } diff --git a/main.go b/main.go index 74ba9f9..4ac1b40 100644 --- a/main.go +++ b/main.go @@ -4,42 +4,114 @@ import ( "log" ) +func fake_team(org string, id string, names []string) (*Team, []*Member) { + members := []*Member{} + for _, name := range(names) { + members = append(members, NewMember(name)) + } + team := NewTeam(org, id, members) + return team, members +} + func fake_data() * EventManager { resources := []Resource{} teams := []*Team{} - teams = append(teams, NewTeam("6659", "A", []*Member{NewMember("jimmy")})) - teams = append(teams, NewTeam("6659", "B", []*Member{NewMember("timmy")})) - teams = append(teams, NewTeam("6659", "C", []*Member{NewMember("grace")})) - teams = append(teams, NewTeam("6659", "D", []*Member{NewMember("jeremy")})) - teams = append(teams, NewTeam("210", "W", []*Member{NewMember("bobby")})) - teams = append(teams, NewTeam("210", "X", []*Member{NewMember("toby")})) - teams = append(teams, NewTeam("210", "Y", []*Member{NewMember("jennifer")})) - teams = append(teams, NewTeam("210", "Z", []*Member{NewMember("emily")})) - teams = append(teams, NewTeam("315", "W", []*Member{NewMember("bobby")})) - teams = append(teams, NewTeam("315", "X", []*Member{NewMember("toby")})) - teams = append(teams, NewTeam("315", "Y", []*Member{NewMember("jennifer")})) - teams = append(teams, NewTeam("315", "Z", []*Member{NewMember("emily")})) + t1, m1 := fake_team("6659", "A", []string{"jimmy"}) + t2, m2 := fake_team("6659", "B", []string{"timmy"}) + t3, m3 := fake_team("6659", "C", []string{"grace"}) + t4, m4 := fake_team("6659", "D", []string{"jeremy"}) + t5, m5 := fake_team("210", "W", []string{"bobby"}) + t6, m6 := fake_team("210", "X", []string{"toby"}) + t7, m7 := fake_team("210", "Y", []string{"jennifer"}) + t8, m8 := fake_team("210", "Z", []string{"emily"}) + t9, m9 := fake_team("315", "W", []string{"bobby"}) + t10, m10 := fake_team("315", "X", []string{"toby"}) + t11, m11 := fake_team("315", "Y", []string{"jennifer"}) + t12, m12 := fake_team("315", "Z", []string{"emily"}) - for _, team := range teams { - resources = append(resources, team) - } + teams = append(teams, t1) + teams = append(teams, t2) + teams = append(teams, t3) + teams = append(teams, t4) + teams = append(teams, t5) + teams = append(teams, t6) + teams = append(teams, t7) + teams = append(teams, t8) + teams = append(teams, t9) + teams = append(teams, t10) + teams = append(teams, t11) + teams = append(teams, t12) + resources = append(resources, m1[0]) + resources = append(resources, m2[0]) + resources = append(resources, m3[0]) + resources = append(resources, m4[0]) + resources = append(resources, m5[0]) + resources = append(resources, m6[0]) + resources = append(resources, m7[0]) + resources = append(resources, m8[0]) + resources = append(resources, m9[0]) + resources = append(resources, m10[0]) + resources = append(resources, m11[0]) + resources = append(resources, m12[0]) + + alliances := []*Alliance{} for i, team := range teams[:len(teams)-1] { for _, team2 := range teams[i+1:] { alliance := NewAlliance(team, team2) - resources = append(resources, alliance) + alliances = append(alliances, alliance) } } - root_event := NewEventQueue("root_event", "", []Resource{}) + arenas := []*Arena{} + arenas = append(arenas, NewVirtualArena("Arena 1")) + arenas = append(arenas, NewVirtualArena("Arena 2")) + arenas = append(arenas, NewVirtualArena("Arena 3")) + + for _, arena := range arenas { + resources = append(resources, arena) + } + + for _, team := range teams { + resources = append(resources, team) + } + + for _, alliance := range alliances { + resources = append(resources, alliance) + } + + + root_event := NewEventQueue("root_event", "", []Resource{}) event_manager := NewEventManager(root_event, resources) + arena_idx := 0 + for i, alliance := range alliances[:len(alliances)-1] { + for _, alliance2 := range alliances[i+1:] { + match := NewMatch(alliance, alliance2, arenas[arena_idx]) + err := event_manager.AddEvent(root_event, match, NewEventQueueInfo(i)) + if err != nil { + log.Printf("Error adding %s: %s", match.Name(), err) + } + arena_idx += 1 + if arena_idx >= len(arenas) { + arena_idx = 0 + } + } + } + + return event_manager } func main() { event_manager := fake_data() - log.Printf("Starting event_manager: %+v", event_manager) + log.Printf("Starting event_manager") + err := event_manager.Run() + if err != nil { + log.Printf("Error running event_manager: %s", err) + } else { + log.Printf("Finished event_manager") + } } diff --git a/manager.go b/manager.go index c917c63..9ebacee 100644 --- a/manager.go +++ b/manager.go @@ -24,12 +24,15 @@ func NewEventManager(root_event Event, dag_nodes []Resource) * EventManager { for _, resource := range dag_nodes { err := manager.AddResource(resource) if err != nil { - log.Printf("Failed to add %s to EventManager: %s", resource.ID(), err) + log.Printf("Failed to add %s to EventManager: %s", resource.Name(), err) return nil } } - manager.AddEvent(nil, root_event, nil) + err := manager.AddEvent(nil, root_event, nil) + if err != nil { + log.Printf("Failed to add %s to EventManager as root_event: %s", root_event.Name(), err) + } return manager; } @@ -56,14 +59,14 @@ func (manager * EventManager) FindEvent(id graphql.ID) Event { func (manager * EventManager) AddResource(resource Resource) error { _, exists := manager.dag_nodes[resource.ID()] if exists == true { - error_str := fmt.Sprintf("%s is already in the resource DAG, cannot add again", resource.ID()) + error_str := fmt.Sprintf("%s is already in the resource DAG, cannot add again", resource.Name()) return errors.New(error_str) } for _, child := range resource.Children() { _, exists := manager.dag_nodes[child.ID()] if exists == false { - error_str := fmt.Sprintf("%s is not in the resource DAG, cannot add %s to DAG", child.ID(), resource.ID()) + error_str := fmt.Sprintf("%s is not in the resource DAG, cannot add %s to DAG", child.Name(), resource.Name()) return errors.New(error_str) } } diff --git a/manager_test.go b/manager_test.go index 9c73d4d..45de337 100644 --- a/manager_test.go +++ b/manager_test.go @@ -330,9 +330,12 @@ func TestStartEventQueue(t * testing.T) { root_event := NewEventQueue("", "", []Resource{}) r := root_event.DoneResource() rel := root_event.UpdateChannel(); - manager := NewEventManager(root_event, []Resource{}) + res_1 := NewResource("test_resource", "", []Resource{}) + res_2 := NewResource("test_resource", "", []Resource{}) + manager := NewEventManager(root_event, []Resource{res_1, res_2}) + - e1:= NewEvent("1", "", []Resource{}) + e1:= NewEvent("1", "", []Resource{res_1, res_2}) e1_r := e1.DoneResource() e1_info := NewEventQueueInfo(1) err := manager.AddEvent(root_event, e1, e1_info) @@ -341,7 +344,7 @@ func TestStartEventQueue(t * testing.T) { } (*graph_tester)(t).CheckForNil(rel) - e2 := NewEvent("1", "", []Resource{}) + e2 := NewEvent("1", "", []Resource{res_1}) e2_r := e2.DoneResource() e2_info := NewEventQueueInfo(2) err = manager.AddEvent(root_event, e2, e2_info) @@ -350,7 +353,7 @@ func TestStartEventQueue(t * testing.T) { } (*graph_tester)(t).CheckForNil(rel) - e3 := NewEvent("1", "", []Resource{}) + e3 := NewEvent("1", "", []Resource{res_2}) e3_r := e3.DoneResource() e3_info := NewEventQueueInfo(3) err = manager.AddEvent(root_event, e3, e3_info) diff --git a/vex.go b/vex.go index 5c5d4f4..aeb350b 100644 --- a/vex.go +++ b/vex.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "log" ) type ArenaDriver interface { @@ -119,6 +120,7 @@ func NewAlliance(team0 * Team, team1 * Team) * Alliance { type Match struct { BaseEvent + state string } func NewMatch(alliance0 * Alliance, alliance1 * Alliance, arena * Arena) * Match { @@ -127,11 +129,24 @@ func NewMatch(alliance0 * Alliance, alliance1 * Alliance, arena * Arena) * Match match := &Match{ BaseEvent: NewBaseEvent(name, description, []Resource{alliance0, alliance1, arena}), + state: "init", } match.LockDone() - match.actions["start"] = func(match Event) (string, error) { - return "", nil + match.actions["start"] = func() (string, error) { + // put the match into "scheduled" state + log.Printf("Starting match") + match.state = "scheduled" + return "wait", nil + } + + match.actions["start_autonomous"] = func() (string, error) { + if match.state != "scheduled" { + log.Printf("Cannot start_autonomous when the match is in %s", match.state) + return "wait", nil + } + log.Printf("Starting autonomous") + return "wait", nil } return match diff --git a/vex_test.go b/vex_test.go index 5103e26..8362a1c 100644 --- a/vex_test.go +++ b/vex_test.go @@ -3,6 +3,7 @@ package main import ( "testing" "fmt" + "time" ) type vex_tester graph_tester @@ -98,7 +99,7 @@ func TestNewAllianceAdd(t *testing.T) { } } -func TestNewMatchAdd(t *testing.T) { +func TestNewMatch(t *testing.T) { name_1 := "Noah" name_2 := "Ben" name_3 := "Justin" @@ -132,5 +133,14 @@ func TestNewMatchAdd(t *testing.T) { root_event := NewMatch(alliance_1, alliance_2, arena) event_manager := NewEventManager(root_event, []Resource{member_1, member_2, member_3, member_4, team_1, team_2, team_3, team_4, alliance_1, alliance_2, arena}) - println(event_manager) + + go func() { + time.Sleep(time.Second * 2) + root_event.Abort() + }() + + err := event_manager.Run() + if err == nil { + t.Fatal(err) + } }