mirror of
https://github.com/Team254/cheesy-arena-lite.git
synced 2026-03-09 13:46:44 -04:00
Updated referee display and optimized for iPad.
This commit is contained in:
1
arena.go
1
arena.go
@@ -46,7 +46,6 @@ type MatchTiming struct {
|
||||
|
||||
type RealtimeScore struct {
|
||||
CurrentScore Score
|
||||
Fouls []Foul
|
||||
Cards map[string]string
|
||||
AutoCommitted bool
|
||||
TeleopCommitted bool
|
||||
|
||||
@@ -200,6 +200,9 @@ func scoreSummary(score *Score) *ScoreSummary {
|
||||
summary.FoulPoints = 6 * len(score.Fouls)
|
||||
|
||||
summary.Score = summary.AutoPoints + summary.StackPoints + summary.CoopertitionPoints - summary.FoulPoints
|
||||
if summary.Score < 0 {
|
||||
summary.Score = 0
|
||||
}
|
||||
|
||||
return summary
|
||||
}
|
||||
|
||||
@@ -74,8 +74,8 @@ func RefereeDisplayHandler(w http.ResponseWriter, r *http.Request) {
|
||||
Rules []string
|
||||
EntryEnabled bool
|
||||
}{eventSettings, matchType, match.DisplayName, red1, red2, red3, blue1, blue2, blue3,
|
||||
mainArena.redRealtimeScore.Fouls, mainArena.blueRealtimeScore.Fouls, mainArena.redRealtimeScore.Cards,
|
||||
mainArena.blueRealtimeScore.Cards, rules,
|
||||
mainArena.redRealtimeScore.CurrentScore.Fouls, mainArena.blueRealtimeScore.CurrentScore.Fouls,
|
||||
mainArena.redRealtimeScore.Cards, mainArena.blueRealtimeScore.Cards, rules,
|
||||
!(mainArena.redRealtimeScore.FoulsCommitted && mainArena.blueRealtimeScore.FoulsCommitted)}
|
||||
err = template.ExecuteTemplate(w, "referee_display.html", data)
|
||||
if err != nil {
|
||||
@@ -157,9 +157,11 @@ func RefereeDisplayWebsocketHandler(w http.ResponseWriter, r *http.Request) {
|
||||
// Add the foul to the correct alliance's list.
|
||||
foul := Foul{TeamId: args.TeamId, Rule: args.Rule, TimeInMatchSec: mainArena.MatchTimeSec()}
|
||||
if args.Alliance == "red" {
|
||||
mainArena.redRealtimeScore.Fouls = append(mainArena.redRealtimeScore.Fouls, foul)
|
||||
mainArena.redRealtimeScore.CurrentScore.Fouls =
|
||||
append(mainArena.redRealtimeScore.CurrentScore.Fouls, foul)
|
||||
} else {
|
||||
mainArena.blueRealtimeScore.Fouls = append(mainArena.blueRealtimeScore.Fouls, foul)
|
||||
mainArena.blueRealtimeScore.CurrentScore.Fouls =
|
||||
append(mainArena.blueRealtimeScore.CurrentScore.Fouls, foul)
|
||||
}
|
||||
mainArena.realtimeScoreNotifier.Notify(nil)
|
||||
case "deleteFoul":
|
||||
@@ -180,9 +182,9 @@ func RefereeDisplayWebsocketHandler(w http.ResponseWriter, r *http.Request) {
|
||||
deleteFoul := Foul{TeamId: args.TeamId, Rule: args.Rule, TimeInMatchSec: args.TimeInMatchSec}
|
||||
var fouls *[]Foul
|
||||
if args.Alliance == "red" {
|
||||
fouls = &mainArena.redRealtimeScore.Fouls
|
||||
fouls = &mainArena.redRealtimeScore.CurrentScore.Fouls
|
||||
} else {
|
||||
fouls = &mainArena.blueRealtimeScore.Fouls
|
||||
fouls = &mainArena.blueRealtimeScore.CurrentScore.Fouls
|
||||
}
|
||||
for i, foul := range *fouls {
|
||||
if foul == deleteFoul {
|
||||
|
||||
@@ -60,17 +60,17 @@ func TestRefereeDisplayWebsocket(t *testing.T) {
|
||||
readWebsocketType(t, ws, "reload")
|
||||
readWebsocketType(t, ws, "reload")
|
||||
readWebsocketType(t, ws, "reload")
|
||||
if assert.Equal(t, 2, len(mainArena.redRealtimeScore.Fouls)) {
|
||||
assert.Equal(t, 256, mainArena.redRealtimeScore.Fouls[0].TeamId)
|
||||
assert.Equal(t, "G22", mainArena.redRealtimeScore.Fouls[0].Rule)
|
||||
assert.Equal(t, 0.0, mainArena.redRealtimeScore.Fouls[0].TimeInMatchSec)
|
||||
assert.Equal(t, 359, mainArena.redRealtimeScore.Fouls[1].TeamId)
|
||||
assert.Equal(t, "G22", mainArena.redRealtimeScore.Fouls[1].Rule)
|
||||
if assert.Equal(t, 2, len(mainArena.redRealtimeScore.CurrentScore.Fouls)) {
|
||||
assert.Equal(t, 256, mainArena.redRealtimeScore.CurrentScore.Fouls[0].TeamId)
|
||||
assert.Equal(t, "G22", mainArena.redRealtimeScore.CurrentScore.Fouls[0].Rule)
|
||||
assert.Equal(t, 0.0, mainArena.redRealtimeScore.CurrentScore.Fouls[0].TimeInMatchSec)
|
||||
assert.Equal(t, 359, mainArena.redRealtimeScore.CurrentScore.Fouls[1].TeamId)
|
||||
assert.Equal(t, "G22", mainArena.redRealtimeScore.CurrentScore.Fouls[1].Rule)
|
||||
}
|
||||
if assert.Equal(t, 1, len(mainArena.blueRealtimeScore.Fouls)) {
|
||||
assert.Equal(t, 1680, mainArena.blueRealtimeScore.Fouls[0].TeamId)
|
||||
assert.Equal(t, "G22", mainArena.blueRealtimeScore.Fouls[0].Rule)
|
||||
assert.Equal(t, 0.0, mainArena.blueRealtimeScore.Fouls[0].TimeInMatchSec)
|
||||
if assert.Equal(t, 1, len(mainArena.blueRealtimeScore.CurrentScore.Fouls)) {
|
||||
assert.Equal(t, 1680, mainArena.blueRealtimeScore.CurrentScore.Fouls[0].TeamId)
|
||||
assert.Equal(t, "G22", mainArena.blueRealtimeScore.CurrentScore.Fouls[0].Rule)
|
||||
assert.Equal(t, 0.0, mainArena.blueRealtimeScore.CurrentScore.Fouls[0].TimeInMatchSec)
|
||||
}
|
||||
assert.False(t, mainArena.redRealtimeScore.FoulsCommitted)
|
||||
assert.False(t, mainArena.blueRealtimeScore.FoulsCommitted)
|
||||
@@ -78,17 +78,17 @@ func TestRefereeDisplayWebsocket(t *testing.T) {
|
||||
// Test foul deletion.
|
||||
ws.Write("deleteFoul", foulData)
|
||||
readWebsocketType(t, ws, "reload")
|
||||
assert.Equal(t, 0, len(mainArena.blueRealtimeScore.Fouls))
|
||||
assert.Equal(t, 0, len(mainArena.blueRealtimeScore.CurrentScore.Fouls))
|
||||
foulData.Alliance = "red"
|
||||
foulData.TeamId = 359
|
||||
foulData.TimeInMatchSec = 29 // Make it not match.
|
||||
ws.Write("deleteFoul", foulData)
|
||||
readWebsocketType(t, ws, "reload")
|
||||
assert.Equal(t, 2, len(mainArena.redRealtimeScore.Fouls))
|
||||
assert.Equal(t, 2, len(mainArena.redRealtimeScore.CurrentScore.Fouls))
|
||||
foulData.TimeInMatchSec = 0
|
||||
ws.Write("deleteFoul", foulData)
|
||||
readWebsocketType(t, ws, "reload")
|
||||
assert.Equal(t, 1, len(mainArena.redRealtimeScore.Fouls))
|
||||
assert.Equal(t, 1, len(mainArena.redRealtimeScore.CurrentScore.Fouls))
|
||||
|
||||
// Test card setting.
|
||||
cardData := struct {
|
||||
|
||||
@@ -17,15 +17,15 @@ h3, h4 {
|
||||
color: #fff;
|
||||
}
|
||||
.btn-referee {
|
||||
width: 120px;
|
||||
width: 100px;
|
||||
margin: 5px 5px;
|
||||
font-size: 30px;
|
||||
font-size: 25px;
|
||||
cursor: default;
|
||||
}
|
||||
.btn-referee-wide {
|
||||
width: 254px;
|
||||
margin: 5px 5px;
|
||||
font-size: 30px;
|
||||
font-size: 25px;
|
||||
}
|
||||
.btn {
|
||||
cursor: default;
|
||||
|
||||
@@ -4,21 +4,29 @@
|
||||
// Client-side logic for the referee interface.
|
||||
|
||||
var websocket;
|
||||
var foulAlliance;
|
||||
var foulTeam;
|
||||
var foulRule;
|
||||
var foulTeamButton;
|
||||
var foulRuleButton;
|
||||
|
||||
// Handles a click on a team button.
|
||||
var setFoulTeam = function(teamButton) {
|
||||
foulAlliance = $(teamButton).attr("data-alliance");
|
||||
foulTeam = $(teamButton).attr("data-team");
|
||||
setSelections();
|
||||
if (foulTeamButton) {
|
||||
foulTeamButton.attr("data-selected", false);
|
||||
}
|
||||
foulTeamButton = $(teamButton);
|
||||
foulTeamButton.attr("data-selected", true);
|
||||
|
||||
$("#commit").prop("disabled", !(foulTeamButton && foulRuleButton));
|
||||
};
|
||||
|
||||
// Handles a click on a rule button.
|
||||
var setFoulRule = function(ruleButton) {
|
||||
foulRule = $(ruleButton).attr("data-rule");
|
||||
setSelections();
|
||||
if (foulRuleButton) {
|
||||
foulRuleButton.attr("data-selected", false);
|
||||
}
|
||||
foulRuleButton = $(ruleButton);
|
||||
foulRuleButton.attr("data-selected", true);
|
||||
|
||||
$("#commit").prop("disabled", !(foulTeamButton && foulRuleButton));
|
||||
};
|
||||
|
||||
// Sets button styles to match the selection cached in the global variables.
|
||||
@@ -30,20 +38,25 @@ var setSelections = function() {
|
||||
$("[data-rule]").each(function(i, ruleButton) {
|
||||
$(ruleButton).attr("data-selected", $(ruleButton).attr("data-rule") == foulRule);
|
||||
});
|
||||
|
||||
$("#commit").prop("disabled", (foulTeam == "" || foulRule == ""));
|
||||
};
|
||||
|
||||
// Resets the buttons to their default selections.
|
||||
var clearFoul = function() {
|
||||
foulTeam = "";
|
||||
foulRule = "";
|
||||
setSelections();
|
||||
if (foulTeamButton) {
|
||||
foulTeamButton.attr("data-selected", false);
|
||||
foulTeamButton = null;
|
||||
}
|
||||
if (foulRuleButton) {
|
||||
foulRuleButton.attr("data-selected", false);
|
||||
foulRuleButton = null;
|
||||
}
|
||||
$("#commit").prop("disabled", true);
|
||||
};
|
||||
|
||||
// Sends the foul to the server to add it to the list.
|
||||
var commitFoul = function() {
|
||||
websocket.send("addFoul", {Alliance: foulAlliance, TeamId: parseInt(foulTeam), Rule: foulRule});
|
||||
websocket.send("addFoul", {Alliance: foulTeamButton.attr("data-alliance"),
|
||||
TeamId: parseInt(foulTeamButton.attr("data-team")), Rule: foulRuleButton.attr("data-rule")});
|
||||
};
|
||||
|
||||
// Removes the foul with the given parameters from the list.
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<title>Referee Display - {{.EventSettings.Name}} - Cheesy Arena</title>
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<link rel="shortcut icon" href="/static/img/favicon.png">
|
||||
<link rel="apple-touch-icon" href="/static/img/apple-icon.png">
|
||||
<link href="/static/css/lib/bootstrap.min.css" rel="stylesheet">
|
||||
@@ -22,7 +23,7 @@
|
||||
{{if .EntryEnabled}}
|
||||
<h3 style="margin-top: 0">{{.MatchType}} Match {{.MatchDisplayName}}</h3>
|
||||
<div class="row">
|
||||
<div class="col-lg-3">
|
||||
<div class="col-xs-3">
|
||||
<h4>Fouls</h4>
|
||||
<table class="table">
|
||||
{{range $foul := .RedFouls}}
|
||||
@@ -40,7 +41,7 @@
|
||||
{{template "card" dict "team" .Blue2 "alliance" "blue" "cards" .BlueCards}}
|
||||
{{template "card" dict "team" .Blue3 "alliance" "blue" "cards" .BlueCards}}
|
||||
</div>
|
||||
<div class="col-lg-9">
|
||||
<div class="col-xs-9">
|
||||
<h4>Add Foul</h4>
|
||||
<div class="row">
|
||||
<a class="btn btn-lg btn-primary btn-referee" data-alliance="red" data-team="{{.Red1.Id}}"
|
||||
@@ -62,6 +63,7 @@
|
||||
onclick="setFoulRule(this);">{{$rule}}</a>
|
||||
{{end}}
|
||||
</div>
|
||||
<br />
|
||||
<div class="row text-center">
|
||||
<a class="btn btn-lg btn-default btn-referee btn-referee-wide" onclick="clearFoul();">Clear Foul</a>
|
||||
<button type="button" class="btn btn-lg btn-success btn-referee btn-referee-wide" id="commit"
|
||||
@@ -73,6 +75,11 @@
|
||||
<a class="btn btn-lg btn-info btn-referee btn-referee-wide"
|
||||
onclick="commitMatch();">Commit Match</a>
|
||||
</div>
|
||||
<br />
|
||||
<div class="row text-center">
|
||||
<a class="btn btn-lg btn-danger btn-referee btn-referee-wide"
|
||||
onclick="location.reload();">Refresh</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
@@ -83,7 +90,6 @@
|
||||
<script src="/static/js/lib/jquery.min.js"></script>
|
||||
<script src="/static/js/lib/jquery.json-2.4.min.js"></script>
|
||||
<script src="/static/js/lib/jquery.websocket-0.0.1.js"></script>
|
||||
<script src="/static/js/lib/bootstrap.min.js"></script>
|
||||
<script src="/static/js/cheesy-websocket.js"></script>
|
||||
<script src="/static/js/referee_display.js"></script>
|
||||
</body>
|
||||
@@ -97,7 +103,7 @@
|
||||
</tr>
|
||||
{{end}}
|
||||
{{define "card"}}
|
||||
<a class="btn btn-lg btn-card" data-old-yellow-card="{{.team.YellowCard}}" data-alliance="{{.alliance}}"
|
||||
<a class="btn btn-md btn-card" data-old-yellow-card="{{.team.YellowCard}}" data-alliance="{{.alliance}}"
|
||||
data-card-team="{{.team.Id}}" data-card="{{index .cards (print .team.Id)}}"
|
||||
onclick="cycleCard(this);">{{.team.Id}}</a><br />
|
||||
{{end}}
|
||||
|
||||
Reference in New Issue
Block a user