diff options
Diffstat (limited to 'src/user/ThreeVideo.ts')
-rw-r--r-- | src/user/ThreeVideo.ts | 60 |
1 files changed, 54 insertions, 6 deletions
diff --git a/src/user/ThreeVideo.ts b/src/user/ThreeVideo.ts index 92615f1..828c6c9 100644 --- a/src/user/ThreeVideo.ts +++ b/src/user/ThreeVideo.ts @@ -2,13 +2,61 @@ import { Video as BaseVideo, type FrameTime, type InitConfig } from '$/lib/Playe import * as THREE from 'three'; import type { OrbitControls } from 'three/examples/jsm/Addons.js'; -export const OnceCell = <T>(create: () => T) => { - let called = false, - cached = null as unknown as T - return () => { - if (called) return cached - else { cached = create(); called = true; return cached } +export type Proxy<T> = T +export const OnceCell = <T>(create: () => T): Proxy<T> => { + let value = null as unknown as T; + let created = false; + let createOnce = (): T extends object ? T : never => { + // @ts-ignore + if (created) return value; else return (created = true, value = create()) } + return new Proxy({ + get value() { + return createOnce() + } + }, { + get(_, ...args) { + return Reflect.get(createOnce(), ...args) + }, + set(_, ...args) { + return Reflect.set(createOnce(), ...args) + }, + has(_, ...args) { + return Reflect.has(createOnce(), ...args) + }, + deleteProperty(_, ...args) { + return Reflect.deleteProperty(createOnce(), ...args) + }, + isExtensible(_, ...args) { + return Reflect.isExtensible(createOnce(), ...args) + }, + ownKeys(_, ...args) { + return Reflect.ownKeys(createOnce(), ...args) + }, + defineProperty(_, ...args) { + return Reflect.defineProperty(createOnce(), ...args) + }, + getOwnPropertyDescriptor(_, ...args) { + return Reflect.getOwnPropertyDescriptor(createOnce(), ...args) + }, + preventExtensions(_, ...args) { + return Reflect.preventExtensions(createOnce(), ...args) + }, + getPrototypeOf(_, ...args) { + return Reflect.getPrototypeOf(createOnce(), ...args) + }, + setPrototypeOf(_, ...args) { + return Reflect.setPrototypeOf(createOnce(), ...args) + }, + apply(_, ...args) { + type F = (this: any, ...args: any[]) => any + return Reflect.apply(createOnce() as unknown as T extends F ? F : never, ...args) + }, + construct(_, ...args) { + type F = (this: any, ...args: any[]) => any + return Reflect.construct(createOnce() as unknown as T extends F ? F : never, ...args) + }, + }) as Proxy<T> } export default abstract class ThreeVideo extends BaseVideo { |