Skip to content

Commit 2a0edd6

Browse files
committed
fix(core): ensure three native events (w/ EventDispatcher) work properly
1 parent 38ad515 commit 2a0edd6

File tree

4 files changed

+35
-5
lines changed

4 files changed

+35
-5
lines changed

libs/core/src/lib/directives/selection.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@ export class NgtSelect {
3232
afterNextRender(() => {
3333
autoEffect(
3434
() => {
35+
const enabled = this.enabled();
36+
if (!enabled) return;
37+
3538
const host = elementRef.nativeElement;
3639
if (!host) return;
3740

3841
const localState = getLocalState(host);
3942
if (!localState) return;
4043

41-
const enabled = this.enabled();
42-
if (!enabled) return;
43-
4444
// ngt-mesh[ngtSelect]
4545
if (host.type === 'Mesh') {
4646
selection.update((prev) => [...prev, host]);

libs/core/src/lib/renderer/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,5 @@ export const SPECIAL_EVENTS = {
2020
UPDATED: 'updated',
2121
ATTACHED: 'attached',
2222
} as const;
23+
24+
export const THREE_NATIVE_EVENTS = ['added', 'removed', 'childadded', 'childremoved', 'disposed'];

libs/core/src/lib/renderer/utils.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { untracked } from '@angular/core';
2+
import { EventDispatcher, Object3D } from 'three';
23
import { removeInteractivity } from '../events';
34
import { getLocalState, invalidateInstance } from '../instance';
45
import { NgtInstanceNode } from '../types';
56
import { attach, detach } from '../utils/attach';
67
import { is } from '../utils/is';
7-
import { SPECIAL_EVENTS } from './constants';
8+
import { SPECIAL_EVENTS, THREE_NATIVE_EVENTS } from './constants';
89

910
// @internal
1011
export const enum NgtRendererClassId {
@@ -211,6 +212,20 @@ export function processThreeEvent(
211212
};
212213
}
213214

215+
if (THREE_NATIVE_EVENTS.includes(eventName) && instance instanceof EventDispatcher) {
216+
// NOTE: rename to dispose because that's the event type, not disposed.
217+
if (eventName === 'disposed') {
218+
eventName = 'dispose';
219+
}
220+
221+
if ((instance as Object3D).parent && (eventName === 'added' || eventName === 'removed')) {
222+
callback({ type: eventName, target: instance });
223+
}
224+
225+
instance.addEventListener(eventName, callback);
226+
return () => instance.removeEventListener(eventName, callback);
227+
}
228+
214229
if (!lS.handlers) lS.handlers = {};
215230

216231
// try to get the previous handler. compound might have one, the THREE object might also have one with the same name

libs/core/src/lib/three-types.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,10 +169,18 @@ export type NgtVector4 = NgtVectorLike<Vector4>;
169169
export type NgtLayers = Layers | Parameters<Layers['set']>[0];
170170
export type NgtQuaternion = Quaternion | Parameters<Quaternion['set']>;
171171

172+
export type ThreeDisposeEvent = { type: 'dispose'; target: NgtInstanceNode };
173+
export type ThreeAddedEvent = { type: 'added'; target: NgtInstanceNode };
174+
export type ThreeRemovedEvent = { type: 'removed'; target: NgtInstanceNode };
175+
export type ThreeChildAddedEvent = { type: 'childadded'; target: NgtInstanceNode; child: NgtInstanceNode };
176+
export type ThreeChildRemovedEvent = { type: 'childremoved'; target: NgtInstanceNode; child: NgtInstanceNode };
177+
172178
export interface NgtNodeEventMap<TOriginal> {
173179
attached: NgtAfterAttach<NgtInstanceNode, TOriginal>;
174180
updated: TOriginal;
175181
beforeRender: NgtBeforeRenderEvent<TOriginal>;
182+
// NOTE: this is named "disposed" to differentiate it from [dispose] property.
183+
disposed: ThreeDisposeEvent;
176184
}
177185

178186
export type NgtNodeElement<TOriginal, TConstructor> = {
@@ -194,6 +202,11 @@ export type NgtNode<TOriginal, TConstructor, TNoEvent = NoEvent<TOriginal>> = Ex
194202

195203
export type NgtObject3DEventsMap = {
196204
[TEvent in keyof NgtEventHandlers]-?: Parameters<NonNullable<NgtEventHandlers[TEvent]>>[0];
205+
} & {
206+
added: ThreeAddedEvent;
207+
removed: ThreeRemovedEvent;
208+
childadded: ThreeChildAddedEvent;
209+
childremoved: ThreeChildRemovedEvent;
197210
};
198211

199212
export type NgtAllObject3DEventsMap = NgtObject3DEventsMap & NgtNodeEventMap<NgtInstanceNode>;
@@ -853,5 +866,5 @@ export interface ThreeElements {
853866

854867
declare global {
855868
interface HTMLElementTagNameMap extends ThreeElements {}
856-
interface HTMLElementEventMap extends NgtNodeEventMap<NgtInstanceNode> {}
869+
interface HTMLElementEventMap extends NgtAllObject3DEventsMap {}
857870
}

0 commit comments

Comments
 (0)