Skip to content

Commit

Permalink
Simplified type declarations. (#6)
Browse files Browse the repository at this point in the history
* Simplified type declarations.
* Updated Node versions in CI
  • Loading branch information
iwoplaza authored Feb 19, 2024
1 parent 952df6b commit 4630e36
Show file tree
Hide file tree
Showing 30 changed files with 2,839 additions and 1,295 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node-version: [12.x, 14.x, 16.x]
node-version: [16.x, 20.x]

steps:
- name: Checkout Code Repository
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
.vscode

dist
**/node_modules
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Gives tools to describe binary structures with full TypeScript support. Encodes

Serialise and deserialise typed schemas without the need for redundant interfaces or an external DSL. Schemas themselves define what type they encode and decode, and **the IDE knows it**!

![Basic Type and Documentation Inferrence](/docs/media/basic-type-and-doc-inferrence.gif)
![Basic Type and Documentation Inference](/docs/media/basic-type-and-doc-inferrence.gif)

Above is a self-contained code snippet using typed-binary. The IDE can properly infer what `Dog` is. What's even more interesting, is that the "parsed" properties inherit the schema's **JSDocs** (seen on the gif above).

Expand Down
17 changes: 10 additions & 7 deletions examples/__util/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { BufferWriter, BufferReader, Schema } from 'typed-binary';
import { BufferWriter, BufferReader, AnySchema, Parsed } from 'typed-binary';

export function writeAndRead<T>(schema: Schema<T>, value: T) {
const buffer = Buffer.alloc(schema.sizeOf(value));
const writer = new BufferWriter(buffer);
const reader = new BufferReader(buffer);
export function writeAndRead<TSchema extends AnySchema>(
schema: TSchema,
value: Parsed<TSchema>,
) {
const buffer = Buffer.alloc(schema.measure(value).size);
const writer = new BufferWriter(buffer);
const reader = new BufferReader(buffer);

schema.write(writer, value);
return schema.read(reader);
schema.write(writer, value);
return schema.read(reader);
}
86 changes: 42 additions & 44 deletions examples/binaryMesh/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,68 +3,66 @@ import fs from 'fs/promises';
import { Mesh } from './schemas';

const DEFAULT_MESH: Mesh = {
faces: [
{
vertices: [
{ x: 0, y: 0, z: 0 },
{ x: 1, y: 0, z: 0.1 },
{ x: 0, y: 1, z: -0.1 },
]
}
],
faces: [
{
vertices: [
{ x: 0, y: 0, z: 0 },
{ x: 1, y: 0, z: 0.1 },
{ x: 0, y: 1, z: -0.1 },
],
},
],
};

async function loadMesh(): Promise<Mesh> {
try {
const buffer = await fs.readFile('./binaryMesh/mesh.bin');
const reader = new BufferReader(buffer);
try {
const buffer = await fs.readFile('./binaryMesh/mesh.bin');
const reader = new BufferReader(buffer);

return Mesh.read(reader);
}
catch (e) {
return DEFAULT_MESH;
}
return Mesh.read(reader);
} catch (e) {
return DEFAULT_MESH;
}
}

async function saveMesh(mesh: Mesh): Promise<void> {
try {
const buffer = Buffer.alloc(Mesh.sizeOf(mesh));
const writer = new BufferWriter(buffer);
try {
const buffer = Buffer.alloc(Mesh.measure(mesh).size);
const writer = new BufferWriter(buffer);

Mesh.write(writer, mesh);
Mesh.write(writer, mesh);

await fs.writeFile('./binaryMesh/mesh.bin', buffer);
}
catch (e) {
console.error(`Error occurred during mesh saving.`);
console.error(e);
}
await fs.writeFile('./binaryMesh/mesh.bin', buffer);
} catch (e) {
console.error(`Error occurred during mesh saving.`);
console.error(e);
}
}

function meshToString(mesh: Mesh): string {
let text = '';
for (const face of mesh.faces) {
for (const v of face.vertices) {
text += `(${v.x}, ${v.y}, ${v.z}) `;
}
let text = '';
for (const face of mesh.faces) {
for (const v of face.vertices) {
text += `(${v.x}, ${v.y}, ${v.z}) `;
}
return text;
}
return text;
}

async function init() {
// Loading the mesh
const mesh = await loadMesh();
console.log(meshToString(mesh));
// Loading the mesh
const mesh = await loadMesh();
console.log(meshToString(mesh));

// Translating the mesh
mesh.faces.forEach(f => {
f.vertices.forEach(v => {
v.x += 1;
});
// Translating the mesh
mesh.faces.forEach((f) => {
f.vertices.forEach((v) => {
v.x += 1;
});
});

// Storing the mesh
await saveMesh(mesh);
// Storing the mesh
await saveMesh(mesh);
}

init();
init();
12 changes: 7 additions & 5 deletions examples/customSchema/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ import { RADIANS } from './radians';

type Rotation = Parsed<typeof Rotation>;
const Rotation = object({
roll: RADIANS,
pitch: RADIANS,
yaw: RADIANS,
roll: RADIANS,
pitch: RADIANS,
yaw: RADIANS,
});

console.log(writeAndRead(Rotation, {
console.log(
writeAndRead(Rotation, {
roll: -0.1,
pitch: 0.12345,
yaw: Math.PI + 1.12345,
}));
}),
);
73 changes: 42 additions & 31 deletions examples/customSchema/radians.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,50 @@
import { ISerialInput, ISerialOutput, Schema, IRefResolver } from 'typed-binary';
import {
ISerialInput,
ISerialOutput,
Schema,
IRefResolver,
MaxValue,
IMeasurer,
Measurer,
} from 'typed-binary';

/**
* A schema storing radians with 2 bytes of precision.
*/
class RadiansSchema extends Schema<number> {
resolve(ctx: IRefResolver): void {
// No inner references to resolve
}

read(input: ISerialInput): number {
const low = input.readByte();
const high = input.readByte();

const discrete = (high << 8) | low;
return discrete / 65535 * Math.PI;
}

write(output: ISerialOutput, value: number): void {
// The value will be wrapped to be in range of [0, Math.PI)
const wrapped = ((value % Math.PI) + Math.PI) % Math.PI;
// Discretising the value to be ints in range of [0, 65535]
const discrete = Math.min(Math.floor(wrapped / Math.PI * 65535), 65535);

const low = discrete & 0xFF;
const high = (discrete >> 8) & 0xFF;

output.writeByte(low);
output.writeByte(high);
}

sizeOf(_: number): number {
// The size of the data serialized by this schema
// doesn't depend on the actual value. It's always 2 bytes.
return 2;
}
resolve(ctx: IRefResolver): void {
// No inner references to resolve
}

read(input: ISerialInput): number {
const low = input.readByte();
const high = input.readByte();

const discrete = (high << 8) | low;
return (discrete / 65535) * Math.PI;
}

write(output: ISerialOutput, value: number): void {
// The value will be wrapped to be in range of [0, Math.PI)
const wrapped = ((value % Math.PI) + Math.PI) % Math.PI;
// Discretising the value to be ints in range of [0, 65535]
const discrete = Math.min(Math.floor((wrapped / Math.PI) * 65535), 65535);

const low = discrete & 0xff;
const high = (discrete >> 8) & 0xff;

output.writeByte(low);
output.writeByte(high);
}

measure(
_: number | MaxValue,
measurer: IMeasurer = new Measurer(),
): IMeasurer {
// The size of the data serialized by this schema
// doesn't depend on the actual value. It's always 2 bytes.
return measurer.add(2);
}
}

export const RADIANS = new RadiansSchema();
Loading

0 comments on commit 4630e36

Please sign in to comment.