@3dsource/angular-unreal-module 0.0.143 → 0.0.145
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.
|
@@ -3249,6 +3249,20 @@ class WebRtcPlayerService extends SubService {
|
|
|
3249
3249
|
this.remoteDescriptionSet = false;
|
|
3250
3250
|
this.iceCandidateBuffer.length = 0;
|
|
3251
3251
|
}
|
|
3252
|
+
/**
|
|
3253
|
+
* Single source of truth for tearing down the remote connection: closes the
|
|
3254
|
+
* signaling WebSocket and then the PeerConnection/DataChannel.
|
|
3255
|
+
*
|
|
3256
|
+
* Called by the `destroyRemoteConnections$` effect and, as a
|
|
3257
|
+
* lifecycle-independent safeguard, by `UnrealSceneComponent.onDestroy` (the
|
|
3258
|
+
* route-scoped effects may already be torn down on navigation). Both close
|
|
3259
|
+
* steps are idempotent, so invoking this twice in one teardown is a harmless
|
|
3260
|
+
* no-op.
|
|
3261
|
+
*/
|
|
3262
|
+
releaseRemoteConnections(reason) {
|
|
3263
|
+
this.signallingSrv.close({ code: WSCloseCode_FORCE_CIRRUS_CLOSE, reason });
|
|
3264
|
+
this.closePC();
|
|
3265
|
+
}
|
|
3252
3266
|
canSend() {
|
|
3253
3267
|
return this.dcClient && this.dcClient.readyState === 'open';
|
|
3254
3268
|
}
|
|
@@ -3816,11 +3830,7 @@ class UnrealEffects {
|
|
|
3816
3830
|
});
|
|
3817
3831
|
this.destroyRemoteConnections$ = createEffect(() => {
|
|
3818
3832
|
return this.actions$.pipe(ofType(destroyRemoteConnections), tap(({ reason }) => {
|
|
3819
|
-
this.
|
|
3820
|
-
code: WSCloseCode_FORCE_CIRRUS_CLOSE,
|
|
3821
|
-
reason,
|
|
3822
|
-
});
|
|
3823
|
-
this.webRtcPlayerService.closePC();
|
|
3833
|
+
this.webRtcPlayerService.releaseRemoteConnections(reason);
|
|
3824
3834
|
}), filter(({ reason }) => reason === DisconnectReason.DropConnection), map(() => dropConnection()));
|
|
3825
3835
|
});
|
|
3826
3836
|
this.destroyConnectionAndRestart$ = createEffect(() => {
|
|
@@ -4732,15 +4742,6 @@ const RESIZE_DEBOUNCE_MS = 300;
|
|
|
4732
4742
|
const FUNCTION_KEY_MIN = 112;
|
|
4733
4743
|
const FUNCTION_KEY_MAX = 123;
|
|
4734
4744
|
const TAB_KEY_CODE = 9;
|
|
4735
|
-
// Browser-destructive / navigation keys (Backspace can navigate back, Enter and
|
|
4736
|
-
// Delete leak into the stream). These are ignored in the viewport regardless of
|
|
4737
|
-
// dev mode — unless an HTML input is focused — to match non-dev-mode behavior.
|
|
4738
|
-
const BROWSER_DESTRUCTIVE_CODES = new Set([
|
|
4739
|
-
'Backspace',
|
|
4740
|
-
'Delete',
|
|
4741
|
-
'Enter',
|
|
4742
|
-
'NumpadEnter',
|
|
4743
|
-
]);
|
|
4744
4745
|
class InputService extends SubService {
|
|
4745
4746
|
constructor() {
|
|
4746
4747
|
super();
|
|
@@ -5166,15 +5167,9 @@ class InputService extends SubService {
|
|
|
5166
5167
|
};
|
|
5167
5168
|
this.startListenKeys(keyBlock);
|
|
5168
5169
|
}
|
|
5169
|
-
/**
|
|
5170
|
-
* Keys that must never reach the Unreal stream from the viewport — Backspace
|
|
5171
|
-
* (browser back navigation), Enter and Delete — regardless of dev mode. An
|
|
5172
|
-
* HTML input keeps them so text entry still works; only the viewport ignores
|
|
5173
|
-
* them. Applied independently of the configurable key filter.
|
|
5174
|
-
*/
|
|
5175
5170
|
isIgnoredViewportKey(event) {
|
|
5176
5171
|
const isInputFieldFocused = event.target?.localName === 'input';
|
|
5177
|
-
return !isInputFieldFocused
|
|
5172
|
+
return !isInputFieldFocused;
|
|
5178
5173
|
}
|
|
5179
5174
|
startListenKeys(_filter) {
|
|
5180
5175
|
const filter = _filter ?? (() => false);
|
|
@@ -7186,26 +7181,19 @@ class UnrealSceneComponent {
|
|
|
7186
7181
|
this.commandsSender = inject(UnrealCommunicatorService);
|
|
7187
7182
|
this.videoService = inject(VideoService);
|
|
7188
7183
|
this.webRtcPlayerService = inject(WebRtcPlayerService);
|
|
7189
|
-
this.signallingService = inject(SignallingService);
|
|
7190
7184
|
this.destroyRef = inject(DestroyRef);
|
|
7191
7185
|
this.unrealConfig = inject(UNREAL_CONFIG);
|
|
7192
7186
|
this.autoHighResolution = false;
|
|
7193
7187
|
this.destroyRef.onDestroy(() => {
|
|
7194
|
-
//
|
|
7195
|
-
//
|
|
7196
|
-
//
|
|
7197
|
-
//
|
|
7188
|
+
// Release the remote connection synchronously, independent of the
|
|
7189
|
+
// route-scoped UnrealEffects. provideUnrealModule (effects) is registered
|
|
7190
|
+
// per 3D route, so on navigation the route's environment injector — and
|
|
7191
|
+
// its UnrealEffects — may be torn down before the
|
|
7198
7192
|
// `destroyUnrealScene → destroyRemoteConnections` effect chain closes the
|
|
7199
|
-
// WebSocket/PeerConnection, which would leak the stream session.
|
|
7200
|
-
//
|
|
7201
|
-
//
|
|
7202
|
-
|
|
7203
|
-
// harmless no-op.
|
|
7204
|
-
this.signallingService.close({
|
|
7205
|
-
code: WSCloseCode_FORCE_CIRRUS_CLOSE,
|
|
7206
|
-
reason: DisconnectReason.Destroy,
|
|
7207
|
-
});
|
|
7208
|
-
this.webRtcPlayerService.closePC();
|
|
7193
|
+
// WebSocket/PeerConnection, which would leak the stream session. We call
|
|
7194
|
+
// the same root-singleton method the effect uses, so the two can never
|
|
7195
|
+
// drift; it's idempotent, so whichever runs second is a harmless no-op.
|
|
7196
|
+
this.webRtcPlayerService.releaseRemoteConnections(DisconnectReason.Destroy);
|
|
7209
7197
|
// State cleanup is reducer-driven, not effect-driven: the
|
|
7210
7198
|
// `destroyUnrealScene` reducer resets the whole UnrealState to
|
|
7211
7199
|
// initialState (cirrusConnected/viewportReady/… → false). Reducers run in
|