Removed vex files and changed package name

graph-rework
noah metz 2023-06-18 18:26:13 -06:00
parent 105de0509c
commit 8b7eb57673
10 changed files with 6 additions and 1120 deletions

@ -1,4 +1,4 @@
package main package git.metznet.ca/MetzNet/graphvent
import ( import (
"fmt" "fmt"

@ -1,4 +1,4 @@
package main package git.metznet.ca/MetzNet/graphvent
import ( import (
"net/http" "net/http"

@ -1,446 +0,0 @@
package main
import (
"github.com/graphql-go/graphql"
"reflect"
"fmt"
"errors"
)
func GQLVexTypes() map[reflect.Type]*graphql.Object {
types := map[reflect.Type]*graphql.Object{}
types[reflect.TypeOf((*Match)(nil))] = GQLVexTypeMatch()
return types
}
func GQLVexMutations() map[string]*graphql.Field {
mutations := map[string]*graphql.Field{}
mutations["setMatchState"] = GQLVexMutationSetMatchState()
return mutations
}
func GQLVexQueries() map[string]*graphql.Field {
queries := map[string]*graphql.Field{}
queries["Arenas"] = GQLVexQueryArenas()
return queries
}
func GQLVexSubscriptions() map[string]*graphql.Field {
subs := map[string]*graphql.Field{}
subs["Arena"] = GQLVexSubscriptionArena()
return subs
}
var gql_vex_subscription_arena *graphql.Field = nil
func GQLVexSubscriptionArena() *graphql.Field {
if gql_vex_subscription_arena == nil {
gql_vex_subscription_arena = &graphql.Field{
Type: GQLVexTypeArena(),
Args: graphql.FieldConfigArgument{
"arena_id": &graphql.ArgumentConfig{
Type: graphql.String,
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
return p.Source, nil
},
Subscribe: GQLVexSubscribeArena,
}
}
return gql_vex_subscription_arena
}
func GQLVexSubscribeArena(p graphql.ResolveParams)(interface{}, error) {
server, ok := p.Context.Value("gql_server").(*GQLServer)
if ok == false {
return nil, fmt.Errorf("Failed to get gql_Server from context and cast to GQLServer")
}
c := make(chan interface{})
arena_id, ok := p.Args["arena_id"].(string)
if ok == false {
return nil, fmt.Errorf("Failed to get arena_id arg")
}
owner, ok := server.Owner().(Event)
if ok == false {
return nil, fmt.Errorf("Failed to cast owner to event")
}
resource := FindRequiredResource(owner, arena_id)
if resource == nil {
return nil, fmt.Errorf("Failed to find resource under owner")
}
arena, ok := resource.(Arena)
if ok == false {
return nil, fmt.Errorf("Failed to cast resource to arena")
}
sig_c := arena.UpdateChannel()
go func(c chan interface{}, sig_c chan GraphSignal, arena Arena) {
c <- arena
for {
_, ok := <- sig_c
if ok == false {
return
}
c <- arena
}
}(c, sig_c, arena)
return c, nil
}
var gql_vex_mutation_set_match_state *graphql.Field= nil
func GQLVexMutationSetMatchState() *graphql.Field {
if gql_vex_mutation_set_match_state == nil {
gql_vex_mutation_set_match_state = &graphql.Field{
Type: GQLTypeSignal(),
Args: graphql.FieldConfigArgument{
"id": &graphql.ArgumentConfig{
Type: graphql.String,
},
"state": &graphql.ArgumentConfig{
Type: graphql.String,
},
"time": &graphql.ArgumentConfig{
Type: graphql.DateTime,
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
server, ok := p.Context.Value("gql_server").(*GQLServer)
if ok == false {
return nil, fmt.Errorf("Failed to cast context gql_server to GQLServer: %+v", p.Context.Value("gql_server"))
}
id, ok := p.Args["id"].(string)
if ok == false {
return nil, errors.New("Failed to cast arg id to string")
}
state, ok := p.Args["state"].(string)
if ok == false {
return nil, errors.New("Failed to cast arg state to string")
}
signal := NewDownSignal(server, state)
owner := server.Owner()
if owner == nil {
return nil, errors.New("Cannot send update without owner")
}
root_event, ok := owner.(Event)
if ok == false {
return nil, errors.New("Cannot send update to Event unless owned by an Event")
}
node := FindChild(root_event, id)
if node == nil {
return nil, errors.New("Failed to find id in event tree from server")
}
SendUpdate(node, signal)
return signal, nil
},
}
}
return gql_vex_mutation_set_match_state
}
var gql_vex_query_arenas *graphql.Field = nil
func GQLVexQueryArenas() *graphql.Field {
if gql_vex_query_arenas == nil {
gql_vex_query_arenas = &graphql.Field{
Type: GQLVexListArena(),
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
server, ok := p.Context.Value("gql_server").(*GQLServer)
if ok == false {
panic("Failed to get/cast gql_server from context")
}
owner, is_event := server.Owner().(Event)
if is_event == false {
return nil, fmt.Errorf("Can't enumerate arenas when server is attached to resource")
}
return FindResources(owner, reflect.TypeOf((*VirtualArena)(nil))), nil
},
}
}
return gql_vex_query_arenas
}
var gql_vex_list_arena * graphql.List = nil
func GQLVexListArena() * graphql.List {
if gql_vex_list_arena == nil {
gql_vex_list_arena = graphql.NewList(GQLVexTypeArena())
}
return gql_vex_list_arena
}
var gql_vex_list_team * graphql.List = nil
func GQLVexListTeam() * graphql.List {
if gql_vex_list_team == nil {
gql_vex_list_team = graphql.NewList(GQLVexTypeTeam())
}
return gql_vex_list_team
}
var gql_vex_list_alliance * graphql.List = nil
func GQLVexListAlliance() * graphql.List {
if gql_vex_list_alliance == nil {
gql_vex_list_alliance = graphql.NewList(GQLVexTypeAlliance())
}
return gql_vex_list_alliance
}
func GQLVexMatchAlliances(p graphql.ResolveParams) (interface{}, error) {
return GQLEventFn(p, func(event Event, p graphql.ResolveParams) (interface{}, error) {
return event.(*Match).alliances, nil
})
}
func GQLVexMatchArena(p graphql.ResolveParams) (interface{}, error) {
return GQLEventFn(p, func(event Event, p graphql.ResolveParams) (interface{}, error) {
return event.(*Match).arena, nil
})
}
func GQLVexMatchControl(p graphql.ResolveParams) (interface{}, error) {
return GQLEventFn(p, func(event Event, p graphql.ResolveParams) (interface{}, error) {
return event.(*Match).control, nil
})
}
func GQLVexMatchState(p graphql.ResolveParams) (interface{}, error) {
return GQLEventFn(p, func(event Event, p graphql.ResolveParams) (interface{}, error) {
return event.(*Match).state, nil
})
}
func GQLVexMatchStateStart(p graphql.ResolveParams) (interface{}, error) {
return GQLEventFn(p, func(event Event, p graphql.ResolveParams) (interface{}, error) {
return event.(*Match).control_start, nil
})
}
func GQLVexMatchStateDuration(p graphql.ResolveParams) (interface{}, error) {
return GQLEventFn(p, func(event Event, p graphql.ResolveParams) (interface{}, error) {
return event.(*Match).control_duration, nil
})
}
func GQLVexAllianceTeams(p graphql.ResolveParams) (interface{}, error) {
return GQLResourceFn(p, func(resource Resource, p graphql.ResolveParams) (interface{}, error) {
return resource.(*Alliance).teams, nil
})
}
var gql_vex_type_arena * graphql.Object = nil
func GQLVexTypeArena() * graphql.Object {
if gql_vex_type_arena == nil {
gql_vex_type_arena = graphql.NewObject(graphql.ObjectConfig{
Name: "Arena",
Interfaces: []*graphql.Interface{
GQLInterfaceNode(),
GQLInterfaceResource(),
},
IsTypeOf: func(p graphql.IsTypeOfParams) bool {
_, ok := p.Value.(Arena)
return ok
},
Fields: graphql.Fields{},
})
gql_vex_type_arena.AddFieldConfig("ID", &graphql.Field{
Type: graphql.String,
Resolve: GQLResourceID,
})
gql_vex_type_arena.AddFieldConfig("Name", &graphql.Field{
Type: graphql.String,
Resolve: GQLResourceName,
})
gql_vex_type_arena.AddFieldConfig("Description", &graphql.Field{
Type: graphql.String,
Resolve: GQLResourceDescription,
})
gql_vex_type_arena.AddFieldConfig("Parents", &graphql.Field{
Type: GQLListResource(),
Resolve: GQLResourceParents,
})
gql_vex_type_arena.AddFieldConfig("Owner", &graphql.Field{
Type: GQLInterfaceNode(),
Resolve: GQLResourceOwner,
})
}
return gql_vex_type_arena
}
var gql_vex_type_match * graphql.Object = nil
func GQLVexTypeMatch() * graphql.Object {
if gql_vex_type_match == nil {
gql_vex_type_match = graphql.NewObject(graphql.ObjectConfig{
Name: "Match",
Interfaces: []*graphql.Interface{
GQLInterfaceNode(),
GQLInterfaceEvent(),
},
IsTypeOf: func(p graphql.IsTypeOfParams) bool {
_, ok := p.Value.(*Match)
return ok
},
Fields: graphql.Fields{},
})
gql_vex_type_match.AddFieldConfig("ID", &graphql.Field{
Type: graphql.String,
Resolve: GQLEventID,
})
gql_vex_type_match.AddFieldConfig("Name", &graphql.Field{
Type: graphql.String,
Resolve: GQLEventName,
})
gql_vex_type_match.AddFieldConfig("Description", &graphql.Field{
Type: graphql.String,
Resolve: GQLEventDescription,
})
gql_vex_type_match.AddFieldConfig("Children", &graphql.Field{
Type: GQLListEvent(),
Resolve: GQLEventChildren,
})
gql_vex_type_match.AddFieldConfig("Alliances", &graphql.Field{
Type: GQLVexListAlliance(),
Resolve: GQLVexMatchAlliances,
})
gql_vex_type_match.AddFieldConfig("Arena", &graphql.Field{
Type: graphql.String,
Resolve: GQLVexMatchArena,
})
gql_vex_type_match.AddFieldConfig("Control", &graphql.Field{
Type: graphql.String,
Resolve: GQLVexMatchControl,
})
gql_vex_type_match.AddFieldConfig("State", &graphql.Field{
Type: graphql.String,
Resolve: GQLVexMatchState,
})
gql_vex_type_match.AddFieldConfig("StateStart", &graphql.Field{
Type: graphql.DateTime,
Resolve: GQLVexMatchStateStart,
})
gql_vex_type_match.AddFieldConfig("StateDuration", &graphql.Field{
Type: graphql.Int,
Resolve: GQLVexMatchStateDuration,
})
}
return gql_vex_type_match
}
var gql_vex_type_alliance * graphql.Object = nil
func GQLVexTypeAlliance() * graphql.Object {
if gql_vex_type_alliance == nil {
gql_vex_type_alliance = graphql.NewObject(graphql.ObjectConfig{
Name: "Alliance",
Interfaces: []*graphql.Interface{
GQLInterfaceNode(),
GQLInterfaceResource(),
},
IsTypeOf: func(p graphql.IsTypeOfParams) bool {
_, ok := p.Value.(*Alliance)
return ok
},
Fields: graphql.Fields{},
})
gql_vex_type_alliance.AddFieldConfig("ID", &graphql.Field{
Type: graphql.String,
Resolve: GQLResourceID,
})
gql_vex_type_alliance.AddFieldConfig("Name", &graphql.Field{
Type: graphql.String,
Resolve: GQLResourceName,
})
gql_vex_type_alliance.AddFieldConfig("Description", &graphql.Field{
Type: graphql.String,
Resolve: GQLResourceDescription,
})
gql_vex_type_alliance.AddFieldConfig("Parents", &graphql.Field{
Type: GQLListResource(),
Resolve: GQLResourceParents,
})
gql_vex_type_alliance.AddFieldConfig("Owner", &graphql.Field{
Type: GQLInterfaceNode(),
Resolve: GQLResourceOwner,
})
gql_vex_type_alliance.AddFieldConfig("Teams", &graphql.Field{
Type: GQLVexListTeam(),
Resolve: GQLVexAllianceTeams,
})
}
return gql_vex_type_alliance
}
var gql_vex_type_team * graphql.Object = nil
func GQLVexTypeTeam() * graphql.Object {
if gql_vex_type_team == nil {
gql_vex_type_team = graphql.NewObject(graphql.ObjectConfig{
Name: "Team",
Interfaces: []*graphql.Interface{
GQLInterfaceNode(),
GQLInterfaceResource(),
},
IsTypeOf: func(p graphql.IsTypeOfParams) bool {
_, ok := p.Value.(*Team)
return ok
},
Fields: graphql.Fields{},
})
}
gql_vex_type_team.AddFieldConfig("ID", &graphql.Field{
Type: graphql.String,
Resolve: GQLResourceID,
})
gql_vex_type_team.AddFieldConfig("Name", &graphql.Field{
Type: graphql.String,
Resolve: GQLResourceName,
})
gql_vex_type_team.AddFieldConfig("Description", &graphql.Field{
Type: graphql.String,
Resolve: GQLResourceDescription,
})
gql_vex_type_team.AddFieldConfig("Parents", &graphql.Field{
Type: GQLListResource(),
Resolve: GQLResourceParents,
})
gql_vex_type_team.AddFieldConfig("Owner", &graphql.Field{
Type: GQLInterfaceNode(),
Resolve: GQLResourceOwner,
})
return gql_vex_type_team
}

@ -1,4 +1,4 @@
package main package git.metznet.ca/MetzNet/graphvent
import ( import (
"sync" "sync"

@ -1,219 +0,0 @@
package main
import (
"time"
"runtime/pprof"
"os"
"os/signal"
"syscall"
"fmt"
)
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_div1 := []*Team{}
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"})
teams_div2 := []*Team{}
t9, m9 := fake_team("666", "A", []string{"jimmy"})
t10, m10 := fake_team("666", "B", []string{"timmy"})
t11, m11 := fake_team("666", "C", []string{"grace"})
t12, m12 := fake_team("666", "D", []string{"jeremy"})
t13, m13 := fake_team("315", "W", []string{"bobby"})
t14, m14 := fake_team("315", "X", []string{"toby"})
t15, m15 := fake_team("315", "Y", []string{"jennifer"})
t16, m16 := fake_team("315", "Z", []string{"emily"})
teams_div1 = append(teams_div1, t1)
teams_div1 = append(teams_div1, t2)
teams_div1 = append(teams_div1, t3)
teams_div1 = append(teams_div1, t4)
teams_div1 = append(teams_div1, t5)
teams_div1 = append(teams_div1, t6)
teams_div1 = append(teams_div1, t7)
teams_div1 = append(teams_div1, t8)
teams_div2 = append(teams_div2, t9)
teams_div2 = append(teams_div2, t10)
teams_div2 = append(teams_div2, t11)
teams_div2 = append(teams_div2, t12)
teams_div2 = append(teams_div2, t13)
teams_div2 = append(teams_div2, t14)
teams_div2 = append(teams_div2, t15)
teams_div2 = append(teams_div2, t16)
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])
resources = append(resources, m13[0])
resources = append(resources, m14[0])
resources = append(resources, m15[0])
resources = append(resources, m16[0])
arenas_div1 := []Arena{}
arenas_div1 = append(arenas_div1, NewVirtualArena("Arena 1"))
arenas_div1 = append(arenas_div1, NewVirtualArena("Arena 2"))
arenas_div2 := []Arena{}
arenas_div2 = append(arenas_div2, NewVirtualArena("Arena 3"))
arenas_div2 = append(arenas_div2, NewVirtualArena("Arena 4"))
for _, arena := range arenas_div1 {
resources = append(resources, arena)
}
for _, arena := range arenas_div2 {
resources = append(resources, arena)
}
for _, team := range teams_div1 {
resources = append(resources, team)
}
for _, team := range teams_div2 {
resources = append(resources, team)
}
alliances_div1 := []*Alliance{}
alliances_div1 = append(alliances_div1, NewAlliance(t1, t2))
alliances_div1 = append(alliances_div1, NewAlliance(t3, t4))
alliances_div1 = append(alliances_div1, NewAlliance(t5, t6))
alliances_div1 = append(alliances_div1, NewAlliance(t7, t8))
alliances_div2 := []*Alliance{}
alliances_div2 = append(alliances_div2, NewAlliance(t9, t10))
alliances_div2 = append(alliances_div2, NewAlliance(t11, t12))
alliances_div2 = append(alliances_div2, NewAlliance(t13, t14))
alliances_div2 = append(alliances_div2, NewAlliance(t15, t16))
for _, alliance := range alliances_div1 {
resources = append(resources, alliance)
}
for _, alliance := range alliances_div2 {
resources = append(resources, alliance)
}
gql_server := NewGQLServer(":8080", GQLVexTypes(), GQLVexQueries(), GQLVexMutations(), GQLVexSubscriptions())
resources = append(resources, gql_server)
root_event := NewEventQueue("root_event", "", []Resource{gql_server})
div_1 := NewEventQueue("Division 1", "", []Resource{})
err := AddChild(root_event, div_1, NewEventQueueInfo(1))
if err != nil {
panic(fmt.Sprintf("Failed to add div_1: %s", err))
}
div_2 := NewEventQueue("Division 2", "", []Resource{})
err = AddChild(root_event, div_2, NewEventQueueInfo(1))
if err != nil {
panic(fmt.Sprintf("Failed to add div_2: %s", err))
}
event_manager := NewEventManager(root_event, resources)
for i, alliance := range(alliances_div1) {
for j, alliance2 := range(alliances_div1) {
if j != i {
if alliance.Children()[0] == alliance2.Children()[0] || alliance.Children()[0] == alliance2.Children()[1] || alliance.Children()[1] == alliance2.Children()[0] || alliance.Children()[1] == alliance2.Children()[1] {
} else {
for arena_idx := 0; arena_idx < len(arenas_div1); arena_idx++ {
match := NewMatch(alliance, alliance2, arenas_div1[arena_idx])
log.Logf("test", "Adding %s", match.Name())
err := event_manager.AddEvent(div_1, match, NewEventQueueInfo(i))
if err != nil {
log.Logf("test", "Error adding %s: %s", match.Name(), err)
}
}
}
}
}
}
for i, alliance := range(alliances_div2) {
for j, alliance2 := range(alliances_div2) {
if j != i {
if alliance.Children()[0] == alliance2.Children()[0] || alliance.Children()[0] == alliance2.Children()[1] || alliance.Children()[1] == alliance2.Children()[0] || alliance.Children()[1] == alliance2.Children()[1] {
} else {
for arena_idx := 0; arena_idx < len(arenas_div2); arena_idx++ {
match := NewMatch(alliance, alliance2, arenas_div2[arena_idx])
log.Logf("test", "Adding %s", match.Name())
err := event_manager.AddEvent(div_2, match, NewEventQueueInfo(i))
if err != nil {
log.Logf("test", "Error adding %s: %s", match.Name(), err)
}
}
}
}
}
}
return event_manager
}
func main() {
event_manager := fake_data()
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go func() {
cpufile, err := os.OpenFile("graphvent.cpu", os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0666)
if err != nil {
panic("Failed to open cpu profile file")
}
memfile, err := os.OpenFile("graphvent.mem", os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0666)
if err != nil {
panic("Failed to open mem profile file")
}
pprof.StartCPUProfile(cpufile)
time.Sleep(3000 * time.Millisecond)
pprof.WriteHeapProfile(memfile)
}()
go func() {
for true {
select {
case <-sigs:
pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
signal := NewDownSignal(nil, "abort")
SendUpdate(event_manager.root_event, signal)
break
}
}
}()
log.Logf("test", "Starting event_manager")
err := event_manager.Run()
if err != nil {
log.Logf("test", "Error running event_manager: %s", err)
} else {
log.Logf("test", "Finished event_manager")
}
pprof.StopCPUProfile()
}

@ -1,4 +1,4 @@
package main package git.metznet.ca/MetzNet/graphvent
import ( import (
"fmt" "fmt"

@ -1,4 +1,4 @@
package main package git.metznet.ca/MetzNet/graphvent
import ( import (
"testing" "testing"

@ -1,4 +1,4 @@
package main package git.metznet.ca/MetzNet/graphvent
import ( import (
"fmt" "fmt"

275
vex.go

@ -1,275 +0,0 @@
package main
import (
"fmt"
"time"
"errors"
)
type Member struct {
BaseResource
}
func NewMember(name string) * Member {
member := &Member{
BaseResource: NewBaseResource(name, "A Team Member", []Resource{}),
}
return member
}
type Team struct {
BaseResource
Org string
Team string
}
func (team * Team) Members() []*Member {
ret := make([]*Member, len(team.children))
for idx, member := range(team.children) {
ret[idx] = member.(*Member)
}
return ret
}
func NewTeam(org string, team string, members []*Member) * Team {
name := fmt.Sprintf("%s%s", org, team)
description := fmt.Sprintf("Team %s", name)
resource := &Team{
BaseResource: NewBaseResource(name, description, make([]Resource, len(members))),
Org: org,
Team: team,
}
for idx, member := range(members) {
resource.children[idx] = member
}
return resource
}
type Alliance struct {
BaseResource
teams []*Team
}
func NewAlliance(team0 * Team, team1 * Team) * Alliance {
name := fmt.Sprintf("Alliance %s/%s", team0.Name(), team1.Name())
description := ""
resource := &Alliance{
BaseResource: NewBaseResource(name, description, []Resource{team0, team1}),
teams: []*Team{team0, team1},
}
return resource
}
type Arena interface {
Resource
}
type VirtualArena struct {
BaseResource
connected bool
}
func NewVirtualArena(name string) * VirtualArena {
arena := &VirtualArena{
BaseResource: NewBaseResource(name, "A virtual vex arena", []Resource{}),
connected: false,
}
return arena
}
func (arena * VirtualArena) lock(node GraphNode) error {
if arena.connected == false {
log.Logf("vex", "ARENA NOT CONNECTED: %s", arena.Name())
error_str := fmt.Sprintf("%s is not connected, cannot lock", arena.Name())
return errors.New(error_str)
}
return nil
}
func (arena * VirtualArena) update(signal GraphSignal) {
arena.signal <- signal
arena.BaseResource.update(signal)
}
func (arena * VirtualArena) Init(abort chan error) bool {
log.Logf("vex", "Initializing %s", arena.Name())
go func(arena * VirtualArena, abort chan error) {
signal := NewSignal(arena, "resource_connected")
arena.connected = true
SendUpdate(arena, signal)
log.Logf("vex", "VIRTUAL_ARENA goroutine starting: %s", arena.Name())
for true {
select {
case <- abort:
log.Logf("vex", "Virtual arena %s aborting", arena.Name())
break
case update := <- arena.signal:
log.Logf("vex", "VIRTUAL_ARENA_ACTION: %s : %+v", arena.Name(), update)
}
}
}(arena, abort)
return true
}
type VexEvent struct {
BaseEvent
}
func NewVexEvent(name string, description string) * VexEvent {
event := &VexEvent{
BaseEvent: NewBaseEvent(name, description, []Resource{}),
}
event.actions["wait"] = EventWait(event)
event.handlers["abort"] = EventAbort(event)
event.actions["start"] = func() (string, error) {
log.Logf("vex", "STARTING_VEX_TOURNAMENT %s", event.Name())
return "wait", nil
}
return event
}
const start_slack = 250 * time.Millisecond
const TEMP_AUTON_TIME = 5 * time.Second
const TEMP_DRIVE_TIME = 5 * time.Second
type Match struct {
BaseEvent
arena Arena
state string
control string
control_start time.Time
control_duration time.Duration
alliances []*Alliance
}
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"
match := &Match{
BaseEvent: NewBaseEvent(name, description, []Resource{alliance0, alliance1, arena}),
state: "init",
control: "init",
control_start: time.UnixMilli(0),
control_duration: 0,
arena: arena,
alliances: []*Alliance{alliance0, alliance1},
}
match.actions["wait"] = EventWait(match)
match.handlers["abort"] = EventAbort(match)
match.actions["start"] = func() (string, error) {
log.Logf("vex", "STARTING_MATCH %s", match.Name())
match.control = "none"
match.state = "scheduled"
match.control_start = time.Now()
return "wait", nil
}
match.handlers["queue_autonomous"] = func(signal GraphSignal) (string, error) {
if match.state != "scheduled" {
log.Logf("vex", "BAD_STATE: %s: %s - %s", signal.Type(), match.state, match.Name())
return "wait", nil
}
log.Logf("vex", "AUTONOMOUS_QUEUED: %s", match.Name())
match.control = "none"
match.state = "autonomous_queued"
match.control_start = time.Now().Add(start_slack)
new_signal := NewSignal(match, "autonomous_queued")
go SendUpdate(match, new_signal)
return "wait", nil
}
match.handlers["start_autonomous"] = func(signal GraphSignal) (string, error) {
if match.state != "autonomous_queued" {
log.Logf("vex", "BAD_STATE: %s: %s - %s", signal.Type(), match.state, match.Name())
return "wait", nil
}
log.Logf("vex", "AUTONOMOUS_RUNNING: %s", match.Name())
match.control = "program"
match.state = "autonomous_running"
match.control_start = time.Now() // TODO
match.control_duration = TEMP_AUTON_TIME
go SendUpdate(match, NewSignal(match, "autonomous_running"))
end_time := match.control_start.Add(TEMP_AUTON_TIME)
match.SetTimeout(end_time, "autonomous_done")
log.Logf("vex", "AUTONOMOUS@%s: %s UNTIL %s", time.Now(), match.control_start, end_time)
return "wait", nil
}
match.handlers["autonomous_done"] = func(signal GraphSignal) (string, error) {
if match.state != "autonomous_running" {
log.Logf("vex", "BAD_STATE: %s: %s - %s", signal.Type(), match.state, match.Name())
return "wait", nil
}
log.Logf("vex", "AUTONOMOUS_DONE: %s", match.Name())
match.control = "none"
match.state = "autonomous_done"
return "wait", nil
}
match.handlers["queue_driver"] = func(signal GraphSignal) (string, error) {
if match.state != "autonomous_done"{
log.Logf("vex", "BAD_STATE: %s: %s - %s", signal.Type(), match.state, match.Name())
return "wait", nil
}
match.control = "none"
match.state = "driver_queued"
match.control_start = time.Now().Add(start_slack)
new_signal := NewSignal(match, "driver_queued")
go SendUpdate(match, new_signal)
return "wait", nil
}
match.handlers["start_driver"] = func(signal GraphSignal) (string, error) {
if match.state != "driver_queued" {
log.Logf("vex", "BAD_STATE: %s: %s - %s", signal.Type(), match.state, match.Name())
return "wait", nil
}
match.control = "driver"
match.state = "driver_running"
match.control_start = time.Now() // TODO
match.control_duration = TEMP_DRIVE_TIME
go SendUpdate(match, NewSignal(match, "driver_running"))
end_time := match.control_start.Add(TEMP_DRIVE_TIME)
match.SetTimeout(end_time, "driver_done")
return "wait", nil
}
match.handlers["driver_done"] = func(signal GraphSignal) (string, error) {
if match.state != "driver_running" {
log.Logf("vex", "BAD_STATE: %s: %s - %s", signal.Type(), match.state, match.Name())
return "wait", nil
}
match.control = "none"
match.state = "driver_done"
return "", nil
}
match.actions["driver_done"] = func() (string, error) {
SendUpdate(match, NewSignal(match, "driver_done"))
return "wait", nil
}
match.actions["autonomous_done"] = func() (string, error) {
SendUpdate(match, NewSignal(match, "autonomous_done"))
return "wait", nil
}
return match
}

@ -1,174 +0,0 @@
package main
import (
"testing"
"fmt"
"runtime/pprof"
"os"
"time"
)
type vex_tester graph_tester
func TestNewMemberAdd(t *testing.T) {
name := "Noah"
member := NewMember(name)
root_event := NewEvent("", "", []Resource{member})
event_manager := NewEventManager(root_event, []Resource{member})
res := event_manager.FindResource(member.ID())
if res == nil {
t.Fatal("Failed to find member in event_manager")
}
if res.Name() != name || res.ID() != member.ID() {
t.Fatal("Name/ID of returned resource did not match")
}
}
func TestNewTeamAdd(t *testing.T) {
name_1 := "Noah"
name_2 := "Ben"
org := "6659"
team_id := "S"
member_1 := NewMember(name_1)
member_2 := NewMember(name_2)
team := NewTeam(org, team_id, []*Member{member_1, member_2})
root_event := NewEvent("", "", []Resource{team})
event_manager := NewEventManager(root_event, []Resource{member_1, member_2, team})
res := event_manager.FindResource(team.ID())
if res == nil {
t.Fatal("Failed to find team in event_manager")
}
if res.Name() != fmt.Sprintf("%s%s", org, team_id) || res.ID() != team.ID() {
t.Fatal("Name/ID of returned team did not match")
}
if res.Children()[0].ID() != member_1.ID() && res.Children()[1].ID() != member_1.ID() {
t.Fatal("Could not find member_1 in team")
}
if res.Children()[0].ID() != member_2.ID() && res.Children()[1].ID() != member_2.ID() {
t.Fatal("Could not find member_2 in team")
}
res = event_manager.FindResource(member_1.ID())
if res == nil {
t.Fatal("Failed to find member_1 in event_manager")
}
if res.Name() != name_1 || res.ID() != member_1.ID() {
t.Fatal("Name/ID of returned member_1 did not match")
}
}
func TestNewAllianceAdd(t *testing.T) {
name_1 := "Noah"
name_2 := "Ben"
org_1 := "6659"
team_id_1 := "S"
org_2 := "210"
team_id_2 := "Y"
member_1 := NewMember(name_1)
member_2 := NewMember(name_2)
team_1 := NewTeam(org_1, team_id_1, []*Member{member_1})
team_2 := NewTeam(org_2, team_id_2, []*Member{member_2})
alliance := NewAlliance(team_1, team_2)
root_event := NewEvent("", "", []Resource{alliance})
event_manager := NewEventManager(root_event, []Resource{member_1, member_2, team_1, team_2, alliance})
res := event_manager.FindResource(alliance.ID())
if res == nil {
t.Fatal("Failed to find alliance in event_manager")
}
if res.Name() != fmt.Sprintf("Alliance %s/%s", team_1.Name(), team_2.Name()) || res.ID() != alliance.ID() {
t.Fatal("Name/ID of returned alliance did not match")
}
}
func TestNewMatch(t *testing.T) {
name_1 := "Noah"
name_2 := "Ben"
name_3 := "Justin"
name_4 := "Ian"
org_1 := "6659"
org_2 := "210"
team_id_1 := "S"
team_id_2 := "Y"
arena_name := "Center Arena"
member_1 := NewMember(name_1)
member_2 := NewMember(name_2)
member_3 := NewMember(name_3)
member_4 := NewMember(name_4)
team_1 := NewTeam(org_1, team_id_1, []*Member{member_1})
team_2 := NewTeam(org_1, team_id_2, []*Member{member_2})
team_3 := NewTeam(org_2, team_id_1, []*Member{member_3})
team_4 := NewTeam(org_2, team_id_2, []*Member{member_4})
alliance_1 := NewAlliance(team_1, team_2)
alliance_2 := NewAlliance(team_3, team_4)
arena := NewVirtualArena(arena_name)
arena_c := arena.UpdateChannel()
match := NewMatch(alliance_1, alliance_2, arena)
root_event := NewEventQueue("root_event", "", []Resource{})
r := root_event.DoneResource()
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})
event_manager.AddEvent(root_event, match, NewEventQueueInfo(1))
go func() {
time.Sleep(time.Second * 20)
if r.Owner() != nil {
pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
abort_signal := NewDownSignal(root_event, "abort")
SendUpdate(root_event, abort_signal)
}
}()
go func(arena_c chan GraphSignal) {
(*graph_tester)(t).WaitForValue(arena_c, "event_start", match, 1*time.Second, "no event_start")
SendUpdate(arena, NewDownSignal(nil, "queue_autonomous"))
(*graph_tester)(t).WaitForValue(arena_c, "autonomous_queued", match, 1*time.Second, "no autonomous_queued")
auton_signal := NewDownSignal(nil, "start_autonomous")
SendUpdate(arena, auton_signal)
(*graph_tester)(t).WaitForValue(arena_c, "autonomous_running", match, 1*time.Second, "no autonomous_running")
(*graph_tester)(t).WaitForValue(arena_c, "autonomous_done", match, 6*time.Second, "no autonomous_done")
SendUpdate(arena, NewDownSignal(nil, "queue_driver"))
(*graph_tester)(t).WaitForValue(arena_c, "driver_queued", match, 1*time.Second, "no driver_queued")
driver_signal := NewDownSignal(nil, "start_driver")
SendUpdate(arena, driver_signal)
(*graph_tester)(t).WaitForValue(arena_c, "driver_running", match, 1*time.Second, "no driver_running")
(*graph_tester)(t).WaitForValue(arena_c, "driver_done", match, 6*time.Second, "no driver_done")
cancel_signal := NewDownSignal(nil, "cancel")
SendUpdate(root_event, cancel_signal)
}(arena_c)
err := event_manager.Run()
if err != nil {
t.Fatal(err)
}
}