Too many things for a single commit but in summary:

We got them data bytes computer majigs being transmitted to the display
and correctly parsed over there. Also seems to be fast. I won't touch
performance issues until I have this working and documented tho.
This commit is contained in:
2026-03-10 23:10:10 +00:00
parent a8d71e0827
commit 16e102dd83
8 changed files with 162 additions and 37 deletions
+51 -11
View File
@@ -3,9 +3,31 @@ package telemetry
import (
"math"
"strconv"
"sync"
"time"
)
type FieldMapper struct {
SDKKey string
DataType DataType
Transform func(any) uint64
}
// NOTE: Update the iracing SDK to write data to the same map ALWAYS, then
// I can bind that address and read directly from there on the transform
type BoundField struct {
Key string
ID FieldID
Transform func(any, *TelemetryField)
}
var bufferPool = sync.Pool{
New: func() any {
b := make([]byte, 0, MaxFields*8)
return &b
},
}
type DataType uint8
const (
@@ -40,33 +62,33 @@ type TelemetryField struct {
// or
// 0x02 - str len max is 255 chars
// [0x02] - str
func (tf *TelemetryField) Pack() []byte {
func (tf *TelemetryField) Pack(dest []byte) []byte {
// NOTE: maybe we can have a pool of these so we don't have to create them here
// or whatever
buf := make([]byte, 0, 8)
buf = append(buf, uint8(tf.Type))
dest = append(dest, uint8(tf.Type))
switch tf.Type {
case DataTypeINT8, DataTypeUINT8:
buf = append(buf, uint8(tf.Raw))
dest = append(dest, uint8(tf.Raw))
case DataTypeINT16, DataTypeUINT16:
buf = append(buf, uint8(tf.Raw), uint8(tf.Raw>>8))
dest = append(dest, uint8(tf.Raw), uint8(tf.Raw>>8))
case DataTypeINT32, DataTypeUINT32:
buf = append(buf, uint8(tf.Raw), uint8(tf.Raw>>8), uint8(tf.Raw>>16))
dest = append(dest, uint8(tf.Raw), uint8(tf.Raw>>8), uint8(tf.Raw>>16))
case DataTypeINT64, DataTypeUINT64:
buf = append(buf, uint8(tf.Raw), uint8(tf.Raw>>8), uint8(tf.Raw>>16),
dest = append(dest, uint8(tf.Raw), uint8(tf.Raw>>8), uint8(tf.Raw>>16),
uint8(tf.Raw>>24), uint8(tf.Raw>>32), uint8(tf.Raw>>40), uint8(tf.Raw>>48),
uint8(tf.Raw>>56),
)
case DataTypeSTRING:
l := min(len(tf.Str), math.MaxUint8)
buf = append(buf, uint8(l))
buf = append(buf, tf.Str[:l]...)
dest = append(dest, uint8(l))
dest = append(dest, tf.Str[:l]...)
case DataTypeCHAR:
dest = append(dest, uint8(tf.Raw))
}
return buf
return dest
}
func (tf *TelemetryField) String() string {
@@ -134,6 +156,7 @@ func GetFieldID(name string) (FieldID, bool) {
type TelemetryData struct {
// Values map[string]*TelemetryField
Values [MaxFields]TelemetryField
ActiveBinds []BoundField
InitialTime time.Time
PenultimateDataPoll time.Time
LastDataPoll time.Time
@@ -142,3 +165,20 @@ type TelemetryData struct {
func NewTelemetryData() *TelemetryData {
return &TelemetryData{}
}
func (td *TelemetryData) Pack() []byte {
bufPtr := bufferPool.Get().(*[]byte)
buf := (*bufPtr)[:0]
for _, bind := range td.ActiveBinds {
buf = td.Values[bind.ID].Pack(buf)
}
// We have to copy here because we have to return the buffer
result := make([]byte, len(buf))
copy(result, buf)
bufferPool.Put(&buf)
return result
}