Skip to content

Commit

Permalink
update to struct-buffer v6 api
Browse files Browse the repository at this point in the history
  • Loading branch information
noahm committed Apr 23, 2024
1 parent 4f60aa1 commit 90d6116
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 63 deletions.
24 changes: 12 additions & 12 deletions sdk/commands/config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { StructBuffer, bits, uint8_t, uint16_t, sbytes } from "@nmann/struct-buffer";
import { EnabledSensors } from "./enabled-sensors.ts";
import { enabledSensors_t } from "./enabled-sensors.ts";
import { Panel } from "../api.ts";
import { padData } from "../utils.ts";

Expand All @@ -9,7 +9,7 @@ export type Decoded<Struct extends { decode(...args: unknown[]): unknown }> = Re
* Each panel has various thresholds that are used based on
* if it's a LoadCell or FSR panel.
*/
const packed_panel_settings_t = new StructBuffer("packed_panel_settings_t", {
const packed_panel_settings_t = new StructBuffer({

Check failure on line 12 in sdk/commands/config.ts

View workflow job for this annotation

GitHub Actions / Typescript

Expected 2-3 arguments, but got 1.
/**
* Load Cell Thresholds
*/
Expand Down Expand Up @@ -56,7 +56,7 @@ const flags_t = bits(uint8_t, {
/**
* Just an RGB struct for named access
*/
const rgb_t = new StructBuffer("rbg_t", {
const rgb_t = new StructBuffer({

Check failure on line 59 in sdk/commands/config.ts

View workflow job for this annotation

GitHub Actions / Typescript

Expected 2-3 arguments, but got 1.
r: uint8_t,
g: uint8_t,
b: uint8_t,
Expand All @@ -69,7 +69,7 @@ const rgb_t = new StructBuffer("rbg_t", {
* The order and packing of this struct corresponds to the configuration packet sent to
* the master controller, so it must not be changed.
*/
export const smx_config_t = new StructBuffer("smx_config_t", {
export const smx_config_t = new StructBuffer({

Check failure on line 72 in sdk/commands/config.ts

View workflow job for this annotation

GitHub Actions / Typescript

Expected 2-3 arguments, but got 1.
/**
* The firmware version of the master controller. Where supported (version 2 and up), this
* will always read back the firmware version. This will default to 0xFF on version 1.
Expand Down Expand Up @@ -120,7 +120,7 @@ export const smx_config_t = new StructBuffer("smx_config_t", {
* Which sensors on each panel to enable. This can be used to disable sensors that
* we know aren't populated.
*/
enabledSensors: new EnabledSensors(),
enabledSensors: enabledSensors_t,

/**
* How long the master controller will wait for a lights command before assuming
Expand Down Expand Up @@ -233,7 +233,7 @@ const NEW_CONFIG_INIT = [
"00".repeat(49),
];

const smx_old_config_t = new StructBuffer("smx_old_config_t", {
const smx_old_config_t = new StructBuffer({

Check failure on line 236 in sdk/commands/config.ts

View workflow job for this annotation

GitHub Actions / Typescript

Expected 2-3 arguments, but got 1.
unused1: uint8_t[6],

masterDebounceMilliseconds: uint16_t,
Expand Down Expand Up @@ -262,7 +262,7 @@ const smx_old_config_t = new StructBuffer("smx_old_config_t", {
panelThreshold1Low: uint8_t,
panelThreshold1High: uint8_t,

enabledSensors: new EnabledSensors(),
enabledSensors: enabledSensors_t,

autoLightsTimeout: uint8_t,

Expand Down Expand Up @@ -361,7 +361,7 @@ export class SMXConfig {
console.log("CONFIG RAW DATA: ", data.toString());

if (this.firmwareVersion >= 5) {
this.config = smx_config_t.decode(data.slice(2, -1), true);
this.config = smx_config_t.decode(data.slice(2, -1), { littleEndian: true });

Check failure on line 364 in sdk/commands/config.ts

View workflow job for this annotation

GitHub Actions / Typescript

Argument of type '{ littleEndian: boolean; }' is not assignable to parameter of type 'boolean | undefined'.
} else {
this.oldConfigSize = data[1];
console.log("Reading Old Config");
Expand All @@ -370,21 +370,21 @@ export class SMXConfig {
// handle very old stage's smaller config data by padding
// it out to the full size of the `smx_old_config_t` struct
const paddedData = padData(slicedData, smx_old_config_t.byteLength);
this.oldConfig = smx_old_config_t.decode(paddedData, true);
this.oldConfig = smx_old_config_t.decode(paddedData, { littleEndian: true });

Check failure on line 373 in sdk/commands/config.ts

View workflow job for this annotation

GitHub Actions / Typescript

Argument of type '{ littleEndian: boolean; }' is not assignable to parameter of type 'boolean | undefined'.
this.config = this.convertOldToNew(this.oldConfig);
}
}

encode(): Uint8Array {
if (this.firmwareVersion >= 5) {
return new Uint8Array(smx_config_t.encode(this.config, true).buffer);
return new Uint8Array(smx_config_t.encode(this.config, { littleEndian: true }).buffer);

Check failure on line 380 in sdk/commands/config.ts

View workflow job for this annotation

GitHub Actions / Typescript

Argument of type '{ littleEndian: boolean; }' is not assignable to parameter of type 'boolean | undefined'.
}

if (!this.oldConfig) throw new ReferenceError("Can not encode old config as it is null");
console.log("Writing Old Config");
this.convertNewToOld();

const encodedConfig = smx_old_config_t.encode(this.oldConfig, true);
const encodedConfig = smx_old_config_t.encode(this.oldConfig, { littleEndian: true });

Check failure on line 387 in sdk/commands/config.ts

View workflow job for this annotation

GitHub Actions / Typescript

Argument of type '{ littleEndian: boolean; }' is not assignable to parameter of type 'boolean | undefined'.
// If the old config data is less than 128 Bytes, only send the first 128 bytes
if (this.oldConfigSize && this.oldConfigSize <= 128) {
return new Uint8Array(encodedConfig.buffer.slice(0, 128));
Expand Down Expand Up @@ -470,7 +470,7 @@ export class SMXConfig {
*/
private convertOldToNew(oldConfig: Decoded<typeof smx_old_config_t>): Decoded<typeof smx_config_t> {
console.log("old config: ", oldConfig);
const newConfig = smx_config_t.decode(sbytes(NEW_CONFIG_INIT.join("")), false);
const newConfig = smx_config_t.decode(sbytes(NEW_CONFIG_INIT.join("")), { littleEndian: false });

newConfig.debounceNodelayMilliseconds = oldConfig.masterDebounceMilliseconds;

Expand Down
4 changes: 2 additions & 2 deletions sdk/commands/data_info.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { StructBuffer, char, uint8_t, uint16_t } from "@nmann/struct-buffer";

const data_info_packet_t = new StructBuffer("data_info_packet_t", {
const data_info_packet_t = new StructBuffer({
/** Always 'I' */
cmd: char,
// Not Used
Expand Down Expand Up @@ -28,7 +28,7 @@ export class SMXDeviceInfo {
}

#decode(data: Uint8Array) {
const info_packet = data_info_packet_t.decode(data, true);
const info_packet = data_info_packet_t.decode(data, { littleEndian: true });

this.player = Number.parseInt(String.fromCharCode(info_packet.player)) + 1;
this.serial = info_packet.serial.map((x) => `00${x.toString(16).toUpperCase()}`.slice(-2)).join("");
Expand Down
10 changes: 4 additions & 6 deletions sdk/commands/enabled-sensors.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { sbytes, sview } from "@nmann/struct-buffer";
import { expect, test, describe } from "vitest";
import { twoEnabledSensors_t, EnabledSensors } from "./enabled-sensors";
import { twoEnabledSensors_t, enabledSensors_t } from "./enabled-sensors";
import { SENSOR_COUNT } from "../api";

describe("twoEnabledSensors_t", () => {
test("encode", () => {
expect(twoEnabledSensors_t.decode(sbytes("F0"), false)).toEqual({
expect(twoEnabledSensors_t.decode(sbytes("F0"), { littleEndian: false })).toEqual({
left0: true,
right0: true,
up0: true,
Expand All @@ -29,8 +29,6 @@ describe("twoEnabledSensors_t", () => {
});
});

const enabledSensors = new EnabledSensors();

const decodedData = [
Array(SENSOR_COUNT).fill(false),
Array(SENSOR_COUNT).fill(true),
Expand All @@ -46,9 +44,9 @@ const decodedData = [
const encodedData = "0f 0f ff 0f 00";

test("decode", () => {
expect(enabledSensors.decode(sbytes(encodedData))).toEqual(decodedData);
expect(enabledSensors_t.decode(sbytes(encodedData))).toEqual(decodedData);
});

test("encode", () => {
expect(sview(enabledSensors.encode(decodedData))).toEqual(encodedData);
expect(sview(enabledSensors_t.encode(decodedData))).toEqual(encodedData);
});
59 changes: 21 additions & 38 deletions sdk/commands/enabled-sensors.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { StructBuffer, bits, createDataView, uint8_t } from "@nmann/struct-buffer";
import { Inject, bits, uint8_t } from "@nmann/struct-buffer";
import { SENSOR_COUNT, FsrSensor } from "../api";

type Decoded<Struct extends { decode(...args: unknown[]): unknown }> = ReturnType<Struct["decode"]>;
Expand Down Expand Up @@ -39,51 +39,34 @@ function joinTwoSensors(
};
}

export class EnabledSensors extends StructBuffer<
// biome-ignore lint/complexity/noBannedTypes: <explanation>
{},
Array<Array<boolean>>,
Array<Array<boolean>>
> {
constructor() {
super("EnabledSensors", {});
}
const BYTE_LENGTH = 5;

override get count() {
return 5; // always 5 items (5 twoDisabledSensors_t)
}

override get isList() {
return true;
}

override get byteLength() {
return 5;
}

override decode(view: DataView, littleEndian = false, offset = 0): Array<Array<boolean>> {
const decoded = twoEnabledSensors_t[this.count]
.decode(view, littleEndian, offset)
.flatMap<Array<boolean>>(splitTwoSensors);
/** very simple custom type that conveniently packs and unpacks */
export const enabledSensors_t = new Inject<Array<Array<boolean>>, Array<Array<boolean>>>(
// decode
(view, offset) => {
const decoded = twoEnabledSensors_t[BYTE_LENGTH].decode(view, { offset }).flatMap<Array<boolean>>(splitTwoSensors);

// decoded now has a trailing entry for the 4 bits of padding on the end of data
// so we slice to just the desired data
return decoded.slice(0, 9);
}
const value = decoded.slice(0, 9);

override encode(obj: Array<Array<boolean>>, littleEndian = false, offset = 0, view?: DataView): DataView {
if (obj.length !== 9) {
return {
size: BYTE_LENGTH,
value,
};
},
// encode
(values) => {
if (values.length !== 9) {
throw new TypeError("DisabledSensors only encodes sets of 9");
}
const v = createDataView(this.count, view);
const joined: Array<Decoded<typeof twoEnabledSensors_t>> = [];
for (let i = 0; i < this.count; i++) {
for (let i = 0; i < BYTE_LENGTH; i++) {
const aIdx = i * 2;
const bIdx = aIdx + 1;
joined.push(joinTwoSensors(obj[aIdx], bIdx < obj.length ? obj[bIdx] : undefined));
joined.push(joinTwoSensors(values[aIdx], bIdx < values.length ? values[bIdx] : undefined));
}
twoEnabledSensors_t[this.count].encode(joined, littleEndian, offset, v);

return v;
}
}
return twoEnabledSensors_t[BYTE_LENGTH].encode(joined);
},
);
8 changes: 4 additions & 4 deletions sdk/commands/sensor_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ const dips_t = bitFields(uint8_t, {
*
* These values are then used to create the `SMXPanelTestData` for each panel.
*/
const detail_data_t = new StructBuffer("detail_data_t", {
const detail_data_t = new StructBuffer({
sig_bad: sig_bad_t,
sensors: int16_t[4],
dips: dips_t,
Expand Down Expand Up @@ -205,8 +205,8 @@ export class SMXSensorTestData {
/**
* Convert the data from 8-Bit Little Endian Bytes to 16-Bit Integers
*/
const sensor_data_t = new StructBuffer("sensor_data_t", { data: uint16_t[size] });
const decoded_data = sensor_data_t.decode(data.slice(preamble), true);
const sensor_data_t = new StructBuffer({ data: uint16_t[size] });
const decoded_data = sensor_data_t.decode(data.slice(preamble), { littleEndian: true });

// Cycle through each panel and grab the data
for (let panel = 0; panel < PANEL_COUNT; panel++) {
Expand All @@ -231,7 +231,7 @@ export class SMXSensorTestData {
}

// Generate an SMXPanelTestData object for each panel
this.panels.push(new SMXPanelTestData(detail_data_t.decode(out_bytes, true), data_mode, isFsr));
this.panels.push(new SMXPanelTestData(detail_data_t.decode(out_bytes, { littleEndian: true }), data_mode, isFsr));
}
}
}
2 changes: 1 addition & 1 deletion sdk/smx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class SMXEvents {
// Panel Input State (If a panel is active or not)
this.inputState$ = rawReport$
.filter((e) => e.reportId === HID_REPORT_INPUT_STATE)
.map((e) => StageInputs.decode(e.data, true));
.map((e) => StageInputs.decode(e.data, { littleEndian: true }));

// All other reports (command responses)
const report$ = rawReport$
Expand Down

0 comments on commit 90d6116

Please sign in to comment.