Got a bunch of stuff going on here
the main is thing is that I hammered one a way of showing data from an ibt
This commit is contained in:
@@ -249,11 +249,11 @@ func (d *CDashDisplay) updateWindowDimensions(win *UIWindow, packet UpdateDimsPa
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *CDashDisplay) MoveWindow(wID int16, delta helper.Vector) error {
|
||||
func (d *CDashDisplay) MoveWindow(wID int16, delta helper.Vector) (UIDimensions, error) {
|
||||
// Get the window from the layout
|
||||
window, ok := d.State.Layout.Windows[wID]
|
||||
if !ok {
|
||||
return fmt.Errorf("window with ID '%d' doesn't exist", wID)
|
||||
return UIDimensions{}, fmt.Errorf("window with ID '%d' doesn't exist", wID)
|
||||
}
|
||||
|
||||
// Now we will create new dimensions
|
||||
@@ -267,7 +267,7 @@ func (d *CDashDisplay) MoveWindow(wID int16, delta helper.Vector) error {
|
||||
Dims: newDimensions,
|
||||
}
|
||||
|
||||
return d.updateWindowDimensions(window, packet)
|
||||
return newDimensions, d.updateWindowDimensions(window, packet)
|
||||
}
|
||||
|
||||
func (d *CDashDisplay) ResizeWindow(wID int16, delta helper.Vector) error {
|
||||
|
||||
@@ -3,6 +3,11 @@ package cdashdisplay
|
||||
// In this file we will place all structs that are 1:1 representation of the
|
||||
// types in the device transport layer ->
|
||||
|
||||
const (
|
||||
ShowIDFalse uint8 = 0
|
||||
ShowIDTrue uint8 = 1
|
||||
)
|
||||
|
||||
type UIDimensions struct {
|
||||
X0 uint16 `yaml:"X0"`
|
||||
Y0 uint16 `yaml:"Y0"`
|
||||
@@ -21,9 +26,18 @@ type UIDecorations struct {
|
||||
Padding uint8 `yaml:"Padding"`
|
||||
}
|
||||
|
||||
// NOTE: we can't use FString32 for this - too many bytes
|
||||
// NOTE: use a bit flags for this options instead
|
||||
type UIWindowOpts struct {
|
||||
ShowID uint8 `yaml:"ShowID"`
|
||||
WinType uint8 `yaml:"WinType"`
|
||||
PreviewValue FString32 `yaml:"PreviewValue"`
|
||||
}
|
||||
|
||||
type UIWindow struct {
|
||||
Dims UIDimensions `yaml:"Dims"`
|
||||
Decor UIDecorations `yaml:"Decor"`
|
||||
Opts UIWindowOpts `yaml:"Opts"`
|
||||
Title FString32 `yaml:"Title"`
|
||||
}
|
||||
|
||||
|
||||
+36
-8
@@ -1,20 +1,24 @@
|
||||
Windows:
|
||||
1:
|
||||
Dims:
|
||||
X0: 250
|
||||
Y0: 120
|
||||
Width: 148
|
||||
Height: 76
|
||||
X0: 234
|
||||
Y0: 124
|
||||
Width: 117
|
||||
Height: 72
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 4
|
||||
TextSize: 6
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Title: TITLE
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 0
|
||||
PreviewValue: "255"
|
||||
Title: SPEEDO
|
||||
2:
|
||||
Dims:
|
||||
X0: 401
|
||||
@@ -27,7 +31,31 @@ Windows:
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 4
|
||||
TextSize: 6
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Title: NEWTITLE
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 0
|
||||
PreviewValue: "7456"
|
||||
Title: TACH
|
||||
3:
|
||||
Dims:
|
||||
X0: 340
|
||||
Y0: 240
|
||||
Width: 84
|
||||
Height: 126
|
||||
Decor:
|
||||
BGColour: 4161
|
||||
FGColour: 65535
|
||||
TitleColour: 65535
|
||||
BorderColour: 63488
|
||||
TitleSize: 2
|
||||
TextSize: 14
|
||||
HasBorder: 1
|
||||
Padding: 0
|
||||
Opts:
|
||||
ShowID: 0
|
||||
WinType: 0
|
||||
PreviewValue: "6"
|
||||
Title: GEAR
|
||||
|
||||
@@ -60,6 +60,10 @@ func NewMainController(logger *slog.Logger) *MainController {
|
||||
mc.EvBus.On(ui.CreateWindowEv{}, func(e any) {
|
||||
win := e.(ui.CreateWindowEv).Window
|
||||
|
||||
winDecor := cdashdisplay.DefaultDecorations
|
||||
winDecor.TextSize = win.TextSize
|
||||
winDecor.TitleSize = win.TitleSize
|
||||
|
||||
uiWindow := cdashdisplay.UIWindow{
|
||||
Dims: cdashdisplay.UIDimensions{
|
||||
X0: win.X,
|
||||
@@ -67,7 +71,12 @@ func NewMainController(logger *slog.Logger) *MainController {
|
||||
Width: win.Width,
|
||||
Height: win.Height,
|
||||
},
|
||||
Decor: cdashdisplay.DefaultDecorations,
|
||||
Opts: cdashdisplay.UIWindowOpts{
|
||||
WinType: win.Type, // NOTE: values aren't implemented yet
|
||||
ShowID: win.ShowID,
|
||||
PreviewValue: helper.B32(win.PreviewValue),
|
||||
},
|
||||
Decor: winDecor,
|
||||
Title: helper.B32(win.Title),
|
||||
}
|
||||
|
||||
@@ -91,10 +100,20 @@ func NewMainController(logger *slog.Logger) *MainController {
|
||||
return
|
||||
}
|
||||
|
||||
// Need to use a better interface for this me things
|
||||
// Update the dimensions
|
||||
curWindow.Dims.X0 = winModel.Window.X
|
||||
curWindow.Dims.Y0 = winModel.Window.Y
|
||||
curWindow.Dims.Width = winModel.Window.Width
|
||||
curWindow.Dims.Height = winModel.Window.Height
|
||||
// Update the opts
|
||||
curWindow.Opts.ShowID = winModel.Window.ShowID
|
||||
curWindow.Opts.WinType = winModel.Window.Type
|
||||
curWindow.Opts.PreviewValue = helper.B32(winModel.Window.PreviewValue)
|
||||
// Update the decorations
|
||||
curWindow.Decor.TitleSize = winModel.Window.TitleSize
|
||||
curWindow.Decor.TextSize = winModel.Window.TextSize
|
||||
// Update the title
|
||||
curWindow.Title = helper.B32(winModel.Window.Title)
|
||||
|
||||
err := mc.CDash.UpdateWindow(winModel.ID, curWindow)
|
||||
@@ -113,11 +132,14 @@ func NewMainController(logger *slog.Logger) *MainController {
|
||||
mc.EvBus.On(ui.MoveWindowEv{}, func(e any) {
|
||||
mvData := e.(ui.MoveWindowEv)
|
||||
pLogger.Debug(fmt.Sprintf("request to move window '%d'", mvData.WindowID))
|
||||
err := mc.CDash.MoveWindow(mvData.WindowID, mvData.Delta)
|
||||
|
||||
newDims, err := mc.CDash.MoveWindow(mvData.WindowID, mvData.Delta)
|
||||
if err != nil && err != io.EOF {
|
||||
pLogger.Debug(fmt.Sprintf("failed to move window '%d' %s", mvData.WindowID, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
mc.EvBus.Emit(ui.WindowMovedEv{ID: mvData.WindowID, Dims: newDims})
|
||||
})
|
||||
|
||||
mc.EvBus.On(ui.ResizeWindowEv{}, func(e any) {
|
||||
@@ -153,14 +175,15 @@ func NewMainController(logger *slog.Logger) *MainController {
|
||||
return
|
||||
}
|
||||
|
||||
// pLogger.Info(fmt.Sprintf("found cdashdisplay on %s!", mc.CDash.WT.Cfg.Name))
|
||||
// mc.EvBus.Emit(ui.PrintLogEv{Log: "found cdashdisplay" + mc.CDash.WT.Cfg.Name + "\n"})
|
||||
mc.CDash = display
|
||||
pLogger.Info("found cdashdisplay on: " + display.WT.Cfg.Name)
|
||||
mc.EvBus.Emit(ui.PrintLogEv{Log: "found cdashdisplay on: " + display.WT.Cfg.Name + "\n"})
|
||||
}()
|
||||
})
|
||||
|
||||
mc.EvBus.On(ui.ForceRedraw{}, func(e any) {
|
||||
mc.App.QueueUpdateDraw(func() {})
|
||||
// mc.App.QueueUpdateDraw(func() {})
|
||||
mc.App.Draw()
|
||||
})
|
||||
|
||||
return mc
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
package controllers
|
||||
@@ -2,9 +2,14 @@
|
||||
package models
|
||||
|
||||
type Window struct {
|
||||
X uint16
|
||||
Y uint16
|
||||
Width uint16
|
||||
Height uint16
|
||||
Title string
|
||||
X uint16
|
||||
Y uint16
|
||||
Width uint16
|
||||
Height uint16
|
||||
TitleSize uint8
|
||||
TextSize uint8
|
||||
Title string
|
||||
Type uint8
|
||||
ShowID uint8
|
||||
PreviewValue string
|
||||
}
|
||||
|
||||
@@ -69,6 +69,11 @@ type WindowCreatedEv struct {
|
||||
Win cdashdisplay.UIWindow
|
||||
}
|
||||
|
||||
type WindowMovedEv struct {
|
||||
ID int16
|
||||
Dims cdashdisplay.UIDimensions
|
||||
}
|
||||
|
||||
type WindowDestroyedEv struct {
|
||||
ID int16
|
||||
}
|
||||
|
||||
@@ -189,6 +189,9 @@ func layoutToolTreeViewEvCapture(bus *events.Bus, doc *dom.DOM,
|
||||
case 'l':
|
||||
// Load the layout
|
||||
bus.Emit(ui.LoadLayoutEv{})
|
||||
case 'g':
|
||||
// Go -> launches the current set up source
|
||||
streamingWindow(bus, doc)
|
||||
}
|
||||
|
||||
return event
|
||||
|
||||
@@ -15,7 +15,9 @@ import (
|
||||
)
|
||||
|
||||
// Validate the form inputs
|
||||
func validateFormInputs(x, y, w, h, title string) (models.Window, error) {
|
||||
func validateFormInputs(x, y, w, h,
|
||||
title, prev, titleSize, textSize string,
|
||||
showID bool) (models.Window, error) {
|
||||
xValue, err := strconv.ParseUint(x, 10, 64)
|
||||
if err != nil {
|
||||
return models.Window{}, err
|
||||
@@ -32,13 +34,30 @@ func validateFormInputs(x, y, w, h, title string) (models.Window, error) {
|
||||
if err != nil {
|
||||
return models.Window{}, err
|
||||
}
|
||||
titleSizeValue, err := strconv.ParseUint(titleSize, 10, 64)
|
||||
if err != nil {
|
||||
return models.Window{}, err
|
||||
}
|
||||
textSizeValue, err := strconv.ParseUint(textSize, 10, 64)
|
||||
if err != nil {
|
||||
return models.Window{}, err
|
||||
}
|
||||
|
||||
showIDValue := cdashdisplay.ShowIDFalse
|
||||
if showID {
|
||||
showIDValue = cdashdisplay.ShowIDTrue
|
||||
}
|
||||
|
||||
return models.Window{
|
||||
X: uint16(xValue),
|
||||
Y: uint16(yValue),
|
||||
Width: uint16(widthValue),
|
||||
Height: uint16(heightValue),
|
||||
Title: title,
|
||||
X: uint16(xValue),
|
||||
Y: uint16(yValue),
|
||||
Width: uint16(widthValue),
|
||||
Height: uint16(heightValue),
|
||||
ShowID: showIDValue,
|
||||
TitleSize: uint8(titleSizeValue),
|
||||
TextSize: uint8(textSizeValue),
|
||||
PreviewValue: prev,
|
||||
Title: title,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -50,12 +69,22 @@ func createNewWindowForm(bus *events.Bus, doc *dom.DOM) {
|
||||
width := tview.NewInputField().SetLabel("width")
|
||||
height := tview.NewInputField().SetLabel("height")
|
||||
title := tview.NewInputField().SetLabel("title")
|
||||
previewValue := tview.NewInputField().SetLabel("preview value")
|
||||
showID := tview.NewCheckbox().SetLabel("show ID").SetChecked(true)
|
||||
winType := tview.NewDropDown().SetLabel("type").
|
||||
SetOptions([]string{"string", "bar"}, func(s string, id int) {
|
||||
// Here we have to add extra options for the configuration of default
|
||||
// values and so on
|
||||
}).
|
||||
SetCurrentOption(0)
|
||||
titleSize := tview.NewDropDown().SetLabel("Title Size").
|
||||
SetOptions([]string{"1", "2", "3", "4", "5", "6", "7", "8"}, func(s string, id int) {
|
||||
}).
|
||||
SetCurrentOption(0)
|
||||
textSize := tview.NewDropDown().SetLabel("Text Size").
|
||||
SetOptions([]string{"1", "2", "3", "4", "5", "6", "7", "8"}, func(s string, id int) {
|
||||
}).
|
||||
SetCurrentOption(0)
|
||||
|
||||
form := tview.NewForm().
|
||||
AddFormItem(x0).
|
||||
@@ -63,8 +92,14 @@ func createNewWindowForm(bus *events.Bus, doc *dom.DOM) {
|
||||
AddFormItem(width).
|
||||
AddFormItem(height).
|
||||
AddFormItem(title).
|
||||
AddFormItem(previewValue).
|
||||
AddFormItem(showID).
|
||||
AddFormItem(winType).
|
||||
AddFormItem(titleSize).
|
||||
AddFormItem(textSize).
|
||||
AddButton("Create", func() {
|
||||
_, titleSizeTxt := titleSize.GetCurrentOption()
|
||||
_, textSizeTxt := textSize.GetCurrentOption()
|
||||
// Validate the inputs
|
||||
window, err := validateFormInputs(
|
||||
x0.GetText(),
|
||||
@@ -72,6 +107,10 @@ func createNewWindowForm(bus *events.Bus, doc *dom.DOM) {
|
||||
width.GetText(),
|
||||
height.GetText(),
|
||||
title.GetText(),
|
||||
previewValue.GetText(),
|
||||
titleSizeTxt,
|
||||
textSizeTxt,
|
||||
showID.IsChecked(),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
@@ -79,6 +118,7 @@ func createNewWindowForm(bus *events.Bus, doc *dom.DOM) {
|
||||
return
|
||||
}
|
||||
|
||||
bus.Emit(ui.LogEv{Log: fmt.Sprintf("showID: %d\n", window.ShowID)})
|
||||
bus.Emit(ui.CreateWindowEv{Window: window})
|
||||
})
|
||||
|
||||
@@ -116,17 +156,38 @@ func windowInfoForm(bus *events.Bus, doc *dom.DOM, idx int16,
|
||||
win *cdashdisplay.UIWindow) *dom.UINode {
|
||||
var err error
|
||||
|
||||
x0 := tview.NewInputField().SetLabel("x").SetText(fmt.Sprintf("%d", win.Dims.X0))
|
||||
y0 := tview.NewInputField().SetLabel("y").SetText(fmt.Sprintf("%d", win.Dims.Y0))
|
||||
width := tview.NewInputField().SetLabel("width").SetText(fmt.Sprintf("%d", win.Dims.Width))
|
||||
height := tview.NewInputField().SetLabel("height").SetText(fmt.Sprintf("%d", win.Dims.Height))
|
||||
title := tview.NewInputField().SetLabel("title").SetText(win.Title.String())
|
||||
x0 := tview.NewInputField().SetLabel("x").
|
||||
SetText(fmt.Sprintf("%d", win.Dims.X0))
|
||||
y0 := tview.NewInputField().SetLabel("y").
|
||||
SetText(fmt.Sprintf("%d", win.Dims.Y0))
|
||||
width := tview.NewInputField().SetLabel("width").
|
||||
SetText(fmt.Sprintf("%d", win.Dims.Width))
|
||||
height := tview.NewInputField().SetLabel("height").
|
||||
SetText(fmt.Sprintf("%d", win.Dims.Height))
|
||||
title := tview.NewInputField().SetLabel("title").
|
||||
SetText(win.Title.String())
|
||||
previewValue := tview.NewInputField().SetLabel("preview value").
|
||||
SetText(win.Opts.PreviewValue.String())
|
||||
showID := tview.NewCheckbox().SetLabel("show ID").SetChecked(true)
|
||||
winType := tview.NewDropDown().SetLabel("type").
|
||||
SetOptions([]string{"string", "bar"}, func(s string, id int) {
|
||||
// Here we have to add extra options for the configuration of default
|
||||
// values and so on
|
||||
}).
|
||||
SetCurrentOption(0)
|
||||
// NOTE: put this thing into a loop that generate the numbers or something yo
|
||||
titleSize := tview.NewDropDown().SetLabel("Title Size").
|
||||
SetOptions([]string{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
|
||||
"11", "12", "13", "14", "15", "16", "17", "18", "19", "20"},
|
||||
func(s string, id int) {
|
||||
}).
|
||||
SetCurrentOption(int(win.Decor.TitleSize))
|
||||
textSize := tview.NewDropDown().SetLabel("Text Size").
|
||||
SetOptions([]string{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
|
||||
"11", "12", "13", "14", "15", "16", "17", "18", "19", "20"},
|
||||
func(s string, id int) {
|
||||
}).
|
||||
SetCurrentOption(int(win.Decor.TextSize))
|
||||
|
||||
form := tview.NewForm().
|
||||
AddFormItem(x0).
|
||||
@@ -134,9 +195,16 @@ func windowInfoForm(bus *events.Bus, doc *dom.DOM, idx int16,
|
||||
AddFormItem(width).
|
||||
AddFormItem(height).
|
||||
AddFormItem(title).
|
||||
AddFormItem(previewValue).
|
||||
AddFormItem(showID).
|
||||
AddFormItem(titleSize).
|
||||
AddFormItem(textSize).
|
||||
AddFormItem(winType).
|
||||
AddButton("Update", func() {
|
||||
bus.Emit(ui.LogEv{Log: "update event was created\n"})
|
||||
|
||||
_, titleSizeTxt := titleSize.GetCurrentOption()
|
||||
_, textSizeTxt := textSize.GetCurrentOption()
|
||||
// Validate the inputs
|
||||
window, err := validateFormInputs(
|
||||
x0.GetText(),
|
||||
@@ -144,6 +212,10 @@ func windowInfoForm(bus *events.Bus, doc *dom.DOM, idx int16,
|
||||
width.GetText(),
|
||||
height.GetText(),
|
||||
title.GetText(),
|
||||
previewValue.GetText(),
|
||||
titleSizeTxt,
|
||||
textSizeTxt,
|
||||
showID.IsChecked(),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
@@ -151,6 +223,7 @@ func windowInfoForm(bus *events.Bus, doc *dom.DOM, idx int16,
|
||||
return
|
||||
}
|
||||
|
||||
bus.Emit(ui.LogEv{Log: fmt.Sprintf("showID: %d\n", window.ShowID)})
|
||||
bus.Emit(ui.LogEv{Log: "sending update window ev\n"})
|
||||
bus.Emit(ui.UpdateWindowEv{ID: idx, Window: window})
|
||||
})
|
||||
@@ -167,17 +240,37 @@ func windowInfoForm(bus *events.Bus, doc *dom.DOM, idx int16,
|
||||
return ev
|
||||
})
|
||||
|
||||
// In case the window is moved we need to update this form
|
||||
bus.On(ui.WindowMovedEv{}, func(e any) {
|
||||
data := e.(ui.WindowMovedEv)
|
||||
// Only update the fields if the event is for this thing
|
||||
if data.ID != idx {
|
||||
return
|
||||
}
|
||||
|
||||
// Get the current window-info-page
|
||||
elem := doc.GetElemByID(windowInfoPageID(data.ID))
|
||||
if elem == nil {
|
||||
bus.Emit(ui.LogEv{Log: "could't get hold of info page"})
|
||||
return
|
||||
}
|
||||
|
||||
x0.SetText(fmt.Sprintf("%d", data.Dims.X0))
|
||||
x0.SetText(fmt.Sprintf("%d", data.Dims.Y0))
|
||||
width.SetText(fmt.Sprintf("%d", data.Dims.Width))
|
||||
height.SetText(fmt.Sprintf("%d", data.Dims.Height))
|
||||
})
|
||||
|
||||
var formNode *dom.UINode
|
||||
elemId := windowInfoPageID(idx)
|
||||
formNode = doc.GetNodeByID(elemId)
|
||||
elemID := windowInfoPageID(idx)
|
||||
formNode = doc.GetNodeByID(elemID)
|
||||
layoutToolActionPagesElem := doc.GetElemByID(layoutToolActionPagesID)
|
||||
if formNode == nil {
|
||||
formNode, err = doc.NewUINode(elemId, layoutToolActionPagesElem, form)
|
||||
formNode, err = doc.NewUINode(elemID, layoutToolActionPagesElem, form)
|
||||
if err != nil {
|
||||
panic("failed to create UI node for the new window form: " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// AddAndShowPage(bus, doc, layoutToolActionPagesElem.(*tview.Pages), formNode)
|
||||
return formNode
|
||||
}
|
||||
|
||||
@@ -0,0 +1,266 @@
|
||||
package views
|
||||
|
||||
import (
|
||||
esdi "esdi/oldEsdi"
|
||||
"esdi/tui/internal/dom"
|
||||
"esdi/tui/internal/events"
|
||||
"esdi/tui/internal/ui"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ESilva15/goirsdk"
|
||||
"github.com/gdamore/tcell/v2"
|
||||
"github.com/rivo/tview"
|
||||
)
|
||||
|
||||
// Car data lengths
|
||||
const (
|
||||
SpeedLen = 5
|
||||
GearLen = 3
|
||||
RpmLen = 6
|
||||
BrakeBiasLen = 6
|
||||
)
|
||||
|
||||
const (
|
||||
streamingBoxID = "streaming-box"
|
||||
)
|
||||
|
||||
var (
|
||||
lastMessageTime time.Time
|
||||
data *esdi.SimulationData = &esdi.SimulationData{}
|
||||
dataView *esdi.DataPacket = &esdi.DataPacket{}
|
||||
initialTime = time.Now()
|
||||
lastTime = time.Now()
|
||||
mu sync.Mutex
|
||||
irsdk *goirsdk.IBT
|
||||
)
|
||||
|
||||
func setUpSource(bus *events.Bus, doc *dom.DOM, tv *tview.TextView) {
|
||||
// Open the telemetry file
|
||||
file, err := os.Open("/home/esilva/Desktop/projetos/simracing_peripherals/testTelemetry/supercars_indianapolis.ibt")
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to open IBT file: %v", err)
|
||||
}
|
||||
|
||||
irsdk, err = goirsdk.Init(file, "./out.ibt", "./out.yaml")
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to load iRacing data")
|
||||
}
|
||||
|
||||
startTime := time.Now()
|
||||
|
||||
go readData()
|
||||
|
||||
// global irsdk is now here
|
||||
go func() {
|
||||
ticker := time.NewTicker(time.Second / 60)
|
||||
defer ticker.Stop()
|
||||
|
||||
counter := 0
|
||||
for t := range ticker.C {
|
||||
// whatever
|
||||
currentTime := time.Now()
|
||||
|
||||
delta := currentTime.Sub(startTime)
|
||||
|
||||
str := stringified() + fmt.Sprintf("%v - %7d\n%5f - %5f",
|
||||
t.UTC(), counter, delta.Seconds(), delta.Seconds()/float64(counter))
|
||||
|
||||
tv.SetText(str)
|
||||
bus.Emit(ui.ForceRedraw{})
|
||||
counter++
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func streamingWindow(bus *events.Bus, doc *dom.DOM) {
|
||||
bus.Emit(ui.LogEv{Log: "creating streaming window"})
|
||||
|
||||
// Get the ActionPages parent
|
||||
box := tview.NewTextView()
|
||||
box.SetBorder(true).SetTitle("STREAMING")
|
||||
box.SetInputCapture(func(ev *tcell.EventKey) *tcell.EventKey {
|
||||
switch ev.Rune() {
|
||||
case 'q':
|
||||
// well, I really need to design the UI to work properly
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
return ev
|
||||
})
|
||||
|
||||
var err error
|
||||
var boxNode *dom.UINode
|
||||
|
||||
// delete the currently existing streaming-box
|
||||
actionPages := doc.GetElemByID(layoutToolActionPagesID).(*tview.Pages)
|
||||
actionPages.RemovePage(streamingBoxID)
|
||||
|
||||
// Get the currently exisiting streaming box in the dom so we can delete it
|
||||
boxNode = doc.GetNodeByID(streamingBoxID)
|
||||
if boxNode != nil {
|
||||
doc.DeleteElem(boxNode)
|
||||
}
|
||||
|
||||
// Register this streaming box as an UINode
|
||||
boxNode, err = doc.NewUINode(
|
||||
streamingBoxID,
|
||||
doc.GetElemByID(layoutToolActionPagesID),
|
||||
box,
|
||||
)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Add it to the action pages and view it
|
||||
AddAndShowPage(bus, doc, actionPages, boxNode, true)
|
||||
|
||||
setUpSource(bus, doc, box)
|
||||
}
|
||||
|
||||
func stringified() string {
|
||||
var buffer strings.Builder
|
||||
|
||||
mu.Lock()
|
||||
sessionTimeR := irsdk.Vars.Vars["SessionTime"].Value
|
||||
sessionTime := float64(sessionTimeR.(float64))
|
||||
|
||||
currTime := time.Now()
|
||||
delta := currTime.Sub(lastTime)
|
||||
buffer.WriteString(fmt.Sprintf("[%s]\n", currTime.Format("2006/01/02 15:04:05.000")))
|
||||
buffer.WriteString(fmt.Sprintf("Delta: %d [%f]\n\n", delta.Milliseconds(), 1000.0/60.0))
|
||||
lastTime = currTime
|
||||
|
||||
elapsed := currTime.Sub(initialTime)
|
||||
softwareElapsed := time.Unix(0, 0).Add(elapsed).Format("04:05.000")
|
||||
sessionElapsed := time.Unix(0, 0).
|
||||
Add(time.Duration(sessionTime * float64(time.Second))).
|
||||
Format("04:05.000")
|
||||
|
||||
buffer.WriteString(fmt.Sprintf("Elapsed (software): %s\n",
|
||||
softwareElapsed))
|
||||
buffer.WriteString(fmt.Sprintf("Elapsed (session): %s\n\n",
|
||||
sessionElapsed))
|
||||
|
||||
// buffer.WriteString("Car data:\n")
|
||||
buffer.WriteString(fmt.Sprintf("Gear: %d, RPM: %d, Speed: %d\n\n",
|
||||
data.Gear, data.RPM, data.Speed))
|
||||
|
||||
// buffer.WriteString("Fuel data:\n")
|
||||
// buffer.WriteString(fmt.Sprintf("Fuel Est: %s\n\n", e.dataPacket.FuelEst))
|
||||
|
||||
// buffer.WriteString("Lap data:\n")
|
||||
// buffer.WriteString(fmt.Sprintf("Delta: [%s] [%f] [%s]\n", e.dataPacket.DeltaToBestLap,
|
||||
// e.data.LapDeltaFloat, lapTimeDeltaRepresentation(e.data.LapDeltaFloat)))
|
||||
// buffer.WriteString(fmt.Sprintf("LapTime: %s\n", e.dataPacket.CurrLapTime))
|
||||
// buffer.WriteString(fmt.Sprintf("Best Lap Time: %s\n", e.dataPacket.BestLapTime))
|
||||
// buffer.WriteString(fmt.Sprintf("Last Lap Time: %s\n", e.dataPacket.LastLapTime))
|
||||
// buffer.WriteString(fmt.Sprintf("LapBestNLapTi: %f\n\n", e.data.LapBestNLapTime))
|
||||
|
||||
// buffer.WriteString("Position data:\n")
|
||||
// buffer.WriteString(fmt.Sprintf("Pos: %d\n", e.dataPacket.Position))
|
||||
|
||||
// for p, v := range e.dataPacket.Standings {
|
||||
// s := fmt.Sprintf("[%2d] %s %-16s %-16s\n",
|
||||
// p+1, v.Lap, string(bytes.Trim(v.DriverName[:], "\x00")), v.TimeBehindString)
|
||||
// buffer.WriteString(s)
|
||||
// }
|
||||
|
||||
// buffer.WriteString(fmt.Sprintf("Size: %v\n", binary.Size(DataPacket{})))
|
||||
// buffer.WriteString(fmt.Sprintf("Recv: %d\n", e.data.Recv))
|
||||
// buffer.WriteString(fmt.Sprintf("Recv Err: %v\n", e.data.ReadError))
|
||||
|
||||
mu.Unlock()
|
||||
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
func msToKph(v float32) int {
|
||||
return int((3600 * v) / 1000)
|
||||
}
|
||||
|
||||
func lapTimeRepresentation(t float32, f string) string {
|
||||
if t < 0 {
|
||||
t = 0
|
||||
}
|
||||
|
||||
wholeSeconds := int64(t)
|
||||
lapTime := time.Unix(wholeSeconds, int64((t-float32(wholeSeconds))*1e9))
|
||||
|
||||
return lapTime.Format(f)
|
||||
}
|
||||
|
||||
func lapTimeDeltaRepresentation(t float32) string {
|
||||
sign := '-'
|
||||
if t < 0 {
|
||||
sign = '+'
|
||||
t = -t
|
||||
}
|
||||
|
||||
// Cap to 99.9 max
|
||||
if t > 99.9 {
|
||||
t = 99.9
|
||||
}
|
||||
|
||||
if t >= 1 {
|
||||
// Round to nearest tenth
|
||||
rounded := float32(int(t*10+0.5)) / 10
|
||||
return fmt.Sprintf("%c%.1f", sign, rounded)
|
||||
}
|
||||
|
||||
// t < 1: round to nearest tenth and remove leading zero (e.g., "0.1" → ".1")
|
||||
rounded := float32(int(t*10+0.5)) / 10
|
||||
s := fmt.Sprintf("%.1f", rounded)
|
||||
if strings.HasPrefix(s, "0") {
|
||||
s = s[1:]
|
||||
}
|
||||
return fmt.Sprintf("%c%s", sign, s)
|
||||
}
|
||||
|
||||
func readData() {
|
||||
dataReaderTicker := time.NewTicker(time.Second / 60)
|
||||
defer dataReaderTicker.Stop()
|
||||
|
||||
initialTime = time.Now()
|
||||
for _ = range dataReaderTicker.C {
|
||||
var err error
|
||||
|
||||
mu.Lock()
|
||||
_, err = irsdk.Update(time.Millisecond * 100)
|
||||
if err != nil {
|
||||
fmt.Printf("could not update data: %v", err)
|
||||
continue
|
||||
}
|
||||
mu.Unlock()
|
||||
|
||||
getVehicleData()
|
||||
|
||||
// Test the actual dataPacket we are sending over the wire
|
||||
copyBytes(dataView.Speed[:], SpeedLen, fmt.Sprintf("%3d", data.Speed))
|
||||
copyBytes(dataView.Gear[:], GearLen, fmt.Sprintf("%2d", data.Gear))
|
||||
copyBytes(dataView.RPM[:], RpmLen, fmt.Sprintf("%3d", data.RPM))
|
||||
|
||||
lastMessageTime = time.Now()
|
||||
}
|
||||
}
|
||||
|
||||
func getVehicleData() {
|
||||
mu.Lock()
|
||||
curGear := irsdk.Vars.Vars["Gear"].Value
|
||||
curRPM := irsdk.Vars.Vars["RPM"].Value
|
||||
curSpeed := irsdk.Vars.Vars["Speed"].Value
|
||||
|
||||
data.Gear = int32(curGear.(int))
|
||||
data.RPM = int32(curRPM.(float32))
|
||||
data.Speed = int32(msToKph(curSpeed.(float32)))
|
||||
mu.Unlock()
|
||||
}
|
||||
|
||||
func copyBytes(dest []byte, destSize int, src string) {
|
||||
copy(dest[:], []byte(src))
|
||||
dest[min(destSize-1, len(src))] = '\x00'
|
||||
}
|
||||
Reference in New Issue
Block a user