From 7caad7149ea9cd8c5a6cd9dd0fc23de92876c55e Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Fri, 13 Mar 2026 23:35:33 +0000 Subject: [PATCH] making it possible for multiple windows to receive the same data still need some more work on this --- providers/iracing/iracing.go | 2 +- telemetry/data.go | 56 ++++++++++++++++++------------------ telemetry/data_test.go | 34 ++++++++++++++++------ 3 files changed, 54 insertions(+), 38 deletions(-) diff --git a/providers/iracing/iracing.go b/providers/iracing/iracing.go index e010abf..2d944cc 100644 --- a/providers/iracing/iracing.go +++ b/providers/iracing/iracing.go @@ -189,7 +189,7 @@ func (i *IRacing) Subscribe(requestFields map[int16]telem.FieldID) { } } - i.data.Values[id].ID = winID + i.data.Values[id].IDs = append(i.data.Values[id].IDs, winID) i.data.ActiveBinds = append(i.data.ActiveBinds, binding) } diff --git a/telemetry/data.go b/telemetry/data.go index 08ccb89..36d7aec 100644 --- a/telemetry/data.go +++ b/telemetry/data.go @@ -45,9 +45,13 @@ const ( // TelemetryField will be the basic unit to hold telemetry data values in our // application. -// From my testing, using an uint64 bucket is around 50x faster than any +// From my testing, using an uint64 bucket is around 50x faster than any/interface{} +// The IDs member is a list so that we can have multiple items on the target device +// consuming the same piece of data +// NOTE: we can optimize this via a special command that says a given piece of data +// is for multiple targets type TelemetryField struct { - ID int16 // Identification: I have to learn how I will use this on other devices + IDs []int16 // Identification for the serial device Type DataType Raw uint64 Str string // Only to be used with DataTypeSTRING @@ -68,28 +72,28 @@ type TelemetryField struct { 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 - dest = append(dest, uint8(tf.ID), uint8(tf.ID>>8)) - dest = append(dest, uint8(tf.Type)) + for _, id := range tf.IDs { + dest = append(dest, uint8(id), uint8(id>>8)) + dest = append(dest, uint8(tf.Type)) - switch tf.Type { - case DataTypeINT8, DataTypeUINT8: - dest = append(dest, uint8(tf.Raw)) - case DataTypeINT16, DataTypeUINT16: - dest = append(dest, uint8(tf.Raw), uint8(tf.Raw>>8)) - case DataTypeINT32, DataTypeUINT32: - dest = append(dest, uint8(tf.Raw), uint8(tf.Raw>>8), uint8(tf.Raw>>16)) - case DataTypeINT64, DataTypeUINT64: - 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) + switch tf.Type { + case DataTypeINT8, DataTypeUINT8, DataTypeCHAR: + dest = append(dest, uint8(tf.Raw)) + case DataTypeINT16, DataTypeUINT16: + dest = append(dest, uint8(tf.Raw), uint8(tf.Raw>>8)) + case DataTypeINT32, DataTypeUINT32: + dest = append(dest, uint8(tf.Raw), uint8(tf.Raw>>8), uint8(tf.Raw>>16), uint8(tf.Raw>>24)) + case DataTypeINT64, DataTypeUINT64: + 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) - dest = append(dest, uint8(l)) - dest = append(dest, tf.Str[:l]...) - case DataTypeCHAR: - dest = append(dest, uint8(tf.Raw)) + dest = append(dest, uint8(l)) + dest = append(dest, tf.Str[:l]...) + } } return dest @@ -156,13 +160,9 @@ func GetFieldID(name string) (FieldID, bool) { return id, ok } -// NOTE: Replace values with a more appropriate custom field approach where -// every custom field only takes as many bytes as required -// NOTE: Add the timing fields here to count frames of data gathering and whatnot -// remember to do the same to whoever is sending data - +// TelemetryData is +// I need to find a way of having the values be per window or some other type TelemetryData struct { - // Values map[string]*TelemetryField Values [MaxFields]TelemetryField ActiveBinds []BoundField InitialTime time.Time diff --git a/telemetry/data_test.go b/telemetry/data_test.go index 728cf77..5eff864 100644 --- a/telemetry/data_test.go +++ b/telemetry/data_test.go @@ -17,7 +17,7 @@ func Test_TelemetryField(t *testing.T) { { name: "test_max_uint8", tf: TelemetryField{ - ID: 0x01, + IDs: []int16{0x01}, Type: DataTypeUINT8, Raw: uint64(math.MaxUint8), }, @@ -26,7 +26,7 @@ func Test_TelemetryField(t *testing.T) { { name: "test_max_int8", tf: TelemetryField{ - ID: 0x02, + IDs: []int16{0x02}, Type: DataTypeINT8, Raw: uint64(math.MaxInt8), }, @@ -35,7 +35,7 @@ func Test_TelemetryField(t *testing.T) { { name: "test_max_uint16", tf: TelemetryField{ - ID: 0x03, + IDs: []int16{0x03}, Type: DataTypeUINT16, Raw: uint64(math.MaxUint16), }, @@ -44,7 +44,7 @@ func Test_TelemetryField(t *testing.T) { { name: "test_max_int16", tf: TelemetryField{ - ID: 0x04, + IDs: []int16{0x04}, Type: DataTypeINT16, Raw: uint64(math.MaxInt16), }, @@ -53,7 +53,7 @@ func Test_TelemetryField(t *testing.T) { { name: "test_string", tf: TelemetryField{ - ID: 0x05, + IDs: []int16{0x05}, Type: DataTypeSTRING, Str: "a cool string!", }, @@ -63,7 +63,7 @@ func Test_TelemetryField(t *testing.T) { { name: "test_char", tf: TelemetryField{ - ID: 0x06, + IDs: []int16{0x06}, Type: DataTypeCHAR, Raw: uint64('R'), }, @@ -94,22 +94,38 @@ func Test_TelemetryData(t *testing.T) { Key: "Gear", ID: Gear, }, + { + Key: "Empty", + ID: Empty, + }, }, } data.Values[Speed] = TelemetryField{ - ID: 0x01, + IDs: []int16{0x01}, Type: DataTypeUINT16, Raw: uint64(254), } data.Values[Gear] = TelemetryField{ - ID: 0x02, + IDs: []int16{0x02}, Type: DataTypeCHAR, Raw: uint64('R'), } - expect := []byte{0x01, 0x00, 0x02, 0xFE, 0x00, 0x02, 0x00, 0x09, 0x52} + data.Values[Empty] = TelemetryField{ + IDs: []int16{0x03, 0x04, 0x05}, + Type: DataTypeCHAR, + Raw: uint64('-'), + } + + expect := []byte{ + 0x01, 0x00, 0x02, 0xFE, 0x00, + 0x02, 0x00, 0x09, 0x52, + 0x03, 0x00, 0x09, 0x2d, + 0x04, 0x00, 0x09, 0x2d, + 0x05, 0x00, 0x09, 0x2d, + } result := data.Pack() if !bytes.Equal(result, expect) {