mirror of
https://github.com/Team254/cheesy-arena-lite.git
synced 2026-03-10 14:16:47 -04:00
Remove game-specific scoring
This commit is contained in:
152
field/arena.go
Normal file → Executable file
152
field/arena.go
Normal file → Executable file
@@ -52,15 +52,14 @@ type Arena struct {
|
||||
TbaClient *partner.TbaClient
|
||||
AllianceStations map[string]*AllianceStation
|
||||
Displays map[string]*Display
|
||||
ScoringPanelRegistry
|
||||
ArenaNotifiers
|
||||
MatchState
|
||||
lastMatchState MatchState
|
||||
CurrentMatch *model.Match
|
||||
MatchStartTime time.Time
|
||||
LastMatchTimeSec float64
|
||||
RedRealtimeScore *RealtimeScore
|
||||
BlueRealtimeScore *RealtimeScore
|
||||
RedScore *game.Score
|
||||
BlueScore *game.Score
|
||||
lastDsPacketTime time.Time
|
||||
lastPeriodicTaskTime time.Time
|
||||
EventStatus EventStatus
|
||||
@@ -113,8 +112,6 @@ func NewArena(dbPath string) (*Arena, error) {
|
||||
|
||||
arena.Displays = make(map[string]*Display)
|
||||
|
||||
arena.ScoringPanelRegistry.initialize()
|
||||
|
||||
// Load empty match as current.
|
||||
arena.MatchState = PreMatch
|
||||
arena.LoadTestMatch()
|
||||
@@ -164,10 +161,6 @@ func (arena *Arena) LoadSettings() error {
|
||||
game.UpdateMatchSounds()
|
||||
arena.MatchTimingNotifier.Notify()
|
||||
|
||||
game.StageCapacities[game.Stage1] = settings.Stage1Capacity
|
||||
game.StageCapacities[game.Stage2] = settings.Stage2Capacity
|
||||
game.StageCapacities[game.Stage3] = settings.Stage3Capacity
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -207,13 +200,12 @@ func (arena *Arena) LoadMatch(match *model.Match) error {
|
||||
arena.AllianceStations["R3"].Team, arena.AllianceStations["B1"].Team, arena.AllianceStations["B2"].Team,
|
||||
arena.AllianceStations["B3"].Team})
|
||||
|
||||
// Reset the arena state and realtime scores.
|
||||
// Reset the arena state and game scores.
|
||||
arena.soundsPlayed = make(map[*game.MatchSound]struct{})
|
||||
arena.RedRealtimeScore = NewRealtimeScore()
|
||||
arena.BlueRealtimeScore = NewRealtimeScore()
|
||||
arena.RedScore = new(game.Score)
|
||||
arena.BlueScore = new(game.Score)
|
||||
arena.FieldVolunteers = false
|
||||
arena.FieldReset = false
|
||||
arena.ScoringPanelRegistry.resetScoreCommitted()
|
||||
|
||||
// Notify any listeners about the new match.
|
||||
arena.MatchLoadNotifier.Notify()
|
||||
@@ -522,14 +514,12 @@ func (arena *Arena) Run() {
|
||||
|
||||
// Calculates the red alliance score summary for the given realtime snapshot.
|
||||
func (arena *Arena) RedScoreSummary() *game.ScoreSummary {
|
||||
return arena.RedRealtimeScore.CurrentScore.Summarize(arena.BlueRealtimeScore.CurrentScore.Fouls,
|
||||
arena.MatchState >= TeleopPeriod)
|
||||
return arena.RedScore.Summarize()
|
||||
}
|
||||
|
||||
// Calculates the blue alliance score summary for the given realtime snapshot.
|
||||
func (arena *Arena) BlueScoreSummary() *game.ScoreSummary {
|
||||
return arena.BlueRealtimeScore.CurrentScore.Summarize(arena.RedRealtimeScore.CurrentScore.Fouls,
|
||||
arena.MatchState >= TeleopPeriod)
|
||||
return arena.BlueScore.Summarize()
|
||||
}
|
||||
|
||||
// Loads a team into an alliance station, cleaning up the previous team there if there is one.
|
||||
@@ -704,23 +694,6 @@ func (arena *Arena) sendDsPacket(auto bool, enabled bool) {
|
||||
arena.lastDsPacketTime = time.Now()
|
||||
}
|
||||
|
||||
// Sends a game data packet encoded with the given Control Panel target color to the given stations.
|
||||
func (arena *Arena) sendGameDataPacket(color game.ControlPanelColor, stations ...string) {
|
||||
gameData := game.GetGameDataForColor(color)
|
||||
log.Printf("Sending game data packet '%s' to stations %v", gameData, stations)
|
||||
for _, station := range stations {
|
||||
if allianceStation, ok := arena.AllianceStations[station]; ok {
|
||||
dsConn := allianceStation.DsConn
|
||||
if dsConn != nil {
|
||||
err := dsConn.sendGameDataPacket(gameData)
|
||||
if err != nil {
|
||||
log.Printf("Error sending game data packet to Team %d: %v", dsConn.TeamId, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the alliance station identifier for the given team, or the empty string if the team is not present
|
||||
// in the current match.
|
||||
func (arena *Arena) getAssignedAllianceStation(teamId int) string {
|
||||
@@ -759,79 +732,10 @@ func (arena *Arena) handlePlcInput() {
|
||||
// Don't do anything if we're outside the match, otherwise we may overwrite manual edits.
|
||||
return
|
||||
}
|
||||
|
||||
redScore := &arena.RedRealtimeScore.CurrentScore
|
||||
oldRedScore := *redScore
|
||||
blueScore := &arena.BlueRealtimeScore.CurrentScore
|
||||
oldBlueScore := *blueScore
|
||||
matchStartTime := arena.MatchStartTime
|
||||
currentTime := time.Now()
|
||||
teleopStarted := arena.MatchState >= TeleopPeriod
|
||||
|
||||
if arena.Plc.IsEnabled() {
|
||||
// Handle power ports.
|
||||
redPortCells, bluePortCells := arena.Plc.GetPowerPorts()
|
||||
redPowerPort := &arena.RedRealtimeScore.powerPort
|
||||
redPowerPort.UpdateState(redPortCells, redScore.CellCountingStage(teleopStarted), matchStartTime, currentTime)
|
||||
redScore.AutoCellsBottom = redPowerPort.AutoCellsBottom
|
||||
redScore.AutoCellsOuter = redPowerPort.AutoCellsOuter
|
||||
redScore.AutoCellsInner = redPowerPort.AutoCellsInner
|
||||
redScore.TeleopCellsBottom = redPowerPort.TeleopCellsBottom
|
||||
redScore.TeleopCellsOuter = redPowerPort.TeleopCellsOuter
|
||||
redScore.TeleopCellsInner = redPowerPort.TeleopCellsInner
|
||||
bluePowerPort := &arena.BlueRealtimeScore.powerPort
|
||||
bluePowerPort.UpdateState(bluePortCells, blueScore.CellCountingStage(teleopStarted), matchStartTime,
|
||||
currentTime)
|
||||
blueScore.AutoCellsBottom = bluePowerPort.AutoCellsBottom
|
||||
blueScore.AutoCellsOuter = bluePowerPort.AutoCellsOuter
|
||||
blueScore.AutoCellsInner = bluePowerPort.AutoCellsInner
|
||||
blueScore.TeleopCellsBottom = bluePowerPort.TeleopCellsBottom
|
||||
blueScore.TeleopCellsOuter = bluePowerPort.TeleopCellsOuter
|
||||
blueScore.TeleopCellsInner = bluePowerPort.TeleopCellsInner
|
||||
|
||||
// Handle control panel.
|
||||
redColor, redSegmentCount, blueColor, blueSegmentCount := arena.Plc.GetControlPanels()
|
||||
redControlPanel := &arena.RedRealtimeScore.ControlPanel
|
||||
redControlPanel.CurrentColor = redColor
|
||||
redControlPanel.UpdateState(redSegmentCount, redScore.StageAtCapacity(game.Stage2, teleopStarted),
|
||||
redScore.StageAtCapacity(game.Stage3, teleopStarted), currentTime)
|
||||
redScore.ControlPanelStatus = redControlPanel.ControlPanelStatus
|
||||
blueControlPanel := &arena.BlueRealtimeScore.ControlPanel
|
||||
blueControlPanel.CurrentColor = blueColor
|
||||
blueControlPanel.UpdateState(blueSegmentCount, blueScore.StageAtCapacity(game.Stage2, teleopStarted),
|
||||
blueScore.StageAtCapacity(game.Stage3, teleopStarted), currentTime)
|
||||
blueScore.ControlPanelStatus = blueControlPanel.ControlPanelStatus
|
||||
|
||||
// Handle shield generator rungs.
|
||||
if game.ShouldAssessRung(matchStartTime, currentTime) {
|
||||
redScore.RungIsLevel, blueScore.RungIsLevel = arena.Plc.GetRungs()
|
||||
}
|
||||
}
|
||||
|
||||
// Check if either alliance has reached Stage 3 capacity.
|
||||
if redScore.StageAtCapacity(game.Stage3, arena.MatchState >= TeleopPeriod) &&
|
||||
redScore.PositionControlTargetColor == game.ColorUnknown ||
|
||||
blueScore.StageAtCapacity(game.Stage3, arena.MatchState >= TeleopPeriod) &&
|
||||
blueScore.PositionControlTargetColor == game.ColorUnknown {
|
||||
// Determine the position control target colors and send packets to inform the driver stations.
|
||||
redScore.PositionControlTargetColor = arena.RedRealtimeScore.ControlPanel.GetPositionControlTargetColor()
|
||||
blueScore.PositionControlTargetColor = arena.BlueRealtimeScore.ControlPanel.GetPositionControlTargetColor()
|
||||
arena.sendGameDataPacket(redScore.PositionControlTargetColor, "R1", "R2", "R3")
|
||||
arena.sendGameDataPacket(blueScore.PositionControlTargetColor, "B1", "B2", "B3")
|
||||
}
|
||||
|
||||
if !oldRedScore.Equals(redScore) || !oldBlueScore.Equals(blueScore) {
|
||||
arena.RealtimeScoreNotifier.Notify()
|
||||
}
|
||||
}
|
||||
|
||||
// Updates the PLC's coils based on its inputs and the current scoring state.
|
||||
func (arena *Arena) handlePlcOutput() {
|
||||
matchStartTime := arena.MatchStartTime
|
||||
currentTime := time.Now()
|
||||
redScore := &arena.RedRealtimeScore.CurrentScore
|
||||
blueScore := &arena.BlueRealtimeScore.CurrentScore
|
||||
|
||||
switch arena.MatchState {
|
||||
case PreMatch:
|
||||
if arena.lastMatchState != PreMatch {
|
||||
@@ -857,51 +761,18 @@ func (arena *Arena) handlePlcOutput() {
|
||||
if arena.FieldReset {
|
||||
arena.Plc.SetFieldResetLight(true)
|
||||
}
|
||||
scoreReady := arena.RedRealtimeScore.FoulsCommitted && arena.BlueRealtimeScore.FoulsCommitted &&
|
||||
arena.alliancePostMatchScoreReady("red") && arena.alliancePostMatchScoreReady("blue")
|
||||
arena.Plc.SetStackLights(false, false, !scoreReady, false)
|
||||
arena.Plc.SetStackLights(false, false, false, false)
|
||||
|
||||
if arena.lastMatchState != PostMatch {
|
||||
go func() {
|
||||
time.Sleep(time.Second * game.PowerPortTeleopGracePeriodSec)
|
||||
arena.Plc.SetPowerPortMotors(false)
|
||||
time.Sleep(time.Second)
|
||||
}()
|
||||
}
|
||||
arena.Plc.SetStageActivatedLights([3]bool{false, false, false}, [3]bool{false, false, false})
|
||||
arena.Plc.SetControlPanelLights(false, false)
|
||||
case AutoPeriod:
|
||||
arena.Plc.SetPowerPortMotors(true)
|
||||
fallthrough
|
||||
case PausePeriod:
|
||||
fallthrough
|
||||
case TeleopPeriod:
|
||||
arena.Plc.SetStageActivatedLights(arena.RedScoreSummary().StagesActivated,
|
||||
arena.BlueScoreSummary().StagesActivated)
|
||||
|
||||
controlPanelLightState := func(state game.ControlPanelLightState) bool {
|
||||
switch state {
|
||||
case game.ControlPanelLightOn:
|
||||
return true
|
||||
case game.ControlPanelLightFlashing:
|
||||
return arena.Plc.GetCycleState(2, 0, 2)
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
arena.Plc.SetControlPanelLights(
|
||||
controlPanelLightState(arena.RedRealtimeScore.ControlPanel.ControlPanelLightState),
|
||||
controlPanelLightState(arena.BlueRealtimeScore.ControlPanel.ControlPanelLightState))
|
||||
|
||||
// If the PLC reports a ball jam, blink the orange light and the power port color.
|
||||
redJam, blueJam := arena.Plc.GetPowerPortJams()
|
||||
blink := arena.Plc.GetCycleState(2, 0, 2)
|
||||
arena.Plc.SetStackLights(redJam && blink, blueJam && blink, (redJam || blueJam) && !blink, true)
|
||||
}
|
||||
|
||||
if game.ShouldAssessRung(matchStartTime, currentTime) {
|
||||
arena.Plc.SetShieldGeneratorLights(redScore.RungIsLevel, blueScore.RungIsLevel)
|
||||
} else {
|
||||
arena.Plc.SetShieldGeneratorLights(false, false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -950,11 +821,6 @@ func (arena *Arena) playSound(name string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (arena *Arena) alliancePostMatchScoreReady(alliance string) bool {
|
||||
numPanels := arena.ScoringPanelRegistry.GetNumPanels(alliance)
|
||||
return numPanels > 0 && arena.ScoringPanelRegistry.GetNumScoreCommitted(alliance) >= numPanels
|
||||
}
|
||||
|
||||
// Performs any actions that need to run at the interval specified by periodicTaskPeriodSec.
|
||||
func (arena *Arena) runPeriodicTasks() {
|
||||
arena.updateEarlyLateMessage()
|
||||
|
||||
52
field/arena_notifiers.go
Normal file → Executable file
52
field/arena_notifiers.go
Normal file → Executable file
@@ -29,7 +29,6 @@ type ArenaNotifiers struct {
|
||||
RealtimeScoreNotifier *websocket.Notifier
|
||||
ReloadDisplaysNotifier *websocket.Notifier
|
||||
ScorePostedNotifier *websocket.Notifier
|
||||
ScoringStatusNotifier *websocket.Notifier
|
||||
}
|
||||
|
||||
type MatchTimeMessage struct {
|
||||
@@ -40,7 +39,6 @@ type MatchTimeMessage struct {
|
||||
type audienceAllianceScoreFields struct {
|
||||
Score *game.Score
|
||||
ScoreSummary *game.ScoreSummary
|
||||
ControlPanel *game.ControlPanel
|
||||
}
|
||||
|
||||
// Instantiates notifiers and configures their message producing methods.
|
||||
@@ -62,7 +60,6 @@ func (arena *Arena) configureNotifiers() {
|
||||
arena.RealtimeScoreNotifier = websocket.NewNotifier("realtimeScore", arena.generateRealtimeScoreMessage)
|
||||
arena.ReloadDisplaysNotifier = websocket.NewNotifier("reload", nil)
|
||||
arena.ScorePostedNotifier = websocket.NewNotifier("scorePosted", arena.generateScorePostedMessage)
|
||||
arena.ScoringStatusNotifier = websocket.NewNotifier("scoringStatus", arena.generateScoringStatusMessage)
|
||||
}
|
||||
|
||||
func (arena *Arena) generateAllianceSelectionMessage() interface{} {
|
||||
@@ -160,8 +157,8 @@ func (arena *Arena) generateRealtimeScoreMessage() interface{} {
|
||||
Blue *audienceAllianceScoreFields
|
||||
MatchState
|
||||
}{}
|
||||
fields.Red = getAudienceAllianceScoreFields(arena.RedRealtimeScore, arena.RedScoreSummary())
|
||||
fields.Blue = getAudienceAllianceScoreFields(arena.BlueRealtimeScore, arena.BlueScoreSummary())
|
||||
fields.Red = getAudienceAllianceScoreFields(arena.RedScore, arena.RedScoreSummary())
|
||||
fields.Blue = getAudienceAllianceScoreFields(arena.BlueScore, arena.BlueScoreSummary())
|
||||
fields.MatchState = arena.MatchState
|
||||
return &fields
|
||||
}
|
||||
@@ -208,53 +205,18 @@ func (arena *Arena) generateScorePostedMessage() interface{} {
|
||||
RedScoreSummary *game.ScoreSummary
|
||||
BlueScoreSummary *game.ScoreSummary
|
||||
Rankings map[int]game.Ranking
|
||||
RedFouls []game.Foul
|
||||
BlueFouls []game.Foul
|
||||
RulesViolated map[int]*game.Rule
|
||||
RedCards map[string]string
|
||||
BlueCards map[string]string
|
||||
SeriesStatus string
|
||||
SeriesLeader string
|
||||
}{arena.SavedMatch.CapitalizedType(), arena.SavedMatch, arena.SavedMatchResult.RedScoreSummary(true),
|
||||
arena.SavedMatchResult.BlueScoreSummary(true), rankings, arena.SavedMatchResult.RedScore.Fouls,
|
||||
arena.SavedMatchResult.BlueScore.Fouls,
|
||||
getRulesViolated(arena.SavedMatchResult.RedScore.Fouls, arena.SavedMatchResult.BlueScore.Fouls),
|
||||
arena.SavedMatchResult.RedCards, arena.SavedMatchResult.BlueCards, seriesStatus, seriesLeader}
|
||||
}
|
||||
|
||||
func (arena *Arena) generateScoringStatusMessage() interface{} {
|
||||
return &struct {
|
||||
RefereeScoreReady bool
|
||||
RedScoreReady bool
|
||||
BlueScoreReady bool
|
||||
NumRedScoringPanels int
|
||||
NumRedScoringPanelsReady int
|
||||
NumBlueScoringPanels int
|
||||
NumBlueScoringPanelsReady int
|
||||
}{arena.RedRealtimeScore.FoulsCommitted && arena.BlueRealtimeScore.FoulsCommitted,
|
||||
arena.alliancePostMatchScoreReady("red"), arena.alliancePostMatchScoreReady("blue"),
|
||||
arena.ScoringPanelRegistry.GetNumPanels("red"), arena.ScoringPanelRegistry.GetNumScoreCommitted("red"),
|
||||
arena.ScoringPanelRegistry.GetNumPanels("blue"), arena.ScoringPanelRegistry.GetNumScoreCommitted("blue")}
|
||||
}{arena.SavedMatch.CapitalizedType(), arena.SavedMatch, arena.SavedMatchResult.RedScoreSummary(),
|
||||
arena.SavedMatchResult.BlueScoreSummary(), rankings,
|
||||
seriesStatus, seriesLeader}
|
||||
}
|
||||
|
||||
// Constructs the data object for one alliance sent to the audience display for the realtime scoring overlay.
|
||||
func getAudienceAllianceScoreFields(allianceScore *RealtimeScore,
|
||||
func getAudienceAllianceScoreFields(allianceScore *game.Score,
|
||||
allianceScoreSummary *game.ScoreSummary) *audienceAllianceScoreFields {
|
||||
fields := new(audienceAllianceScoreFields)
|
||||
fields.Score = &allianceScore.CurrentScore
|
||||
fields.Score = allianceScore
|
||||
fields.ScoreSummary = allianceScoreSummary
|
||||
fields.ControlPanel = &allianceScore.ControlPanel
|
||||
return fields
|
||||
}
|
||||
|
||||
// Produce a map of rules that were violated by either alliance so that they are available to the announcer.
|
||||
func getRulesViolated(redFouls, blueFouls []game.Foul) map[int]*game.Rule {
|
||||
rules := make(map[int]*game.Rule)
|
||||
for _, foul := range redFouls {
|
||||
rules[foul.RuleId] = game.GetRuleById(foul.RuleId)
|
||||
}
|
||||
for _, foul := range blueFouls {
|
||||
rules[foul.RuleId] = game.GetRuleById(foul.RuleId)
|
||||
}
|
||||
return rules
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
// Copyright 2017 Team 254. All Rights Reserved.
|
||||
// Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
//
|
||||
// Model representing the current state of the score during a match.
|
||||
|
||||
package field
|
||||
|
||||
import "github.com/Team254/cheesy-arena/game"
|
||||
|
||||
type RealtimeScore struct {
|
||||
CurrentScore game.Score
|
||||
Cards map[string]string
|
||||
FoulsCommitted bool
|
||||
powerPort game.PowerPort
|
||||
ControlPanel game.ControlPanel
|
||||
}
|
||||
|
||||
func NewRealtimeScore() *RealtimeScore {
|
||||
return &RealtimeScore{Cards: make(map[string]string)}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
// Copyright 2019 Team 254. All Rights Reserved.
|
||||
// Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
//
|
||||
// Model representing and methods for tracking the state of a realtime scoring panel.
|
||||
|
||||
package field
|
||||
|
||||
import (
|
||||
"github.com/Team254/cheesy-arena/websocket"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type ScoringPanelRegistry struct {
|
||||
scoringPanels map[string]map[*websocket.Websocket]bool // The score committed state for each panel.
|
||||
mutex sync.Mutex
|
||||
}
|
||||
|
||||
func (registry *ScoringPanelRegistry) initialize() {
|
||||
registry.scoringPanels = map[string]map[*websocket.Websocket]bool{"red": {}, "blue": {}}
|
||||
}
|
||||
|
||||
// Resets the score committed state for each registered panel to false.
|
||||
func (registry *ScoringPanelRegistry) resetScoreCommitted() {
|
||||
registry.mutex.Lock()
|
||||
defer registry.mutex.Unlock()
|
||||
|
||||
for _, alliancePanels := range registry.scoringPanels {
|
||||
for key := range alliancePanels {
|
||||
alliancePanels[key] = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the number of registered panels for the given alliance.
|
||||
func (registry *ScoringPanelRegistry) GetNumPanels(alliance string) int {
|
||||
registry.mutex.Lock()
|
||||
defer registry.mutex.Unlock()
|
||||
|
||||
return len(registry.scoringPanels[alliance])
|
||||
}
|
||||
|
||||
// Returns the number of registered panels whose score is committed for the given alliance.
|
||||
func (registry *ScoringPanelRegistry) GetNumScoreCommitted(alliance string) int {
|
||||
registry.mutex.Lock()
|
||||
defer registry.mutex.Unlock()
|
||||
|
||||
numCommitted := 0
|
||||
for _, panel := range registry.scoringPanels[alliance] {
|
||||
if panel {
|
||||
numCommitted++
|
||||
}
|
||||
}
|
||||
return numCommitted
|
||||
}
|
||||
|
||||
// Adds a panel to the registry, referenced by its websocket pointer.
|
||||
func (registry *ScoringPanelRegistry) RegisterPanel(alliance string, ws *websocket.Websocket) {
|
||||
registry.mutex.Lock()
|
||||
defer registry.mutex.Unlock()
|
||||
|
||||
registry.scoringPanels[alliance][ws] = false
|
||||
}
|
||||
|
||||
// Sets the score committed state to true for the given panel, referenced by its websocket pointer.
|
||||
func (registry *ScoringPanelRegistry) SetScoreCommitted(alliance string, ws *websocket.Websocket) {
|
||||
registry.mutex.Lock()
|
||||
defer registry.mutex.Unlock()
|
||||
|
||||
registry.scoringPanels[alliance][ws] = true
|
||||
}
|
||||
|
||||
// Removes a panel from the registry, referenced by its websocket pointer.
|
||||
func (registry *ScoringPanelRegistry) UnregisterPanel(alliance string, ws *websocket.Websocket) {
|
||||
registry.mutex.Lock()
|
||||
defer registry.mutex.Unlock()
|
||||
|
||||
delete(registry.scoringPanels[alliance], ws)
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
// Copyright 2019 Team 254. All Rights Reserved.
|
||||
// Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
|
||||
package field
|
||||
|
||||
import (
|
||||
"github.com/Team254/cheesy-arena/websocket"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestScoringPanelRegistry(t *testing.T) {
|
||||
var registry ScoringPanelRegistry
|
||||
registry.initialize()
|
||||
assert.Equal(t, 0, registry.GetNumPanels("red"))
|
||||
assert.Equal(t, 0, registry.GetNumScoreCommitted("red"))
|
||||
assert.Equal(t, 0, registry.GetNumPanels("blue"))
|
||||
assert.Equal(t, 0, registry.GetNumScoreCommitted("blue"))
|
||||
|
||||
ws1 := new(websocket.Websocket)
|
||||
ws2 := new(websocket.Websocket)
|
||||
ws3 := new(websocket.Websocket)
|
||||
registry.RegisterPanel("red", ws1)
|
||||
registry.RegisterPanel("blue", ws2)
|
||||
registry.RegisterPanel("red", ws3)
|
||||
assert.Equal(t, 2, registry.GetNumPanels("red"))
|
||||
assert.Equal(t, 0, registry.GetNumScoreCommitted("red"))
|
||||
assert.Equal(t, 1, registry.GetNumPanels("blue"))
|
||||
assert.Equal(t, 0, registry.GetNumScoreCommitted("blue"))
|
||||
|
||||
registry.SetScoreCommitted("red", ws3)
|
||||
registry.SetScoreCommitted("blue", ws2)
|
||||
registry.SetScoreCommitted("blue", ws2)
|
||||
assert.Equal(t, 2, registry.GetNumPanels("red"))
|
||||
assert.Equal(t, 1, registry.GetNumScoreCommitted("red"))
|
||||
assert.Equal(t, 1, registry.GetNumPanels("blue"))
|
||||
assert.Equal(t, 1, registry.GetNumScoreCommitted("blue"))
|
||||
|
||||
registry.UnregisterPanel("red", ws1)
|
||||
registry.UnregisterPanel("blue", ws2)
|
||||
assert.Equal(t, 1, registry.GetNumPanels("red"))
|
||||
assert.Equal(t, 1, registry.GetNumScoreCommitted("red"))
|
||||
assert.Equal(t, 0, registry.GetNumPanels("blue"))
|
||||
assert.Equal(t, 0, registry.GetNumScoreCommitted("blue"))
|
||||
|
||||
registry.resetScoreCommitted()
|
||||
assert.Equal(t, 1, registry.GetNumPanels("red"))
|
||||
assert.Equal(t, 0, registry.GetNumScoreCommitted("red"))
|
||||
assert.Equal(t, 0, registry.GetNumPanels("blue"))
|
||||
assert.Equal(t, 0, registry.GetNumScoreCommitted("blue"))
|
||||
}
|
||||
Reference in New Issue
Block a user