Skip to content

Commit 0d756b6

Browse files
committed
feat: makeDereferencable
1 parent df4fe61 commit 0d756b6

3 files changed

Lines changed: 103 additions & 0 deletions

File tree

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { snip, type Origin } from '../data/snippet.ts';
2+
import type { BaseData } from '../data/wgslTypes.ts';
3+
import { $gpuValueOf, $internal, $ownSnippet, $resolve } from '../shared/symbols.ts';
4+
import { valueProxyHandler } from '../core/valueProxyUtils.ts';
5+
import type { SelfResolvable } from '../types.ts';
6+
import { inCodegenMode } from '../execMode.ts';
7+
8+
export function makeDereferencable<T extends SelfResolvable>(
9+
value: T,
10+
options: makeDereferencable.Options<T>,
11+
): T {
12+
Object.defineProperty(value, $gpuValueOf, {
13+
get() {
14+
const [dataType, origin] = options.getDataTypeAndOrigin.apply(this);
15+
16+
return new Proxy(
17+
{
18+
[$internal]: true,
19+
get [$ownSnippet]() {
20+
return snip(this, dataType, origin);
21+
},
22+
[$resolve]: (ctx) => ctx.resolve(this),
23+
toString: () => `${this.toString()}.$`,
24+
},
25+
valueProxyHandler,
26+
);
27+
},
28+
});
29+
30+
Object.defineProperty(value, '$', {
31+
get() {
32+
if (inCodegenMode()) {
33+
return this[$gpuValueOf];
34+
}
35+
// TODO: Add proper error message
36+
throw new Error(
37+
'Cannot read WebGL uniform outside of shader code. Use `.write()` to update it.',
38+
);
39+
},
40+
});
41+
42+
return value;
43+
}
44+
45+
export namespace makeDereferencable {
46+
export interface Options<T> {
47+
getDataTypeAndOrigin(this: T): [dataType: BaseData, origin: Origin];
48+
}
49+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { snip, type Origin, type ResolvedSnippet } from '../data/snippet.ts';
2+
import { type BaseData } from '../data/wgslTypes.ts';
3+
import { $internal, $resolve, isMarkedInternal } from '../shared/symbols.ts';
4+
import type { ResolutionCtx, SelfResolvable } from '../types.ts';
5+
6+
/**
7+
*
8+
* @param value
9+
* @param options
10+
* @returns
11+
*/
12+
export function makeResolvable<T>(
13+
value: T,
14+
options: makeResolvable.Options<T>,
15+
): T & SelfResolvable {
16+
if (!isMarkedInternal(value)) {
17+
Object.defineProperty(value, $internal, {
18+
value: true,
19+
});
20+
}
21+
22+
Object.defineProperty(value, 'toString', {
23+
value() {
24+
return options.asString.apply(this);
25+
},
26+
});
27+
28+
Object.defineProperty(value, $resolve, {
29+
value(ctx: ResolutionCtx): ResolvedSnippet {
30+
const protoSnippet = options.resolve.apply(this, [ctx]);
31+
32+
return snip(protoSnippet.value, protoSnippet.dataType, protoSnippet.origin);
33+
},
34+
});
35+
36+
return value as T & SelfResolvable;
37+
}
38+
39+
interface ProtoSnippet {
40+
value: string;
41+
dataType: BaseData;
42+
origin: Origin;
43+
}
44+
45+
export namespace makeResolvable {
46+
export interface Options<T> {
47+
resolve(this: T, ctx: ResolutionCtx): ProtoSnippet;
48+
asString(this: T): string;
49+
}
50+
51+
export type Resolvable = SelfResolvable;
52+
}

packages/typegpu/src/tgsl/shaderGenerator_members.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import type { Snippet } from '../data/snippet.ts';
66

77
export { UnknownData } from '../data/dataTypes.ts';
88
export { getName } from '../shared/meta.ts';
9+
export { makeDereferencable } from './makeDereferencable.ts';
10+
export { makeResolvable } from './makeResolvable.ts';
911

1012
// types
1113
export type { ResolutionCtx, FunctionArgument, TgpuShaderStage } from '../types.ts';

0 commit comments

Comments
 (0)