Skip to content

Commit f775b53

Browse files
Chau TranChau Tran
Chau Tran
authored and
Chau Tran
committed
feat(core): add timing in injection context functions
1 parent 4840344 commit f775b53

File tree

9 files changed

+176
-153
lines changed

9 files changed

+176
-153
lines changed

libs/angular-three/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ export * from './lib/utils/is';
2121
export * from './lib/utils/make';
2222
export * from './lib/utils/safe-detect-changes';
2323
export * from './lib/utils/signal';
24+
export * from './lib/utils/timing';
2425
export * from './lib/utils/update';

libs/angular-three/src/lib/loader.ts

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import type {
2121
import { assertInjectionContext } from './utils/assert-in-injection-context';
2222
import { makeObjectGraph } from './utils/make';
2323
import { safeDetectChanges } from './utils/safe-detect-changes';
24+
import { requestAnimationInInjectionContext } from './utils/timing';
2425

2526
export type NgtLoaderResults<
2627
TInput extends string | string[] | Record<string, string>,
@@ -107,29 +108,26 @@ export function injectNgtLoader<
107108
const response = signal<NgtLoaderResults<TUrl, NgtBranchingReturn<TReturn, GLTF, GLTF & NgtObjectMap>>>(null!);
108109
const effector = load(loaderConstructorFactory, inputs, { extensions, onProgress });
109110

110-
requestAnimationFrame(() => {
111-
effect(
112-
() => {
113-
const originalUrls = untracked(inputs);
114-
Promise.all(effector())
115-
.then((results) => {
116-
if (Array.isArray(originalUrls)) return results;
117-
if (typeof originalUrls === 'string') return results[0];
118-
const keys = Object.keys(originalUrls);
119-
return keys.reduce((result, key) => {
120-
(result as NgtAnyRecord)[key] = results[keys.indexOf(key)];
121-
return result;
122-
}, {} as { [key in keyof TUrl]: NgtBranchingReturn<TReturn, GLTF, GLTF & NgtObjectMap> });
123-
})
124-
.then((value) => {
125-
response.set(
126-
value as NgtLoaderResults<TUrl, NgtBranchingReturn<TReturn, GLTF, GLTF & NgtObjectMap>>
127-
);
128-
safeDetectChanges(cdr);
129-
});
130-
},
131-
{ injector }
132-
);
111+
requestAnimationInInjectionContext(() => {
112+
effect(() => {
113+
const originalUrls = untracked(inputs);
114+
Promise.all(effector())
115+
.then((results) => {
116+
if (Array.isArray(originalUrls)) return results;
117+
if (typeof originalUrls === 'string') return results[0];
118+
const keys = Object.keys(originalUrls);
119+
return keys.reduce((result, key) => {
120+
(result as NgtAnyRecord)[key] = results[keys.indexOf(key)];
121+
return result;
122+
}, {} as { [key in keyof TUrl]: NgtBranchingReturn<TReturn, GLTF, GLTF & NgtObjectMap> });
123+
})
124+
.then((value) => {
125+
response.set(
126+
value as NgtLoaderResults<TUrl, NgtBranchingReturn<TReturn, GLTF, GLTF & NgtObjectMap>>
127+
);
128+
safeDetectChanges(cdr);
129+
});
130+
});
133131
});
134132

135133
return response.asReadonly();

libs/angular-three/src/lib/stores/signal.store.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,13 @@ export class NgtSignalStore<TState extends object> {
106106
...(typeof state === 'function' ? state(previous) : state),
107107
}));
108108
}
109+
110+
patch(state: Partial<TState>) {
111+
this.#state.update((previous) => ({
112+
...state,
113+
...previous,
114+
}));
115+
}
109116
}
110117

111118
function parseOptions(keysAndOptions: any[]): [string[], CreateComputedOptions<any>?] {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { Injector, runInInjectionContext } from '@angular/core';
2+
import { assertInjectionContext } from './assert-in-injection-context';
3+
4+
export function requestAnimationInInjectionContext(cb: () => void, injector?: Injector) {
5+
injector = assertInjectionContext(requestAnimationInInjectionContext, injector);
6+
return requestAnimationFrame(() => {
7+
return runInInjectionContext(injector!, cb);
8+
});
9+
}
10+
11+
export function queueMicrotaskInInjectionContext(cb: () => void, injector?: Injector) {
12+
injector = assertInjectionContext(requestAnimationInInjectionContext, injector);
13+
return queueMicrotask(() => {
14+
return runInInjectionContext(injector!, cb);
15+
});
16+
}
17+
18+
export function queueMacrotaskInInjectionContext(cb: () => void, injector?: Injector) {
19+
injector = assertInjectionContext(requestAnimationInInjectionContext, injector);
20+
return setTimeout(() => {
21+
return runInInjectionContext(injector!, cb);
22+
});
23+
}

libs/soba/src/staging/spot-light.stories.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ export const Default = makeStoryObject(DefaultSpotLightStory, {
179179
argsOptions: { size: number(256), debug: false, volumetric: true },
180180
});
181181

182-
// TODO: shadows doesn't seem to work due to some racing condition with map
182+
// TODO: shadow.map also needs to set size, shadow.mapSize isn't enough. investigate further?
183183
export const Shadows = makeStoryObject(ShadowsSpotLightStory, {
184184
canvasOptions: { lights: false },
185185
argsOptions: { wind: true, debug: false },

libs/soba/staging/src/center/center.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Component, computed, CUSTOM_ELEMENTS_SCHEMA, effect, EventEmitter, Input, Output } from '@angular/core';
2-
import { extend, injectNgtRef, NgtSignalStore, type NgtGroup } from 'angular-three';
2+
import { extend, injectNgtRef, NgtSignalStore, requestAnimationInInjectionContext, type NgtGroup } from 'angular-three';
33
import { Box3, Group, Sphere, Vector3 } from 'three';
44

55
export type NgtsCenterState = {
@@ -111,7 +111,9 @@ export class NgtsCenter extends NgtSignalStore<NgtsCenterState> {
111111

112112
constructor() {
113113
super({ precise: true });
114-
this.#setPosition();
114+
requestAnimationInInjectionContext(() => {
115+
this.#setPosition();
116+
});
115117
}
116118

117119
#setPosition() {

0 commit comments

Comments
 (0)