@woosh/meep-engine 3.46.0 → 3.47.0
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/editor/actions/concrete/TransformModifyAction.d.ts.map +1 -1
- package/editor/actions/concrete/TransformModifyAction.js +10 -2
- package/editor/ecs/component/FieldDescriptor.js +15 -0
- package/editor/ecs/component/createObjectEditor.js +41 -12
- package/editor/ecs/component/editors/ecs/Transform64Editor.d.ts.map +1 -1
- package/editor/ecs/component/editors/ecs/Transform64Editor.js +77 -70
- package/editor/tools/TransformToolV2.d.ts.map +1 -1
- package/editor/tools/TransformToolV2.js +4 -0
- package/editor/tools/v2/TransformControls.d.ts.map +1 -1
- package/editor/tools/v2/TransformControls.js +7 -0
- package/editor/view/ecs/EntityEditor.d.ts.map +1 -1
- package/editor/view/ecs/EntityEditor.js +4 -2
- package/package.json +1 -1
- package/src/core/collection/array/array_insert_at.d.ts +16 -0
- package/src/core/collection/array/array_insert_at.d.ts.map +1 -0
- package/src/core/collection/array/array_insert_at.js +32 -0
- package/src/core/collection/array/array_remove_at.d.ts +15 -0
- package/src/core/collection/array/array_remove_at.d.ts.map +1 -0
- package/src/core/collection/array/array_remove_at.js +30 -0
- package/src/core/geom/3d/quaternion/quat3_look_rotation.d.ts +37 -0
- package/src/core/geom/3d/quaternion/quat3_look_rotation.d.ts.map +1 -0
- package/src/core/geom/3d/quaternion/quat3_look_rotation.js +172 -0
- package/src/core/geom/Quaternion.d.ts +1 -0
- package/src/core/geom/Quaternion.d.ts.map +1 -1
- package/src/core/geom/Quaternion.js +12 -48
- package/src/engine/Engine.d.ts.map +1 -1
- package/src/engine/Engine.js +9 -4
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +10 -0
- package/src/engine/ecs/transform/t64_look_rotation.d.ts +4 -4
- package/src/engine/ecs/transform/t64_look_rotation.d.ts.map +1 -1
- package/src/engine/ecs/transform/t64_look_rotation.js +7 -18
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js +30 -1
- package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts +6 -0
- package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -1
- package/src/engine/graphics3/GPUParticleEmitterSystem.js +72 -29
- package/src/engine/input/devices/KeyboardDevice.d.ts +1 -0
- package/src/engine/input/devices/KeyboardDevice.d.ts.map +1 -1
- package/src/engine/input/devices/KeyboardDevice.js +7 -6
- package/src/engine/navigation/ecs/path_following/PathFollowingSystem.d.ts.map +1 -1
- package/src/engine/navigation/ecs/path_following/PathFollowingSystem.js +15 -2
- package/src/engine/network/CONGESTION_CONTROL.md +9 -9
- package/src/engine/network/MESSAGE_TRANSPORT.md +364 -0
- package/src/engine/network/NetworkSession.d.ts +31 -11
- package/src/engine/network/NetworkSession.d.ts.map +1 -1
- package/src/engine/network/NetworkSession.js +453 -286
- package/src/engine/network/README.md +77 -27
- package/src/engine/network/SMOOTHNESS_DESIGN.md +13 -5
- package/src/engine/network/diagnostics/BandwidthMeter.d.ts +1 -1
- package/src/engine/network/diagnostics/BandwidthMeter.js +1 -1
- package/src/engine/network/orchestrator/HostJoin.d.ts +111 -0
- package/src/engine/network/orchestrator/HostJoin.d.ts.map +1 -0
- package/src/engine/network/orchestrator/HostJoin.js +271 -0
- package/src/engine/network/orchestrator/NetworkPeer.d.ts +151 -112
- package/src/engine/network/orchestrator/NetworkPeer.d.ts.map +1 -1
- package/src/engine/network/orchestrator/NetworkPeer.js +450 -499
- package/src/engine/network/orchestrator/PendingSlices.d.ts +30 -0
- package/src/engine/network/orchestrator/PendingSlices.d.ts.map +1 -0
- package/src/engine/network/orchestrator/PendingSlices.js +83 -0
- package/src/engine/network/orchestrator/ReliableFrames.d.ts +34 -0
- package/src/engine/network/orchestrator/ReliableFrames.d.ts.map +1 -0
- package/src/engine/network/orchestrator/ReliableFrames.js +96 -0
- package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts +77 -10
- package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts.map +1 -1
- package/src/engine/network/orchestrator/ServerAuthoritativeClient.js +236 -61
- package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts +20 -6
- package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts.map +1 -1
- package/src/engine/network/orchestrator/ServerAuthoritativeServer.js +33 -8
- package/src/engine/network/replication/Replicator.d.ts.map +1 -1
- package/src/engine/network/replication/Replicator.js +7 -1
- package/src/engine/network/sim/ActionLog.d.ts +32 -5
- package/src/engine/network/sim/ActionLog.d.ts.map +1 -1
- package/src/engine/network/sim/ActionLog.js +47 -5
- package/src/engine/network/sim/SimActionExecutor.d.ts +42 -2
- package/src/engine/network/sim/SimActionExecutor.d.ts.map +1 -1
- package/src/engine/network/sim/SimActionExecutor.js +100 -4
- package/src/engine/network/sim/Snapshotter.d.ts +12 -0
- package/src/engine/network/sim/Snapshotter.d.ts.map +1 -1
- package/src/engine/network/sim/Snapshotter.js +43 -0
- package/src/engine/network/state/Baseline.d.ts +1 -1
- package/src/engine/network/state/Baseline.js +1 -1
- package/src/engine/network/state/FrameBufferRing.d.ts +25 -6
- package/src/engine/network/state/FrameBufferRing.d.ts.map +1 -1
- package/src/engine/network/state/FrameBufferRing.js +51 -6
- package/src/engine/network/state/InputRing.d.ts +4 -0
- package/src/engine/network/state/InputRing.d.ts.map +1 -1
- package/src/engine/network/state/InputRing.js +7 -0
- package/src/engine/network/transport/DeferredTransport.d.ts.map +1 -1
- package/src/engine/network/transport/DeferredTransport.js +1 -0
- package/src/engine/network/transport/LoopbackTransport.d.ts.map +1 -1
- package/src/engine/network/transport/LoopbackTransport.js +4 -2
- package/src/engine/network/transport/Transport.d.ts +7 -0
- package/src/engine/network/transport/Transport.d.ts.map +1 -1
- package/src/engine/network/transport/Transport.js +8 -0
- package/src/engine/network/transport/adapters/NodeUDPTransport.d.ts.map +1 -1
- package/src/engine/network/transport/adapters/NodeUDPTransport.js +20 -5
- package/src/engine/network/transport/adapters/WebRTCDataChannelTransport.d.ts.map +1 -1
- package/src/engine/network/transport/adapters/WebRTCDataChannelTransport.js +8 -0
- package/src/engine/network/transport/adapters/WebTransportTransport.d.ts.map +1 -1
- package/src/engine/network/transport/adapters/WebTransportTransport.js +6 -0
- package/src/engine/network/transport/connection/Connection.d.ts +191 -0
- package/src/engine/network/transport/connection/Connection.d.ts.map +1 -0
- package/src/engine/network/transport/connection/Connection.js +1262 -0
- package/src/engine/network/transport/connection/RangeSet.d.ts +94 -0
- package/src/engine/network/transport/connection/RangeSet.d.ts.map +1 -0
- package/src/engine/network/transport/connection/RangeSet.js +260 -0
- package/src/engine/network/transport/connection/RxStream.d.ts +48 -0
- package/src/engine/network/transport/connection/RxStream.d.ts.map +1 -0
- package/src/engine/network/transport/connection/RxStream.js +211 -0
- package/src/engine/network/transport/connection/TxStream.d.ts +90 -0
- package/src/engine/network/transport/connection/TxStream.d.ts.map +1 -0
- package/src/engine/network/transport/connection/TxStream.js +243 -0
- package/src/engine/network/transport/connection/bytes_copy.d.ts +17 -0
- package/src/engine/network/transport/connection/bytes_copy.d.ts.map +1 -0
- package/src/engine/network/transport/connection/bytes_copy.js +34 -0
- package/src/engine/network/transport/connection/varint.d.ts +46 -0
- package/src/engine/network/transport/connection/varint.d.ts.map +1 -0
- package/src/engine/network/transport/connection/varint.js +107 -0
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/engine/sound/ecs/audio/AudioEmitter.d.ts +38 -7
- package/src/engine/sound/ecs/audio/AudioEmitter.d.ts.map +1 -1
- package/src/engine/sound/ecs/audio/AudioEmitter.js +35 -7
- package/src/engine/sound/ecs/audio/AudioEmitterSerializationAdapter.d.ts.map +1 -1
- package/src/engine/sound/ecs/audio/AudioEmitterSerializationAdapter.js +5 -1
- package/src/engine/sound/ecs/audio/AudioEmitterSerializationUpgrader_0_1.d.ts +18 -0
- package/src/engine/sound/ecs/audio/AudioEmitterSerializationUpgrader_0_1.d.ts.map +1 -0
- package/src/engine/sound/ecs/audio/AudioEmitterSerializationUpgrader_0_1.js +48 -0
- package/src/engine/sound/ecs/audio/AudioEmitterSystem.d.ts +12 -2
- package/src/engine/sound/ecs/audio/AudioEmitterSystem.d.ts.map +1 -1
- package/src/engine/sound/ecs/audio/AudioEmitterSystem.js +173 -9
- package/src/engine/sound/ecs/audio/LiveEmitterSet.d.ts +9 -3
- package/src/engine/sound/ecs/audio/LiveEmitterSet.d.ts.map +1 -1
- package/src/engine/sound/ecs/audio/LiveEmitterSet.js +28 -8
- package/src/engine/sound/ecs/trigger/AudioEventTrigger.d.ts +8 -0
- package/src/engine/sound/ecs/trigger/AudioEventTrigger.d.ts.map +1 -1
- package/src/engine/sound/ecs/trigger/AudioEventTriggerSerializationAdapter.d.ts.map +1 -1
- package/src/engine/sound/ecs/trigger/AudioEventTriggerSerializationAdapter.js +5 -1
- package/src/engine/sound/ecs/trigger/AudioEventTriggerSerializationUpgrader_0_1.d.ts +18 -0
- package/src/engine/sound/ecs/trigger/AudioEventTriggerSerializationUpgrader_0_1.d.ts.map +1 -0
- package/src/engine/sound/ecs/trigger/AudioEventTriggerSerializationUpgrader_0_1.js +51 -0
- package/src/engine/sound/ecs/trigger/AudioEventTriggerSystem.d.ts.map +1 -1
- package/src/engine/sound/ecs/trigger/AudioEventTriggerSystem.js +15 -1
- package/src/engine/sound/sopra/README.md +768 -644
- package/src/engine/sound/sopra/SopraEngine.d.ts +104 -8
- package/src/engine/sound/sopra/SopraEngine.d.ts.map +1 -1
- package/src/engine/sound/sopra/SopraEngine.js +327 -12
- package/src/engine/sound/sopra/definition/EventDescription.d.ts +28 -2
- package/src/engine/sound/sopra/definition/EventDescription.d.ts.map +1 -1
- package/src/engine/sound/sopra/definition/EventDescription.js +55 -5
- package/src/engine/sound/sopra/definition/EventDescriptionSerializationAdapter.d.ts +10 -0
- package/src/engine/sound/sopra/definition/EventDescriptionSerializationAdapter.d.ts.map +1 -1
- package/src/engine/sound/sopra/definition/EventDescriptionSerializationAdapter.js +77 -55
- package/src/engine/sound/sopra/definition/EventDescriptionSerializationUpgrader_0_1.d.ts +31 -0
- package/src/engine/sound/sopra/definition/EventDescriptionSerializationUpgrader_0_1.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/EventDescriptionSerializationUpgrader_0_1.js +75 -0
- package/src/engine/sound/sopra/definition/effect/AbstractAudioEffect.d.ts +38 -9
- package/src/engine/sound/sopra/definition/effect/AbstractAudioEffect.d.ts.map +1 -1
- package/src/engine/sound/sopra/definition/effect/AbstractAudioEffect.js +34 -5
- package/src/engine/sound/sopra/definition/effect/CompressorEffect.d.ts +7 -2
- package/src/engine/sound/sopra/definition/effect/CompressorEffect.d.ts.map +1 -1
- package/src/engine/sound/sopra/definition/effect/CompressorEffect.js +137 -122
- package/src/engine/sound/sopra/definition/effect/EqEffect.d.ts +3 -1
- package/src/engine/sound/sopra/definition/effect/EqEffect.d.ts.map +1 -1
- package/src/engine/sound/sopra/definition/effect/EqEffect.js +146 -131
- package/src/engine/sound/sopra/definition/effect/ReverbEffect.d.ts +1 -0
- package/src/engine/sound/sopra/definition/effect/ReverbEffect.d.ts.map +1 -1
- package/src/engine/sound/sopra/definition/effect/ReverbEffect.js +6 -1
- package/src/engine/sound/sopra/runtime/BusGraph.d.ts +44 -2
- package/src/engine/sound/sopra/runtime/BusGraph.d.ts.map +1 -1
- package/src/engine/sound/sopra/runtime/BusGraph.js +83 -43
- package/src/engine/sound/sopra/runtime/EffectChain.d.ts +96 -0
- package/src/engine/sound/sopra/runtime/EffectChain.d.ts.map +1 -0
- package/src/engine/sound/sopra/runtime/EffectChain.js +286 -0
- package/src/engine/sound/sopra/runtime/EffectParamOverrides.d.ts +123 -0
- package/src/engine/sound/sopra/runtime/EffectParamOverrides.d.ts.map +1 -0
- package/src/engine/sound/sopra/runtime/EffectParamOverrides.js +320 -0
- package/src/engine/sound/sopra/runtime/EventInstance.d.ts +55 -5
- package/src/engine/sound/sopra/runtime/EventInstance.d.ts.map +1 -1
- package/src/engine/sound/sopra/runtime/EventInstance.js +201 -26
- package/src/engine/sound/sopra/serialization/populateSopraSerializationRegistry.d.ts +2 -1
- package/src/engine/sound/sopra/serialization/populateSopraSerializationRegistry.d.ts.map +1 -1
- package/src/engine/sound/sopra/serialization/populateSopraSerializationRegistry.js +6 -1
- package/src/engine/sound/sopra/serialization/sopraSerializationHarness.d.ts +15 -0
- package/src/engine/sound/sopra/serialization/sopraSerializationHarness.d.ts.map +1 -1
- package/src/engine/sound/sopra/serialization/sopraSerializationHarness.js +32 -0
- package/src/engine/sound/sopra/util/MockAudioContext.d.ts.map +1 -1
- package/src/engine/sound/sopra/util/MockAudioContext.js +3 -0
- package/src/engine/sound/sopra/util/fadeOutAndStop.d.ts +13 -3
- package/src/engine/sound/sopra/util/fadeOutAndStop.d.ts.map +1 -1
- package/src/engine/sound/sopra/util/fadeOutAndStop.js +25 -13
- package/src/shade/RENDERER_CONTRACT.md +6 -3
- package/src/shade/device/SHADE_DEVICE_FLOOR.d.ts +24 -0
- package/src/shade/device/SHADE_DEVICE_FLOOR.d.ts.map +1 -0
- package/src/shade/device/SHADE_DEVICE_FLOOR.js +34 -0
- package/src/shade/device/ShadeDeviceFailure.d.ts +12 -5
- package/src/shade/device/ShadeDeviceFailure.d.ts.map +1 -1
- package/src/shade/device/ShadeDeviceFailure.js +17 -8
- package/src/shade/device/ShadeDeviceFailureReason.d.ts +1 -1
- package/src/shade/device/ShadeDeviceFailureReason.js +2 -2
- package/src/shade/device/shade_device_floor_unmet.d.ts +13 -0
- package/src/shade/device/shade_device_floor_unmet.d.ts.map +1 -0
- package/src/shade/device/shade_device_floor_unmet.js +32 -0
- package/src/shade/renderer/Renderer.d.ts +2 -0
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +29 -55
- package/src/shade/renderer/buffer/GPUBufferAllocator.d.ts.map +1 -1
- package/src/shade/renderer/buffer/GPUBufferAllocator.js +9 -0
- package/src/shade/renderer/buffer/buffer_pool_ops.d.ts +21 -12
- package/src/shade/renderer/buffer/buffer_pool_ops.d.ts.map +1 -1
- package/src/shade/renderer/buffer/buffer_pool_ops.js +18 -19
- package/src/shade/renderer/gpu_primitive/test/gpu_test.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/test/gpu_test.js +8 -11
- package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
- package/src/shade/renderer/pool/TransientResourcePool.d.ts +24 -0
- package/src/shade/renderer/pool/TransientResourcePool.d.ts.map +1 -1
- package/src/shade/renderer/pool/TransientResourcePool.js +41 -10
- package/src/shade/renderer/shader/ComputeShader.d.ts.map +1 -1
- package/src/shade/renderer/shader/ComputeShader.js +18 -2
- package/src/shade/renderer/shader/ImageShader.d.ts.map +1 -1
- package/src/shade/renderer/shader/ImageShader.js +230 -218
- package/src/view/graphics/GraphicsContextFailureView.d.ts +1 -2
- package/src/view/graphics/GraphicsContextFailureView.d.ts.map +1 -1
- package/src/view/graphics/GraphicsContextFailureView.js +1 -2
- package/src/engine/network/transport/Channel.js +0 -336
- package/src/engine/network/transport/ReliableCommandPipeline.js +0 -335
- package/src/engine/network/transport/fragments/FragmentAssembler.js +0 -350
- package/src/engine/network/transport/fragments/FragmentRetention.js +0 -191
- package/src/engine/network/transport/fragments/fragment_send.js +0 -157
- package/src/engine/network/transport/fragments/packet_size.js +0 -107
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Send half of one reliable lane: an ordered byte stream of `[varint length][bytes]` messages.
|
|
3
|
+
*
|
|
4
|
+
* A message is copied once, into {@link #buffer}, when it is queued. What goes on the wire is byte
|
|
5
|
+
* ranges of the stream, and what a lost packet costs is the ranges it carried: they are queued for
|
|
6
|
+
* re-sending, minus anything acknowledged since. Bytes are released once every byte before them is
|
|
7
|
+
* acknowledged.
|
|
8
|
+
*
|
|
9
|
+
* Flow control needs no frames. The sender never sends a byte at or past `acked_prefix + window`.
|
|
10
|
+
* The receiver delivers each message the moment its bytes are contiguous and its contiguous point is
|
|
11
|
+
* never behind the sender's acked prefix, so what the receiver must hold out of order is bounded by
|
|
12
|
+
* the window, and what it holds in order is bounded by the largest message.
|
|
13
|
+
*
|
|
14
|
+
* @author Alex Goldring
|
|
15
|
+
* @copyright Company Named Limited (c) 2026
|
|
16
|
+
*/
|
|
17
|
+
export class TxStream {
|
|
18
|
+
/**
|
|
19
|
+
* @param {number} window bytes the sender may have past its acked prefix
|
|
20
|
+
*/
|
|
21
|
+
constructor(window: number);
|
|
22
|
+
/** @type {number} @readonly */
|
|
23
|
+
readonly window: number;
|
|
24
|
+
/** Stream offset one past the last byte queued. */
|
|
25
|
+
get end(): number;
|
|
26
|
+
/** Every byte below this is acknowledged. */
|
|
27
|
+
get acked_prefix(): number;
|
|
28
|
+
/**
|
|
29
|
+
* Whether anything is waiting to go out: a re-send, or new bytes the window lets through.
|
|
30
|
+
* @returns {boolean}
|
|
31
|
+
*/
|
|
32
|
+
has_sendable(): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Whether bytes are queued that the receiver has not acknowledged.
|
|
35
|
+
* @returns {boolean}
|
|
36
|
+
*/
|
|
37
|
+
has_unacked(): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Queue one message.
|
|
40
|
+
*
|
|
41
|
+
* @param {Uint8Array} bytes
|
|
42
|
+
* @param {number} offset
|
|
43
|
+
* @param {number} length
|
|
44
|
+
* @returns {number} stream offset one past the message: delivered once the acked prefix reaches it
|
|
45
|
+
*/
|
|
46
|
+
append(bytes: Uint8Array, offset: number, length: number): number;
|
|
47
|
+
/**
|
|
48
|
+
* Pick the next range to send, at most `max_length` bytes: the lowest pending re-send first,
|
|
49
|
+
* then new bytes up to the window. Writes `[offset, length]` into `out`; length 0 means nothing
|
|
50
|
+
* to send. The range is not marked sent until {@link mark_sent}.
|
|
51
|
+
*
|
|
52
|
+
* @param {number} max_length
|
|
53
|
+
* @param {Float64Array} out
|
|
54
|
+
*/
|
|
55
|
+
peek(max_length: number, out: Float64Array): void;
|
|
56
|
+
/**
|
|
57
|
+
* The range {@link peek} returned has gone out.
|
|
58
|
+
* @param {number} offset
|
|
59
|
+
* @param {number} length
|
|
60
|
+
*/
|
|
61
|
+
mark_sent(offset: number, length: number): void;
|
|
62
|
+
/**
|
|
63
|
+
* Copy stream bytes `[offset, offset + length)` into `out` at `out_offset`.
|
|
64
|
+
* @param {number} offset
|
|
65
|
+
* @param {number} length
|
|
66
|
+
* @param {Uint8Array} out
|
|
67
|
+
* @param {number} out_offset
|
|
68
|
+
*/
|
|
69
|
+
copy_out(offset: number, length: number, out: Uint8Array, out_offset: number): void;
|
|
70
|
+
/**
|
|
71
|
+
* A packet carrying `[offset, offset + length)` was acknowledged.
|
|
72
|
+
* @param {number} offset
|
|
73
|
+
* @param {number} length
|
|
74
|
+
*/
|
|
75
|
+
on_acked(offset: number, length: number): void;
|
|
76
|
+
/**
|
|
77
|
+
* A packet carrying `[offset, offset + length)` was declared lost, or is being probed: send what
|
|
78
|
+
* of it is still unacknowledged again.
|
|
79
|
+
* @param {number} offset
|
|
80
|
+
* @param {number} length
|
|
81
|
+
* @returns {boolean} whether any of it is still unacknowledged, and so queued to go again
|
|
82
|
+
*/
|
|
83
|
+
on_lost(offset: number, length: number): boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Forget everything: the connection is gone.
|
|
86
|
+
*/
|
|
87
|
+
clear(): void;
|
|
88
|
+
#private;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=TxStream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TxStream.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/network/transport/connection/TxStream.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;GAeG;AACH;IA4CI;;OAEG;IACH,oBAFW,MAAM,EAMhB;IAHG,+BAA+B;IAC/B,iBADW,MAAM,CACG;IAIxB,mDAAmD;IACnD,kBAEC;IAED,6CAA6C;IAC7C,2BAEC;IAED;;;OAGG;IACH,gBAFa,OAAO,CAKnB;IAED;;;OAGG;IACH,eAFa,OAAO,CAInB;IAED;;;;;;;OAOG;IACH,cALW,UAAU,UACV,MAAM,UACN,MAAM,GACJ,MAAM,CAUlB;IAED;;;;;;;OAOG;IACH,iBAHW,MAAM,OACN,YAAY,QAatB;IAED;;;;OAIG;IACH,kBAHW,MAAM,UACN,MAAM,QAQhB;IAED;;;;;;OAMG;IACH,iBALW,MAAM,UACN,MAAM,OACN,UAAU,cACV,MAAM,QAKhB;IAED;;;;OAIG;IACH,iBAHW,MAAM,UACN,MAAM,QAahB;IAED;;;;;;OAMG;IACH,gBAJW,MAAM,UACN,MAAM,GACJ,OAAO,CAgBnB;IAED;;OAEG;IACH,cAIC;;CA8BJ"}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { bytes_copy } from "./bytes_copy.js";
|
|
2
|
+
import { RangeSet } from "./RangeSet.js";
|
|
3
|
+
import { varint_size, varint_write } from "./varint.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Send half of one reliable lane: an ordered byte stream of `[varint length][bytes]` messages.
|
|
7
|
+
*
|
|
8
|
+
* A message is copied once, into {@link #buffer}, when it is queued. What goes on the wire is byte
|
|
9
|
+
* ranges of the stream, and what a lost packet costs is the ranges it carried: they are queued for
|
|
10
|
+
* re-sending, minus anything acknowledged since. Bytes are released once every byte before them is
|
|
11
|
+
* acknowledged.
|
|
12
|
+
*
|
|
13
|
+
* Flow control needs no frames. The sender never sends a byte at or past `acked_prefix + window`.
|
|
14
|
+
* The receiver delivers each message the moment its bytes are contiguous and its contiguous point is
|
|
15
|
+
* never behind the sender's acked prefix, so what the receiver must hold out of order is bounded by
|
|
16
|
+
* the window, and what it holds in order is bounded by the largest message.
|
|
17
|
+
*
|
|
18
|
+
* @author Alex Goldring
|
|
19
|
+
* @copyright Company Named Limited (c) 2026
|
|
20
|
+
*/
|
|
21
|
+
export class TxStream {
|
|
22
|
+
/**
|
|
23
|
+
* Stream bytes from {@link #base} on. Grows to a high-watermark.
|
|
24
|
+
* @type {Uint8Array}
|
|
25
|
+
*/
|
|
26
|
+
#buffer;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Stream offset of `#buffer[0]`.
|
|
30
|
+
* @type {number}
|
|
31
|
+
*/
|
|
32
|
+
#base = 0;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Stream offset one past the last byte queued.
|
|
36
|
+
* @type {number}
|
|
37
|
+
*/
|
|
38
|
+
#end = 0;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* First offset never sent.
|
|
42
|
+
* @type {number}
|
|
43
|
+
*/
|
|
44
|
+
#next_new = 0;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Every byte below this is acknowledged.
|
|
48
|
+
* @type {number}
|
|
49
|
+
*/
|
|
50
|
+
#acked_prefix = 0;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Acknowledged ranges at or above {@link #acked_prefix}.
|
|
54
|
+
* @type {RangeSet}
|
|
55
|
+
*/
|
|
56
|
+
#acked = new RangeSet();
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Ranges carried by packets declared lost, still unacknowledged, to be sent again before any
|
|
60
|
+
* new byte.
|
|
61
|
+
* @type {RangeSet}
|
|
62
|
+
*/
|
|
63
|
+
#retransmit = new RangeSet();
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @param {number} window bytes the sender may have past its acked prefix
|
|
67
|
+
*/
|
|
68
|
+
constructor(window) {
|
|
69
|
+
/** @type {number} @readonly */
|
|
70
|
+
this.window = window;
|
|
71
|
+
this.#buffer = new Uint8Array(1024);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Stream offset one past the last byte queued. */
|
|
75
|
+
get end() {
|
|
76
|
+
return this.#end;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Every byte below this is acknowledged. */
|
|
80
|
+
get acked_prefix() {
|
|
81
|
+
return this.#acked_prefix;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Whether anything is waiting to go out: a re-send, or new bytes the window lets through.
|
|
86
|
+
* @returns {boolean}
|
|
87
|
+
*/
|
|
88
|
+
has_sendable() {
|
|
89
|
+
if (!this.#retransmit.is_empty()) return true;
|
|
90
|
+
return this.#next_new < this.#end && this.#next_new < this.#acked_prefix + this.window;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Whether bytes are queued that the receiver has not acknowledged.
|
|
95
|
+
* @returns {boolean}
|
|
96
|
+
*/
|
|
97
|
+
has_unacked() {
|
|
98
|
+
return this.#acked_prefix < this.#end;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Queue one message.
|
|
103
|
+
*
|
|
104
|
+
* @param {Uint8Array} bytes
|
|
105
|
+
* @param {number} offset
|
|
106
|
+
* @param {number} length
|
|
107
|
+
* @returns {number} stream offset one past the message: delivered once the acked prefix reaches it
|
|
108
|
+
*/
|
|
109
|
+
append(bytes, offset, length) {
|
|
110
|
+
const header = varint_size(length);
|
|
111
|
+
this.#reserve(header + length);
|
|
112
|
+
let at = this.#end - this.#base;
|
|
113
|
+
at = varint_write(this.#buffer, at, length);
|
|
114
|
+
bytes_copy(bytes, offset, this.#buffer, at, length);
|
|
115
|
+
this.#end += header + length;
|
|
116
|
+
return this.#end;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Pick the next range to send, at most `max_length` bytes: the lowest pending re-send first,
|
|
121
|
+
* then new bytes up to the window. Writes `[offset, length]` into `out`; length 0 means nothing
|
|
122
|
+
* to send. The range is not marked sent until {@link mark_sent}.
|
|
123
|
+
*
|
|
124
|
+
* @param {number} max_length
|
|
125
|
+
* @param {Float64Array} out
|
|
126
|
+
*/
|
|
127
|
+
peek(max_length, out) {
|
|
128
|
+
if (!this.#retransmit.is_empty()) {
|
|
129
|
+
const s = this.#retransmit.start(0);
|
|
130
|
+
const e = this.#retransmit.end(0);
|
|
131
|
+
out[0] = s;
|
|
132
|
+
out[1] = Math.min(e - s, max_length);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const limit = Math.min(this.#end, this.#acked_prefix + this.window);
|
|
136
|
+
out[0] = this.#next_new;
|
|
137
|
+
out[1] = Math.max(0, Math.min(limit - this.#next_new, max_length));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* The range {@link peek} returned has gone out.
|
|
142
|
+
* @param {number} offset
|
|
143
|
+
* @param {number} length
|
|
144
|
+
*/
|
|
145
|
+
mark_sent(offset, length) {
|
|
146
|
+
if (offset < this.#next_new) {
|
|
147
|
+
this.#retransmit.remove(offset, offset + length);
|
|
148
|
+
} else {
|
|
149
|
+
this.#next_new = offset + length;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Copy stream bytes `[offset, offset + length)` into `out` at `out_offset`.
|
|
155
|
+
* @param {number} offset
|
|
156
|
+
* @param {number} length
|
|
157
|
+
* @param {Uint8Array} out
|
|
158
|
+
* @param {number} out_offset
|
|
159
|
+
*/
|
|
160
|
+
copy_out(offset, length, out, out_offset) {
|
|
161
|
+
const from = offset - this.#base;
|
|
162
|
+
bytes_copy(this.#buffer, from, out, out_offset, length);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* A packet carrying `[offset, offset + length)` was acknowledged.
|
|
167
|
+
* @param {number} offset
|
|
168
|
+
* @param {number} length
|
|
169
|
+
*/
|
|
170
|
+
on_acked(offset, length) {
|
|
171
|
+
const end = offset + length;
|
|
172
|
+
if (end <= this.#acked_prefix) return;
|
|
173
|
+
this.#retransmit.remove(offset, end);
|
|
174
|
+
this.#acked.add(Math.max(offset, this.#acked_prefix), end);
|
|
175
|
+
if (this.#acked.min() <= this.#acked_prefix) {
|
|
176
|
+
this.#acked_prefix = this.#acked.run_end(this.#acked.min());
|
|
177
|
+
this.#acked.remove_below(this.#acked_prefix);
|
|
178
|
+
// bytes are moved out of the way only when room is needed (#reserve): releasing on
|
|
179
|
+
// every ack would slide a large message's tail down once per packet
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* A packet carrying `[offset, offset + length)` was declared lost, or is being probed: send what
|
|
185
|
+
* of it is still unacknowledged again.
|
|
186
|
+
* @param {number} offset
|
|
187
|
+
* @param {number} length
|
|
188
|
+
* @returns {boolean} whether any of it is still unacknowledged, and so queued to go again
|
|
189
|
+
*/
|
|
190
|
+
on_lost(offset, length) {
|
|
191
|
+
let start = Math.max(offset, this.#acked_prefix);
|
|
192
|
+
const end = offset + length;
|
|
193
|
+
if (end <= start) return false;
|
|
194
|
+
this.#retransmit.add(start, end);
|
|
195
|
+
// take back out whatever has been acknowledged meanwhile
|
|
196
|
+
const acked = this.#acked;
|
|
197
|
+
for (let i = 0; i < acked.count; i++) {
|
|
198
|
+
const s = acked.start(i);
|
|
199
|
+
if (s >= end) break;
|
|
200
|
+
const e = acked.end(i);
|
|
201
|
+
if (e > start) this.#retransmit.remove(s, e);
|
|
202
|
+
}
|
|
203
|
+
return !this.#acked.contains_range(start, end);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Forget everything: the connection is gone.
|
|
208
|
+
*/
|
|
209
|
+
clear() {
|
|
210
|
+
this.#base = this.#end = this.#next_new = this.#acked_prefix = 0;
|
|
211
|
+
this.#acked.clear();
|
|
212
|
+
this.#retransmit.clear();
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Make room for `extra` more bytes, first by dropping acknowledged bytes from the front, then
|
|
217
|
+
* by growing.
|
|
218
|
+
* @param {number} extra
|
|
219
|
+
*/
|
|
220
|
+
#reserve(extra) {
|
|
221
|
+
const used = this.#end - this.#base;
|
|
222
|
+
if (used + extra <= this.#buffer.length) return;
|
|
223
|
+
this.#release();
|
|
224
|
+
const kept = this.#end - this.#base;
|
|
225
|
+
if (kept + extra <= this.#buffer.length) return;
|
|
226
|
+
let size = this.#buffer.length * 2;
|
|
227
|
+
while (size < kept + extra) size *= 2;
|
|
228
|
+
const next = new Uint8Array(size);
|
|
229
|
+
next.set(this.#buffer.subarray(0, kept));
|
|
230
|
+
this.#buffer = next;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Drop the acknowledged prefix from the front of the buffer.
|
|
235
|
+
*/
|
|
236
|
+
#release() {
|
|
237
|
+
const drop = this.#acked_prefix - this.#base;
|
|
238
|
+
if (drop <= 0) return;
|
|
239
|
+
const kept = this.#end - this.#acked_prefix;
|
|
240
|
+
if (kept > 0) this.#buffer.copyWithin(0, drop, drop + kept);
|
|
241
|
+
this.#base = this.#acked_prefix;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copy `length` bytes from `source[source_offset..]` to `target[target_offset..]`.
|
|
3
|
+
*
|
|
4
|
+
* `target.set(source.subarray(a, b), at)` allocates a view on every call; on the packet path —
|
|
5
|
+
* every message in, every message out, every segment — that was nearly all of the connection
|
|
6
|
+
* layer's allocation. The small copies, which are most of them, allocate nothing here.
|
|
7
|
+
*
|
|
8
|
+
* The ranges may not overlap.
|
|
9
|
+
*
|
|
10
|
+
* @param {Uint8Array} source
|
|
11
|
+
* @param {number} source_offset
|
|
12
|
+
* @param {Uint8Array} target
|
|
13
|
+
* @param {number} target_offset
|
|
14
|
+
* @param {number} length
|
|
15
|
+
*/
|
|
16
|
+
export function bytes_copy(source: Uint8Array, source_offset: number, target: Uint8Array, target_offset: number, length: number): void;
|
|
17
|
+
//# sourceMappingURL=bytes_copy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bytes_copy.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/network/transport/connection/bytes_copy.js"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;GAcG;AACH,mCANW,UAAU,iBACV,MAAM,UACN,UAAU,iBACV,MAAM,UACN,MAAM,QAUhB"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Up to this many bytes a plain loop copies; past it, `set` over a `subarray` view does.
|
|
3
|
+
*
|
|
4
|
+
* Measured on Node 22 (one copy, warmed up): the loop costs about 1.2 ns a byte, `set` over a view
|
|
5
|
+
* 50–70 ns whatever the size — 42 against 51 ns at 20 bytes, 127 against 53 at 100, 1,390 against
|
|
6
|
+
* 69 at 1,100. Below this a loop is as fast and allocates nothing; above it the view's one small,
|
|
7
|
+
* short-lived allocation buys a memcpy.
|
|
8
|
+
*/
|
|
9
|
+
const LOOP_LIMIT = 64;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Copy `length` bytes from `source[source_offset..]` to `target[target_offset..]`.
|
|
13
|
+
*
|
|
14
|
+
* `target.set(source.subarray(a, b), at)` allocates a view on every call; on the packet path —
|
|
15
|
+
* every message in, every message out, every segment — that was nearly all of the connection
|
|
16
|
+
* layer's allocation. The small copies, which are most of them, allocate nothing here.
|
|
17
|
+
*
|
|
18
|
+
* The ranges may not overlap.
|
|
19
|
+
*
|
|
20
|
+
* @param {Uint8Array} source
|
|
21
|
+
* @param {number} source_offset
|
|
22
|
+
* @param {Uint8Array} target
|
|
23
|
+
* @param {number} target_offset
|
|
24
|
+
* @param {number} length
|
|
25
|
+
*/
|
|
26
|
+
export function bytes_copy(source, source_offset, target, target_offset, length) {
|
|
27
|
+
if (length > LOOP_LIMIT) {
|
|
28
|
+
target.set(source.subarray(source_offset, source_offset + length), target_offset);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
for (let i = 0; i < length; i++) {
|
|
32
|
+
target[target_offset + i] = source[source_offset + i];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bytes `value` takes.
|
|
3
|
+
* @param {number} value non-negative integer ≤ {@link VARINT_MAX}
|
|
4
|
+
* @returns {number} 1, 2, 4 or 8
|
|
5
|
+
*/
|
|
6
|
+
export function varint_size(value: number): number;
|
|
7
|
+
/**
|
|
8
|
+
* Write `value` at `offset`. The caller has checked room: {@link varint_size} bytes.
|
|
9
|
+
*
|
|
10
|
+
* @param {Uint8Array} bytes
|
|
11
|
+
* @param {number} offset
|
|
12
|
+
* @param {number} value non-negative integer ≤ {@link VARINT_MAX}
|
|
13
|
+
* @returns {number} offset past the written bytes
|
|
14
|
+
*/
|
|
15
|
+
export function varint_write(bytes: Uint8Array, offset: number, value: number): number;
|
|
16
|
+
/**
|
|
17
|
+
* Read a varint at `cursor.position`, advancing it. Returns -1 when the bytes run out before
|
|
18
|
+
* `end` or the value is past {@link VARINT_MAX}: a truncated or hostile frame, which the caller
|
|
19
|
+
* drops.
|
|
20
|
+
*
|
|
21
|
+
* @param {Uint8Array} bytes
|
|
22
|
+
* @param {{position: number}} cursor
|
|
23
|
+
* @param {number} end exclusive bound of readable bytes
|
|
24
|
+
* @returns {number}
|
|
25
|
+
*/
|
|
26
|
+
export function varint_read(bytes: Uint8Array, cursor: {
|
|
27
|
+
position: number;
|
|
28
|
+
}, end: number): number;
|
|
29
|
+
/**
|
|
30
|
+
* Variable-length unsigned integers in the QUIC encoding (RFC 9000 §16): the top two bits of the
|
|
31
|
+
* first byte give the length — 1, 2, 4 or 8 bytes — and the rest is the value, big-endian.
|
|
32
|
+
*
|
|
33
|
+
* 0 .. 63 1 byte
|
|
34
|
+
* 64 .. 16,383 2 bytes
|
|
35
|
+
* .. 2^30 - 1 4 bytes
|
|
36
|
+
* .. 2^53 - 1 8 bytes (2^62 - 1 on the wire; JavaScript numbers stop at 2^53)
|
|
37
|
+
*
|
|
38
|
+
* Chosen over LEB128 because the length is known before a byte is written, so a packet builder can
|
|
39
|
+
* check room for a frame header without trial-encoding it.
|
|
40
|
+
*
|
|
41
|
+
* @author Alex Goldring
|
|
42
|
+
* @copyright Company Named Limited (c) 2026
|
|
43
|
+
*/
|
|
44
|
+
/** Largest value {@link varint_write} encodes. */
|
|
45
|
+
export const VARINT_MAX: number;
|
|
46
|
+
//# sourceMappingURL=varint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"varint.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/network/transport/connection/varint.js"],"names":[],"mappings":"AAqBA;;;;GAIG;AACH,mCAHW,MAAM,GACJ,MAAM,CAOlB;AAED;;;;;;;GAOG;AACH,oCALW,UAAU,UACV,MAAM,SACN,MAAM,GACJ,MAAM,CA8BlB;AAED;;;;;;;;;GASG;AACH,mCALW,UAAU,UACV;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAC,OAClB,MAAM,GACJ,MAAM,CA2BlB;AA1GD;;;;;;;;;;;;;;GAcG;AAEH,kDAAkD;AAClD,gCAAkD"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Variable-length unsigned integers in the QUIC encoding (RFC 9000 §16): the top two bits of the
|
|
3
|
+
* first byte give the length — 1, 2, 4 or 8 bytes — and the rest is the value, big-endian.
|
|
4
|
+
*
|
|
5
|
+
* 0 .. 63 1 byte
|
|
6
|
+
* 64 .. 16,383 2 bytes
|
|
7
|
+
* .. 2^30 - 1 4 bytes
|
|
8
|
+
* .. 2^53 - 1 8 bytes (2^62 - 1 on the wire; JavaScript numbers stop at 2^53)
|
|
9
|
+
*
|
|
10
|
+
* Chosen over LEB128 because the length is known before a byte is written, so a packet builder can
|
|
11
|
+
* check room for a frame header without trial-encoding it.
|
|
12
|
+
*
|
|
13
|
+
* @author Alex Goldring
|
|
14
|
+
* @copyright Company Named Limited (c) 2026
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/** Largest value {@link varint_write} encodes. */
|
|
18
|
+
export const VARINT_MAX = Number.MAX_SAFE_INTEGER;
|
|
19
|
+
|
|
20
|
+
const TWO_POW_32 = 4294967296;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Bytes `value` takes.
|
|
24
|
+
* @param {number} value non-negative integer ≤ {@link VARINT_MAX}
|
|
25
|
+
* @returns {number} 1, 2, 4 or 8
|
|
26
|
+
*/
|
|
27
|
+
export function varint_size(value) {
|
|
28
|
+
if (value < 64) return 1;
|
|
29
|
+
if (value < 16384) return 2;
|
|
30
|
+
if (value < 1073741824) return 4;
|
|
31
|
+
return 8;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Write `value` at `offset`. The caller has checked room: {@link varint_size} bytes.
|
|
36
|
+
*
|
|
37
|
+
* @param {Uint8Array} bytes
|
|
38
|
+
* @param {number} offset
|
|
39
|
+
* @param {number} value non-negative integer ≤ {@link VARINT_MAX}
|
|
40
|
+
* @returns {number} offset past the written bytes
|
|
41
|
+
*/
|
|
42
|
+
export function varint_write(bytes, offset, value) {
|
|
43
|
+
if (value < 64) {
|
|
44
|
+
bytes[offset] = value;
|
|
45
|
+
return offset + 1;
|
|
46
|
+
}
|
|
47
|
+
if (value < 16384) {
|
|
48
|
+
bytes[offset] = 0x40 | (value >>> 8);
|
|
49
|
+
bytes[offset + 1] = value & 0xFF;
|
|
50
|
+
return offset + 2;
|
|
51
|
+
}
|
|
52
|
+
if (value < 1073741824) {
|
|
53
|
+
bytes[offset] = 0x80 | (value >>> 24);
|
|
54
|
+
bytes[offset + 1] = (value >>> 16) & 0xFF;
|
|
55
|
+
bytes[offset + 2] = (value >>> 8) & 0xFF;
|
|
56
|
+
bytes[offset + 3] = value & 0xFF;
|
|
57
|
+
return offset + 4;
|
|
58
|
+
}
|
|
59
|
+
const hi = Math.floor(value / TWO_POW_32);
|
|
60
|
+
const lo = value - hi * TWO_POW_32;
|
|
61
|
+
bytes[offset] = 0xC0 | (hi >>> 24);
|
|
62
|
+
bytes[offset + 1] = (hi >>> 16) & 0xFF;
|
|
63
|
+
bytes[offset + 2] = (hi >>> 8) & 0xFF;
|
|
64
|
+
bytes[offset + 3] = hi & 0xFF;
|
|
65
|
+
bytes[offset + 4] = lo >>> 24;
|
|
66
|
+
bytes[offset + 5] = (lo >>> 16) & 0xFF;
|
|
67
|
+
bytes[offset + 6] = (lo >>> 8) & 0xFF;
|
|
68
|
+
bytes[offset + 7] = lo & 0xFF;
|
|
69
|
+
return offset + 8;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Read a varint at `cursor.position`, advancing it. Returns -1 when the bytes run out before
|
|
74
|
+
* `end` or the value is past {@link VARINT_MAX}: a truncated or hostile frame, which the caller
|
|
75
|
+
* drops.
|
|
76
|
+
*
|
|
77
|
+
* @param {Uint8Array} bytes
|
|
78
|
+
* @param {{position: number}} cursor
|
|
79
|
+
* @param {number} end exclusive bound of readable bytes
|
|
80
|
+
* @returns {number}
|
|
81
|
+
*/
|
|
82
|
+
export function varint_read(bytes, cursor, end) {
|
|
83
|
+
const p = cursor.position;
|
|
84
|
+
if (p >= end) return -1;
|
|
85
|
+
const first = bytes[p];
|
|
86
|
+
const kind = first >>> 6;
|
|
87
|
+
if (kind === 0) {
|
|
88
|
+
cursor.position = p + 1;
|
|
89
|
+
return first;
|
|
90
|
+
}
|
|
91
|
+
if (kind === 1) {
|
|
92
|
+
if (p + 2 > end) return -1;
|
|
93
|
+
cursor.position = p + 2;
|
|
94
|
+
return ((first & 0x3F) << 8) | bytes[p + 1];
|
|
95
|
+
}
|
|
96
|
+
if (kind === 2) {
|
|
97
|
+
if (p + 4 > end) return -1;
|
|
98
|
+
cursor.position = p + 4;
|
|
99
|
+
return ((first & 0x3F) * 16777216) + (bytes[p + 1] << 16) + (bytes[p + 2] << 8) + bytes[p + 3];
|
|
100
|
+
}
|
|
101
|
+
if (p + 8 > end) return -1;
|
|
102
|
+
const hi = ((first & 0x3F) * 16777216) + (bytes[p + 1] << 16) + (bytes[p + 2] << 8) + bytes[p + 3];
|
|
103
|
+
if (hi > 0x1FFFFF) return -1; // past 2^53
|
|
104
|
+
const lo = (bytes[p + 4] * 16777216) + (bytes[p + 5] << 16) + (bytes[p + 6] << 8) + bytes[p + 7];
|
|
105
|
+
cursor.position = p + 8;
|
|
106
|
+
return hi * TWO_POW_32 + lo;
|
|
107
|
+
}
|
|
@@ -66,11 +66,11 @@ export class FluidObstacleSystem extends System<any> {
|
|
|
66
66
|
/**
|
|
67
67
|
* @param {FluidComponent} fluid
|
|
68
68
|
*/
|
|
69
|
-
static "__#
|
|
69
|
+
static "__#440@#refresh_masks"(fluid: FluidComponent): void;
|
|
70
70
|
/**
|
|
71
71
|
* @param {FluidComponent} fluid
|
|
72
72
|
*/
|
|
73
|
-
static "__#
|
|
73
|
+
static "__#440@#clear_field"(fluid: FluidComponent): void;
|
|
74
74
|
/**
|
|
75
75
|
* Mark every cell of `fluid` whose centre lies within `inflation` of the
|
|
76
76
|
* posed shape as solid. Iteration is clipped to the shape's world AABB
|
|
@@ -82,7 +82,7 @@ export class FluidObstacleSystem extends System<any> {
|
|
|
82
82
|
* @param {number} inflation world-units SDF threshold
|
|
83
83
|
* @param {Float64Array} point length-3 scratch
|
|
84
84
|
*/
|
|
85
|
-
static "__#
|
|
85
|
+
static "__#440@#voxelize"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array): void;
|
|
86
86
|
/**
|
|
87
87
|
* Write the obstacle's translation velocity onto every face of every cell
|
|
88
88
|
* it voxelized — the moving-wall boundary condition. Runs AFTER the mask
|
|
@@ -102,7 +102,7 @@ export class FluidObstacleSystem extends System<any> {
|
|
|
102
102
|
* @param {number} wvy
|
|
103
103
|
* @param {number} wvz
|
|
104
104
|
*/
|
|
105
|
-
static "__#
|
|
105
|
+
static "__#440@#stamp_wall_velocity"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array, wvx: number, wvy: number, wvz: number): void;
|
|
106
106
|
constructor();
|
|
107
107
|
dependencies: (typeof FluidObstacle)[];
|
|
108
108
|
components_used: (ResourceAccessSpecification<typeof Transform64> | ResourceAccessSpecification<typeof RigidBody> | ResourceAccessSpecification<typeof Collider> | ResourceAccessSpecification<typeof FluidComponent> | ResourceAccessSpecification<typeof FluidObstacle>)[];
|
|
@@ -16,13 +16,14 @@ export class AudioEmitter {
|
|
|
16
16
|
/**
|
|
17
17
|
* The authored event this emitter plays.
|
|
18
18
|
*
|
|
19
|
-
* Authored data: fixed for as long as the emitter is playing. Routing (`busId`,
|
|
20
|
-
* `panningModel`) decides the shape of the instance's audio graph, which is built once when
|
|
21
|
-
* voice starts; and `distanceMin`, `distanceMax`, `maxInstances
|
|
22
|
-
* part in {@link EventDescription.hash}, which
|
|
23
|
-
* editing any of them in place on a sounding emitter
|
|
24
|
-
* longer be found by. Change them by re-linking the
|
|
25
|
-
* the voice down and re-reads the description cleanly.
|
|
19
|
+
* Authored data: fixed for as long as the emitter is linked, playing or dormant. Routing (`busId`,
|
|
20
|
+
* `is3D`, `panningModel`) decides the shape of the instance's audio graph, which is built once when
|
|
21
|
+
* the voice starts; and `distanceMin`, `distanceMax`, `maxInstances`, the attenuation curve and the
|
|
22
|
+
* insert `effects` (every field of every effect) all take part in {@link EventDescription.hash}, which
|
|
23
|
+
* the `VoiceManager` buckets live instances by — so editing any of them in place on a sounding emitter
|
|
24
|
+
* files that instance under a hash it can no longer be found by. Change them by re-linking the
|
|
25
|
+
* component (remove and re-add it), which tears the voice down and re-reads the description cleanly.
|
|
26
|
+
* A playing effect's parameters move through {@link effectOverrides}, never through the definition.
|
|
26
27
|
*
|
|
27
28
|
* @type {EventDescription}
|
|
28
29
|
*/
|
|
@@ -59,6 +60,31 @@ export class AudioEmitter {
|
|
|
59
60
|
* @type {AcousticDirectivity}
|
|
60
61
|
*/
|
|
61
62
|
directivity: AcousticDirectivity;
|
|
63
|
+
/**
|
|
64
|
+
* This emitter's own values for its event's insert-effect parameters ({@link EventDescription.effects}):
|
|
65
|
+
* a lowpass closing over one torch as a door shuts on it, while every other torch playing the same
|
|
66
|
+
* event stays bright.
|
|
67
|
+
*
|
|
68
|
+
* Live state, the way {@link volume} is live — plumbed by `AudioEmitterSystem` onto whichever instance
|
|
69
|
+
* is current, and put onto every new one. A spatially managed emitter's instance is torn down when it
|
|
70
|
+
* is demoted and built afresh when it is promoted again, and is built at these values, not the event's;
|
|
71
|
+
* a value moved straight on an instance (`AudioEmitterSystem.instanceFor(entity).setEffectParam`) lasts
|
|
72
|
+
* only as long as that instance.
|
|
73
|
+
*
|
|
74
|
+
* Not authored data, so absent from {@link toJSON}, {@link equals} and {@link hash}: two emitters that
|
|
75
|
+
* differ only in where a filter has been turned are the same emitter, and the overrides must change
|
|
76
|
+
* neither what a save contains nor which polyphony bucket a voice is filed under.
|
|
77
|
+
*
|
|
78
|
+
* Checked against the event: while the emitter is linked, an override its event has no such parameter
|
|
79
|
+
* for throws where it is written, and is not kept; one written before the link is checked by the link,
|
|
80
|
+
* which throws instead of playing. So {@link EffectParamOverrides#clear} them before re-adding the
|
|
81
|
+
* component with a different event. One entity per `AudioEmitter`: a second link of the same component
|
|
82
|
+
* throws, since the overrides can follow only one playing instance.
|
|
83
|
+
*
|
|
84
|
+
* @readonly
|
|
85
|
+
* @type {EffectParamOverrides}
|
|
86
|
+
*/
|
|
87
|
+
readonly effectOverrides: EffectParamOverrides;
|
|
62
88
|
/**
|
|
63
89
|
* Observation surface, not authored state — deliberately absent from {@link toJSON}, {@link equals}
|
|
64
90
|
* and {@link hash}: two emitters that differ only in who is listening are the same emitter, and a
|
|
@@ -104,6 +130,10 @@ export class AudioEmitter {
|
|
|
104
130
|
priority: number;
|
|
105
131
|
stealMode: number;
|
|
106
132
|
virtualThresholdDb: number;
|
|
133
|
+
effects: {
|
|
134
|
+
type: string;
|
|
135
|
+
data: any;
|
|
136
|
+
}[];
|
|
107
137
|
};
|
|
108
138
|
volume: number;
|
|
109
139
|
autoplay: boolean;
|
|
@@ -122,5 +152,6 @@ export namespace AudioEmitter {
|
|
|
122
152
|
import { EventDescription } from "../../sopra/definition/EventDescription.js";
|
|
123
153
|
import Vector1 from "../../../../core/geom/Vector1.js";
|
|
124
154
|
import { AcousticDirectivity } from "../../simulation/definition/AcousticDirectivity.js";
|
|
155
|
+
import { EffectParamOverrides } from "../../sopra/runtime/EffectParamOverrides.js";
|
|
125
156
|
import Signal from "../../../../core/events/signal/Signal.js";
|
|
126
157
|
//# sourceMappingURL=AudioEmitter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AudioEmitter.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/sound/ecs/audio/AudioEmitter.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AudioEmitter.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/sound/ecs/audio/AudioEmitter.js"],"names":[],"mappings":"AAWA;;;;;;;;GAQG;AACH;IA2JI;;;OAGG;IACH,4BAFa,YAAY,CAMxB;IAjKD;;;;;;;;;;;;;OAaG;IACH,OAFU,gBAAgB,CAEK;IAE/B;;;OAGG;IACH,QAFU,OAAO,CAEO;IAExB;;;;OAIG;IACH,UAFU,OAAO,CAED;IAEhB;;;;;OAKG;IACH,UAFU,OAAO,CAEA;IAEjB;;;;;OAKG;IACH,cAFU,MAAM,CAEqB;IAErC;;;;;OAKG;IACH,aAFU,mBAAmB,CAEW;IAExC;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,0BAFU,oBAAoB,CAEe;IAE7C;;;;;;;;;;;;;;;OAeG;IACH,aAFU;QAAC,KAAK,EAAE,OAAO,YAAY,CAAC,CAAA;KAAC,CAIrC;IAEF;;;OAGG;IACH,cAHW,YAAY,GACV,OAAO,CASnB;IAED,eAaC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MASC;IAED,0BAaC;CAWJ;;;;iCAlLgC,4CAA4C;oBAHzD,kCAAkC;oCAElB,oDAAoD;qCAEnD,6CAA6C;mBAL/D,0CAA0C"}
|