Commit f2c44b6c authored by Loïck Bonniot's avatar Loïck Bonniot

[d] Improve event import

parent 1f645003
Pipeline #503 failed with stage
......@@ -4,8 +4,8 @@ import "github.com/visualfc/goqt/ui"
var colors = map[string]uint32{
"red": 0x00ff0000,
"blue": 0x0000ff00,
"green": 0x000000ff,
"green": 0x0000aa00,
"blue": 0x000000ff,
"black": 0x00000000,
}
......
......@@ -2,20 +2,64 @@ package gui
import (
"fmt"
"time"
"math"
"time"
"dfss/dfssd/api"
"github.com/visualfc/goqt/ui"
)
// TEMPORARY
const quantum = 100 // discretization argument for events (ns)
const speed = 500 // duration of a quantum (ms)
const speed = 1000 // duration of a quantum (ms)
// AddEvent interprets an incoming event into a graphic one.
// Expected format:
//
// Timestamp: unix nano timestamp
// Identifier: either "platform", "ttp" or "<email>"
// Log: one of the following
// "sent promise to <email>"
// "sent signature to <email>"
//
// Other messages are currently ignored.
func (w *Window) AddEvent(e *api.Log) {
event := Event{
Sender: w.scene.identifierToIndex(e.Identifier),
Date: time.Unix(0, e.Timestamp),
}
w.Log(fmt.Sprint(e.Identifier, " ", e.Log))
var receiver string
if n, _ := fmt.Sscanf(e.Log, "sent promise to %s", &receiver); n > 0 {
event.Type = PROMISE
event.Receiver = w.scene.identifierToIndex(receiver)
} else if n, _ := fmt.Sscanf(e.Log, "sent signature to %s", &receiver); n > 0 {
event.Type = SIGNATURE
event.Receiver = w.scene.identifierToIndex(receiver)
}
if receiver != "" {
w.scene.Events = append(w.scene.Events, event)
}
}
func (w *Window) DrawEvent(e *Event) {
xa, ya := w.GetClientPosition(e.Sender)
xb, yb := w.GetClientPosition(e.Receiver)
w.DrawArrow(xa, ya, xb, yb, colors["red"])
var color string
switch e.Type {
case PROMISE:
color = "blue"
case SIGNATURE:
color = "green"
default:
color = "black"
}
w.DrawArrow(xa, ya, xb, yb, colors[color])
}
func (w *Window) PrintQuantumInformation() {
......@@ -25,10 +69,10 @@ func (w *Window) PrintQuantumInformation() {
}
beginning := w.scene.Events[0].Date.UnixNano()
totalDuration := w.scene.Events[len(w.scene.Events) - 1].Date.UnixNano() - beginning
nbQuantum := math.Ceil(float64(totalDuration) / quantum)
totalDuration := w.scene.Events[len(w.scene.Events)-1].Date.UnixNano() - beginning
nbQuantum := math.Max(1, math.Ceil(float64(totalDuration)/quantum))
durationFromBeginning := w.scene.currentTime.UnixNano() - beginning
currentQuantum := math.Ceil(float64(durationFromBeginning) / quantum)+1
currentQuantum := math.Ceil(float64(durationFromBeginning)/quantum) + 1
if w.scene.currentEvent == 0 {
currentQuantum = 0
......@@ -38,6 +82,9 @@ func (w *Window) PrintQuantumInformation() {
func (w *Window) initTimer() {
w.timer = ui.NewTimerWithParent(w)
lastNbOfClients := len(w.scene.Clients)
w.timer.OnTimeout(func() {
nbEvents := len(w.scene.Events)
if w.scene.currentEvent >= nbEvents {
......@@ -53,6 +100,11 @@ func (w *Window) initTimer() {
return
}
// Check if need to redraw everything
if lastNbOfClients != len(w.scene.Clients) {
w.initScene()
}
// Init first time
if w.scene.currentEvent == 0 {
w.scene.currentTime = w.scene.Events[0].Date
......@@ -75,3 +127,21 @@ func (w *Window) initTimer() {
w.scene.currentTime = endOfQuantum
})
}
func (s *Scene) identifierToIndex(identifier string) int {
if identifier == "platform" {
return -1
}
if identifier == "ttp" {
return -2
}
for i, c := range s.Clients {
if c.Name == identifier {
return i
}
}
s.Clients = append(s.Clients, Client{Name: identifier})
return len(s.Clients) - 1
}
......@@ -26,6 +26,10 @@ func (w *Window) DrawClients() {
}
func (w *Window) GetClientPosition(i int) (x, y float64) {
if i < 0 {
return w.GetServerPosition(i == -1)
}
nbClients := float64(len(w.scene.Clients))
angle := 2 * math.Pi * float64(i) / nbClients
return math.Cos(angle) * (w.circleSize / 2), math.Sin(angle) * (w.circleSize / 2)
......@@ -33,7 +37,7 @@ func (w *Window) GetClientPosition(i int) (x, y float64) {
func (w *Window) GetServerPosition(platform bool) (x, y float64) {
x = w.circleSize/2 + 150
y = -16
y = 0
if !platform {
x *= -1
}
......@@ -45,12 +49,12 @@ func (w *Window) DrawServers() {
ttp := scene.AddPixmap(w.pixmaps["ttp"])
x, y := w.GetServerPosition(false)
ttp.SetPosFWithXY(x, y)
ttp.SetPosFWithXY(x-32, y-16)
ttp.SetToolTip("TTP")
platform := scene.AddPixmap(w.pixmaps["platform"])
platform.SetX(w.circleSize/2 + 150)
platform.SetY(-16)
x, y = w.GetServerPosition(true)
platform.SetPosFWithXY(x, y-16)
platform.SetToolTip("Platform")
}
......
......@@ -12,15 +12,15 @@ import (
type Window struct {
*ui.QMainWindow
logField *ui.QTextEdit
graphics *ui.QGraphicsView
progress *ui.QLabel
playButton *ui.QPushButton
stopButton *ui.QPushButton
logField *ui.QTextEdit
graphics *ui.QGraphicsView
progress *ui.QLabel
playButton *ui.QPushButton
stopButton *ui.QPushButton
replayButton *ui.QPushButton
scene *Scene
circleSize float64
pixmaps map[string]*ui.QPixmap
scene *Scene
circleSize float64
pixmaps map[string]*ui.QPixmap
currentArrows []*ui.QGraphicsPathItem
timer *ui.QTimer
......@@ -53,6 +53,6 @@ type Scene struct {
Clients []Client
Events []Event
currentTime time.Time
currentEvent int
currentTime time.Time
currentEvent int
}
......@@ -47,19 +47,6 @@ func NewWindow() *Window {
w.initScene()
w.initTimer()
// TEST ONLY
w.scene.Clients = []Client{
Client{"signer1@lesterpig.com"},
Client{"signer2@insa-rennes.fr"},
Client{"signer3@dfss.com"},
}
w.scene.Events = []Event{
Event{PROMISE, 0, 1, time.Unix(0, 5)},
Event{SIGNATURE, 1, 2, time.Unix(0, 15)},
Event{PROMISE, 1, 0, time.Unix(0, 134)},
Event{OTHER, 0, 1, time.Unix(0, 402)},
}
w.StatusBar().ShowMessage("Ready")
w.PrintQuantumInformation()
return w
......@@ -71,6 +58,7 @@ func (w *Window) OnResizeEvent(ev *ui.QResizeEvent) bool {
}
func (w *Window) Log(str string) {
str = time.Now().Format("[15:04:05.000] ") + str
w.logField.Append(str)
w.logField.EnsureCursorVisible()
}
......@@ -120,15 +108,13 @@ func (w *Window) addActions() {
w.playButton.OnClicked(func() {
w.playButton.SetDisabled(true)
w.stopButton.SetDisabled(false)
w.timer.StartWithMsec(500)
w.Log("Started simulation")
w.timer.StartWithMsec(speed)
})
w.stopButton.OnClicked(func() {
w.playButton.SetDisabled(false)
w.stopButton.SetDisabled(true)
w.timer.Stop()
w.Log("Paused simulation")
})
w.stopButton.SetDisabled(true)
......@@ -136,7 +122,6 @@ func (w *Window) addActions() {
w.RemoveArrows()
w.scene.currentEvent = 0
w.PrintQuantumInformation()
w.Log("Restarting simulation")
})
}
......
......@@ -8,6 +8,7 @@ import (
"strconv"
"dfss"
"dfss/dfssd/api"
"dfss/dfssd/gui"
"dfss/dfssd/server"
"github.com/visualfc/goqt/ui"
......@@ -51,10 +52,10 @@ func main() {
case "version":
fmt.Println("v"+dfss.Version, runtime.GOOS, runtime.GOARCH)
case "nogui":
lfn := func(str string) {
fmt.Println(str)
fn := func(v *api.Log) {
fmt.Printf("[%d] %s: %s\n", v.Timestamp, v.Identifier, v.Log)
}
err := server.Listen("0.0.0.0:"+strconv.Itoa(port), lfn)
err := server.Listen("0.0.0.0:"+strconv.Itoa(port), fn)
if err != nil {
os.Exit(1)
}
......@@ -62,7 +63,7 @@ func main() {
ui.Run(func() {
window := gui.NewWindow()
go func() {
err := server.Listen("0.0.0.0:"+strconv.Itoa(port), window.Log)
err := server.Listen("0.0.0.0:"+strconv.Itoa(port), window.AddEvent)
if err != nil {
window.Log("!! " + err.Error())
}
......
......@@ -20,17 +20,16 @@ func (s *Server) SendLog(ctx context.Context, in *api.Log) (*api.Ack, error) {
}
// Listen with gRPG service
func Listen(addrPort string, lfn func(string)) error {
func Listen(addrPort string, fn func(*api.Log)) error {
// open tcp socket
lis, err := net.Listen("tcp", addrPort)
if err != nil {
grpclog.Fatalf("Failed to open tcp socket: %v", err)
return err
}
lfn("Server listening on " + addrPort)
// log display manager
go displayHandler(lfn)
go displayHandler(fn)
// bootstrap gRPC service !
grpcServer := grpc.NewServer()
......
package server
import (
"fmt"
"sort"
"sync"
"time"
......@@ -23,7 +22,7 @@ func addMessage(msg *api.Log) {
}
// display logs that are more than since (ms) old
func display(since int64, lfn func(string)) {
func display(since int64, fn func(*api.Log)) {
var out []*api.Log // sorted messages to display
var recycled []*api.Log // messages too recent to be displayed
......@@ -45,15 +44,16 @@ func display(since int64, lfn func(string)) {
sort.Sort(ByTimestamp(out))
for _, v := range out {
lfn(fmt.Sprintf("[%d] %s:: %s", v.Timestamp, v.Identifier, v.Log))
//lfn()
fn(v)
}
}
// refresh every second
func displayHandler(lfn func(string)) {
func displayHandler(fn func(*api.Log)) {
ticker := time.NewTicker(time.Second)
for range ticker.C {
display(1000, lfn)
display(1000, fn)
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment