@bloopjs/bloop 0.0.12 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/jsr.json +1 -1
- package/package.json +2 -2
- package/src/context.ts +2 -64
- package/src/mod.ts +8 -8
- package/test/tape.test.ts +49 -2
package/jsr.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bloopjs/bloop",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.13",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"@types/bun": "latest"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@bloopjs/engine": "0.0.
|
|
26
|
+
"@bloopjs/engine": "0.0.13"
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
29
|
"typescript": "^5"
|
package/src/context.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { InputSnapshot } from "@bloopjs/engine";
|
|
1
|
+
import type { EngineTiming, InputSnapshot } from "@bloopjs/engine";
|
|
2
2
|
import type { BloopSchema } from "./data/schema";
|
|
3
3
|
|
|
4
4
|
export type Context<
|
|
@@ -21,67 +21,5 @@ export type Context<
|
|
|
21
21
|
/** The input snapshot */
|
|
22
22
|
inputs: InputSnapshot;
|
|
23
23
|
/** The timing information for the current frame */
|
|
24
|
-
time: TimingSnapshot;
|
|
24
|
+
time: EngineTiming.TimingSnapshot;
|
|
25
25
|
};
|
|
26
|
-
|
|
27
|
-
export type TimingSnapshot = {
|
|
28
|
-
/** The number of seconds (usually fractional) since the last frame */
|
|
29
|
-
dt: number;
|
|
30
|
-
/** The total number of seconds since the engine started */
|
|
31
|
-
time: number;
|
|
32
|
-
/** The number of frames rendered since the engine started */
|
|
33
|
-
frame: number;
|
|
34
|
-
|
|
35
|
-
/** The current frame rate of the engine in frames per second */
|
|
36
|
-
// fps: number;
|
|
37
|
-
/** The number of frames rendered since the engine started */
|
|
38
|
-
highResFrame: bigint;
|
|
39
|
-
/** The total number of milliseconds since the engine started */
|
|
40
|
-
highResTime: bigint;
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export const TIMING_SNAPSHOT_SIZE = 32;
|
|
44
|
-
|
|
45
|
-
// these functions should go in engine
|
|
46
|
-
export function encodeTimingSnapshot(
|
|
47
|
-
ts: TimingSnapshot,
|
|
48
|
-
target: Uint8Array,
|
|
49
|
-
): number {
|
|
50
|
-
if (target.byteLength !== TIMING_SNAPSHOT_SIZE) {
|
|
51
|
-
throw new Error("Target buffer must be exactly 32 bytes");
|
|
52
|
-
}
|
|
53
|
-
const view = new DataView(
|
|
54
|
-
target.buffer,
|
|
55
|
-
target.byteOffset,
|
|
56
|
-
target.byteLength,
|
|
57
|
-
);
|
|
58
|
-
view.setFloat32(0, ts.dt, true);
|
|
59
|
-
view.setFloat32(4, ts.time, true);
|
|
60
|
-
view.setBigUint64(8, ts.highResFrame, true);
|
|
61
|
-
view.setBigUint64(16, ts.highResTime, true);
|
|
62
|
-
view.setUint32(24, ts.frame, true);
|
|
63
|
-
return TIMING_SNAPSHOT_SIZE;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export function decodeTimingSnapshot(
|
|
67
|
-
source: Uint8Array,
|
|
68
|
-
target: TimingSnapshot,
|
|
69
|
-
): number {
|
|
70
|
-
if (source.byteLength !== TIMING_SNAPSHOT_SIZE) {
|
|
71
|
-
throw new Error(
|
|
72
|
-
`Source buffer must be exactly ${TIMING_SNAPSHOT_SIZE} bytes`,
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
const view = new DataView(
|
|
76
|
-
source.buffer,
|
|
77
|
-
source.byteOffset,
|
|
78
|
-
source.byteLength,
|
|
79
|
-
);
|
|
80
|
-
target.dt = view.getFloat32(0, true);
|
|
81
|
-
target.time = view.getFloat32(4, true);
|
|
82
|
-
target.highResFrame = view.getBigUint64(8, true);
|
|
83
|
-
target.highResTime = view.getBigUint64(16, true);
|
|
84
|
-
target.frame = view.getUint32(24, true);
|
|
85
|
-
|
|
86
|
-
return TIMING_SNAPSHOT_SIZE;
|
|
87
|
-
}
|
package/src/mod.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { BloopSchema } from "./data/schema";
|
|
2
2
|
import type { Bag } from "./data/bag";
|
|
3
3
|
import type { System } from "./system";
|
|
4
|
-
import { EngineInputs, type PlatformEvent } from "@bloopjs/engine";
|
|
5
|
-
import {
|
|
4
|
+
import { EngineTiming, EngineInputs, type PlatformEvent } from "@bloopjs/engine";
|
|
5
|
+
import { type Context } from "./context";
|
|
6
|
+
import { TIMING_SNAPSHOT_SIZE } from "../../engine/js/timing";
|
|
6
7
|
|
|
7
8
|
export type BloopOpts<B extends Bag> = {
|
|
8
9
|
/** defaults to "Game" */
|
|
@@ -65,7 +66,7 @@ export class Bloop<GS extends BloopSchema> {
|
|
|
65
66
|
};
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
get bag() {
|
|
69
|
+
get bag(): GS["B"] {
|
|
69
70
|
return this.#context.bag;
|
|
70
71
|
}
|
|
71
72
|
|
|
@@ -82,11 +83,11 @@ export class Bloop<GS extends BloopSchema> {
|
|
|
82
83
|
const encoder = new TextEncoder();
|
|
83
84
|
const textBytes = encoder.encode(str);
|
|
84
85
|
|
|
85
|
-
const size = TIMING_SNAPSHOT_SIZE + 4 + textBytes.length;
|
|
86
|
+
const size = EngineTiming.TIMING_SNAPSHOT_SIZE + 4 + textBytes.length;
|
|
86
87
|
|
|
87
88
|
const buffer = new Uint8Array(size);
|
|
88
89
|
const view = new DataView(buffer.buffer);
|
|
89
|
-
let offset = encodeTimingSnapshot(this.#context.time, buffer.subarray(0, TIMING_SNAPSHOT_SIZE));
|
|
90
|
+
let offset = EngineTiming.encodeTimingSnapshot(this.#context.time, buffer.subarray(0, EngineTiming.TIMING_SNAPSHOT_SIZE));
|
|
90
91
|
view.setUint32(offset, textBytes.length, true);
|
|
91
92
|
offset += 4;
|
|
92
93
|
|
|
@@ -96,16 +97,15 @@ export class Bloop<GS extends BloopSchema> {
|
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
restore(snapshot: Uint8Array) {
|
|
99
|
-
const size = decodeTimingSnapshot(new Uint8Array(snapshot.buffer, 0,
|
|
100
|
+
const size = EngineTiming.decodeTimingSnapshot(new Uint8Array(snapshot.buffer, 0, EngineTiming.TIMING_SNAPSHOT_SIZE), this.#context.time);
|
|
100
101
|
const view = new DataView(snapshot.buffer);
|
|
101
102
|
let offset = size;
|
|
102
|
-
const length = view.getUint32(
|
|
103
|
+
const length = view.getUint32(offset, true);
|
|
103
104
|
offset += 4;
|
|
104
105
|
const bagBytes = snapshot.slice(offset, offset + length);
|
|
105
106
|
const decoder = new TextDecoder();
|
|
106
107
|
const str = decoder.decode(bagBytes);
|
|
107
108
|
this.#context.bag = JSON.parse(str);
|
|
108
|
-
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
/**
|
package/test/tape.test.ts
CHANGED
|
@@ -30,13 +30,22 @@ describe("tapes", () => {
|
|
|
30
30
|
expect(bloop.bag.cool).toEqual(43);
|
|
31
31
|
});
|
|
32
32
|
|
|
33
|
-
it("
|
|
33
|
+
it("can snapshot the bag on frame 0", async () => {
|
|
34
34
|
const bloop = Bloop.create({
|
|
35
35
|
bag: {
|
|
36
|
-
|
|
36
|
+
score: 10,
|
|
37
37
|
},
|
|
38
38
|
});
|
|
39
39
|
|
|
40
|
+
await mount(bloop);
|
|
41
|
+
const snapshot = bloop.snapshot();
|
|
42
|
+
bloop.restore(snapshot);
|
|
43
|
+
expect(bloop.bag.score).toEqual(10);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("snapshots time", async () => {
|
|
47
|
+
const bloop = Bloop.create();
|
|
48
|
+
|
|
40
49
|
const timeCheck = {
|
|
41
50
|
dt: 0,
|
|
42
51
|
time: 0,
|
|
@@ -77,4 +86,42 @@ describe("tapes", () => {
|
|
|
77
86
|
expect(bloop.context.time.frame).toEqual(2);
|
|
78
87
|
});
|
|
79
88
|
});
|
|
89
|
+
|
|
90
|
+
describe("playback", () => {
|
|
91
|
+
it("can play back inputs", async () => {
|
|
92
|
+
const bloop = Bloop.create({
|
|
93
|
+
bag: {
|
|
94
|
+
clicks: 0,
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
bloop.system("countClicks", {
|
|
99
|
+
update({ bag, inputs }) {
|
|
100
|
+
if (inputs.mouse.left.down) {
|
|
101
|
+
bag.clicks++;
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const { runtime, emitter } = await mount(bloop);
|
|
107
|
+
|
|
108
|
+
runtime.record();
|
|
109
|
+
emitter.mousedown("Left");
|
|
110
|
+
runtime.step();
|
|
111
|
+
expect(bloop.context.time.frame).toEqual(1);
|
|
112
|
+
expect(bloop.bag.clicks).toEqual(1);
|
|
113
|
+
emitter.mouseup("Left");
|
|
114
|
+
runtime.step();
|
|
115
|
+
expect(bloop.context.time.frame).toEqual(2);
|
|
116
|
+
expect(bloop.bag.clicks).toEqual(1);
|
|
117
|
+
|
|
118
|
+
runtime.stepBack();
|
|
119
|
+
expect(bloop.context.time.frame).toEqual(1);
|
|
120
|
+
expect(bloop.bag.clicks).toEqual(1);
|
|
121
|
+
|
|
122
|
+
runtime.stepBack();
|
|
123
|
+
expect(bloop.context.time.frame).toEqual(0);
|
|
124
|
+
expect(bloop.bag.clicks).toEqual(0);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
80
127
|
});
|