aboutsummaryrefslogtreecommitdiffstats
path: root/src/user/ThreeVideo.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/user/ThreeVideo.ts')
-rw-r--r--src/user/ThreeVideo.ts60
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 {