Skip to content
This repository has been archived by the owner on Feb 10, 2023. It is now read-only.

Commit

Permalink
fix(core): clean up instance
Browse files Browse the repository at this point in the history
  • Loading branch information
nartc committed Jul 24, 2022
1 parent 336b453 commit 104523f
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 49 deletions.
55 changes: 7 additions & 48 deletions libs/core/src/lib/abstracts/instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ import {
Optional,
Output,
} from '@angular/core';
import { filter, map, Observable, of, pairwise, pipe, startWith, switchMap, tap, withLatestFrom } from 'rxjs';
import { filter, map, Observable, of, pipe, switchMap, tap, withLatestFrom } from 'rxjs';
import * as THREE from 'three';
import { injectInstanceHostRef, injectInstanceRef } from '../di/instance';
import { Ref } from '../ref';
import { NgtComponentStore, startWithUndefined, tapEffect } from '../stores/component-store';
import { NgtComponentStore, tapEffect } from '../stores/component-store';
import { NgtStore } from '../stores/store';
import type { AttachFunction, BooleanInput, NgtInstanceInternal, NgtUnknownInstance, UnknownRecord } from '../types';
import { applyProps } from '../utils/apply-props';
import { checkNeedsUpdate } from '../utils/check-needs-update';
import { coerceBooleanProperty } from '../utils/coercion';
import { removeInteractivity } from '../utils/events';
import { createNgtProvider } from '../utils/inject';
import { prepare } from '../utils/instance';
import { checkUpdate, optionsFieldsToOptions, prepare } from '../utils/instance';
import { is } from '../utils/is';
import { mutate } from '../utils/mutate';

Expand Down Expand Up @@ -259,34 +259,6 @@ export abstract class NgtInstance<
return {};
}

protected optionsFieldsToOptions(fields: Record<string, boolean>, keepPrevious = false): Observable<UnknownRecord> {
const optionEntries = Object.entries(fields);
if (optionEntries.length === 0) return of({});
return this.select(
...optionEntries.map(([inputKey, shouldStartWithUndefined]) => {
const subInput$ = this.select((s) => (s as UnknownRecord)[inputKey]);
if (shouldStartWithUndefined) return subInput$.pipe(startWithUndefined());
return subInput$;
}),
(...args: any[]) =>
args.reduce((record, arg, index) => {
record[optionEntries[index][0]] = arg;
return record;
}, {} as UnknownRecord)
).pipe(
startWith({}),
pairwise(),
map(([prev, curr]) => {
return Object.entries(curr).reduce((options, [currKey, currValue]) => {
if (!is.equ(prev[currKey], currValue) || (keepPrevious && is.equ(prev[currKey], currValue))) {
options[currKey] = currValue;
}
return options;
}, {} as UnknownRecord);
})
);
}

override ngOnDestroy() {
this.zone.runOutsideAngular(() => {
this.destroy();
Expand All @@ -298,7 +270,7 @@ export abstract class NgtInstance<
tapEffect(() => {
// assigning
const setOptionsSub = this.setOptions(
this.select(this.optionsFieldsToOptions(this.optionFields), this.setOptionsTrigger$, (options) => options)
this.select(optionsFieldsToOptions(this, this.optionFields), this.setOptionsTrigger$, (options) => options)
);

// attaching
Expand Down Expand Up @@ -357,7 +329,7 @@ export abstract class NgtInstance<

this.postSetOptions(this.instanceValue);

this.checkUpdate(this.instanceValue);
checkUpdate(this.instanceValue);

if (this.update.observed) {
this.update.emit(this.instanceValue);
Expand Down Expand Up @@ -427,24 +399,11 @@ export abstract class NgtInstance<
this.__ngt__.previousAttach = propertyToAttach;
this.set({ attach: propertyToAttach } as Partial<TInstanceState>);
}
this.checkUpdate(parentInstanceRef.value);
this.checkUpdate(this.instanceValue);
checkUpdate(parentInstanceRef.value);
checkUpdate(this.instanceValue);
})
)
);

private checkUpdate(value: unknown): void {
if (is.object3d(value)) {
value.updateMatrix();
} else if (is.camera(value)) {
if (is.perspective(value) || is.orthographic(value)) {
value.updateProjectionMatrix();
}
value.updateMatrixWorld();
}

checkNeedsUpdate(value);
}
}

export const provideNgtInstance = createNgtProvider(NgtInstance);
50 changes: 50 additions & 0 deletions libs/core/src/lib/utils/instance.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { map, Observable, of, pairwise, startWith } from 'rxjs';
import { Ref } from '../ref';
import { NgtComponentStore, startWithUndefined } from '../stores/component-store';
import type { NgtInstanceInternal, NgtState, NgtUnknownInstance, UnknownRecord } from '../types';
import { applyProps } from './apply-props';
import { checkNeedsUpdate } from './check-needs-update';
import { is } from './is';

export function getInstanceInternal<T extends object = UnknownRecord>(
Expand Down Expand Up @@ -40,3 +43,50 @@ export function prepare<TInstance extends object = UnknownRecord>(
},
});
}

export function optionsFieldsToOptions(
instance: NgtComponentStore,
fields: Record<string, boolean>,
keepPrevious = false
): Observable<UnknownRecord> {
const optionEntries = Object.entries(fields);
if (optionEntries.length === 0) return of({});
return instance
.select(
...optionEntries.map(([inputKey, shouldStartWithUndefined]) => {
const subInput$ = instance.select((s) => (s as UnknownRecord)[inputKey]);
if (shouldStartWithUndefined) return subInput$.pipe(startWithUndefined());
return subInput$;
}),
(...args: any[]) =>
args.reduce((record, arg, index) => {
record[optionEntries[index][0]] = arg;
return record;
}, {} as UnknownRecord)
)
.pipe(
startWith({}),
pairwise(),
map(([prev, curr]) =>
Object.entries(curr).reduce((options, [currKey, currValue]) => {
if (!is.equ(prev[currKey], currValue) || (keepPrevious && is.equ(prev[currKey], currValue))) {
options[currKey] = currValue;
}
return options;
}, {} as UnknownRecord)
)
);
}

export function checkUpdate(value: unknown): void {
if (is.object3d(value)) {
value.updateMatrix();
} else if (is.camera(value)) {
if (is.perspective(value) || is.orthographic(value)) {
value.updateProjectionMatrix();
}
value.updateMatrixWorld();
}

checkNeedsUpdate(value);
}
3 changes: 2 additions & 1 deletion libs/postprocessing/src/lib/effect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
NgtInstance,
NgtUnknownInstance,
NumberInput,
optionsFieldsToOptions,
provideInstanceRef,
provideNgtInstance,
startWithUndefined,
Expand Down Expand Up @@ -70,7 +71,7 @@ export abstract class NgtCommonEffect<TEffect extends Effect = Effect> extends N
this.store.onReady(() => {
this.init(
this.select(
this.optionsFieldsToOptions(this.effectOptionsFields, true),
optionsFieldsToOptions(this, this.effectOptionsFields, true),
this.ctorParams$,
(effectOptions) => effectOptions
)
Expand Down

0 comments on commit 104523f

Please sign in to comment.