Parallele_Verteilte_Systeme/go/TrafficLights/TrafficLight.go

152 lines
2.6 KiB
Go

package main
import (
"fmt"
)
var printDebugMessages = false
type CardinalDirection string
const (
north = CardinalDirection("North")
south = CardinalDirection("South")
east = CardinalDirection("East")
west = CardinalDirection("West")
)
func nextDirection(currentDirection CardinalDirection) CardinalDirection {
switch currentDirection {
case north:
return east
case east:
return south
case south:
return west
case west:
return north
}
return north
}
func oppositeDirection(currentDirection CardinalDirection) CardinalDirection {
switch currentDirection {
case north:
return south
case east:
return west
case south:
return north
case west:
return east
}
return north
}
type Colour int
const (
red Colour = iota
green
yellow
)
func (colour Colour) String() string {
switch colour {
case red:
return "Red"
case yellow:
return "Yellow"
case green:
return "Green"
default:
return "null"
}
}
func nextColour(colour Colour) Colour {
return (colour + 1) % (yellow + 1)
}
var northChannel = make(chan string)
var southChannel = make(chan string)
var eastChannel = make(chan string)
var westChannel = make(chan string)
func getChannel(direction CardinalDirection) chan string {
switch direction {
case north:
return northChannel
case south:
return northChannel
case east:
return eastChannel
case west:
return eastChannel
}
return nil
}
func main() {
var quitChannel = make(chan string)
go TrafficLight(north)
go TrafficLight(south)
go TrafficLight(east)
go TrafficLight(west)
<-quitChannel
}
func TrafficLight(direction CardinalDirection) {
var colour = red
if direction == east || direction == west {
handover("changeDirection", direction)
}
for {
show(direction, colour)
if colour == red {
sync("wait", direction)
handover("changeDirection", direction)
}
sync("changeLight"+string(nextColour(colour)), direction)
colour = nextColour(colour)
}
}
func handover(message string, direction CardinalDirection) {
getChannel(nextDirection(direction)) <- message
select {
case msg := <-getChannel(direction):
debug(msg)
}
}
func sync(message string, direction CardinalDirection) {
defer debug(string(direction) + " done with message " + message)
debug(string(direction) + " sync with message " + message)
select {
case getChannel(direction) <- message:
case msg := <-getChannel(direction):
debug(msg)
}
}
func show(direction CardinalDirection, colour Colour) {
fmt.Println(string(direction), " : ", colour.String())
}
func debug(message string) {
if printDebugMessages {
fmt.Println("Debug: " + message)
}
}