Skip to content

Commit

Permalink
Fixed plum circular dependency. (#291)
Browse files Browse the repository at this point in the history
  • Loading branch information
iwoplaza authored Sep 10, 2024
1 parent 75de8e3 commit b79681b
Show file tree
Hide file tree
Showing 21 changed files with 197 additions and 104 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"@types/node": "^20.11.13",
"@vitest/coverage-v8": "0.33.0",
"@vitest/ui": "0.33.0",
"dpdm": "^3.14.0",
"husky": "^9.0.11",
"jsdom": "^24.0.0",
"prettier": "^3.2.4",
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/src/createRuntime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
type TgpuPlum,
type Unsubscribe,
isPlum,
} from './tgpuPlum';
} from './tgpuPlumTypes';
import type {
ComputePipelineExecutorOptions,
ComputePipelineOptions,
Expand Down
8 changes: 2 additions & 6 deletions packages/typegpu/src/data/struct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,10 @@ import {
object,
} from 'typed-binary';
import { RecursiveDataTypeError } from '../errors';
import type { TgpuNamable } from '../namable';
import { code } from '../tgpuCode';
import { TgpuIdentifier } from '../tgpuIdentifier';
import type {
AnyTgpuData,
ResolutionCtx,
TgpuData,
TgpuNamable,
} from '../types';
import type { AnyTgpuData, ResolutionCtx, TgpuData } from '../types';
import { TgpuAlignedImpl } from './align';
import alignIO from './alignIO';
import { TgpuSizedImpl } from './size';
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/src/experimental/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export type {
export type { TgpuCode } from '../tgpuCode';
export type { TgpuConst } from '../tgpuConstant';
export type { TgpuFn } from '../tgpuFunction';
export type { TgpuPlum } from '../tgpuPlum';
export type { TgpuPlum } from '../tgpuPlumTypes';
export type { TgpuSettable } from '../settableTrait';
export type { TgpuFn as TgpuFnExperimental } from '../tgpuFunctionExperimental';
export type { TgpuVar } from '../tgpuVariable';
Expand Down
15 changes: 15 additions & 0 deletions packages/typegpu/src/namable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* Can be assigned a name. Not to be confused with
* being able to HAVE a name.
*/
export interface TgpuNamable {
$name(label?: string | undefined): this;
}

export function isNamable(value: unknown): value is TgpuNamable {
return (
!!value &&
(typeof value === 'object' || typeof value === 'function') &&
'$name' in value
);
}
2 changes: 1 addition & 1 deletion packages/typegpu/src/plumStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
type Getter,
type TgpuPlum,
isExternalPlum,
} from './tgpuPlum';
} from './tgpuPlumTypes';

export type PlumListener<T> = (newValue: T) => unknown;
type Unsubscribe = () => void;
Expand Down
10 changes: 3 additions & 7 deletions packages/typegpu/src/tgpuBuffer.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import { BufferWriter, type Parsed } from 'typed-binary';
import type { TgpuPlum } from './tgpuPlum';
import {
type AnyTgpuData,
type TgpuAllocatable,
type TgpuNamable,
isGPUBuffer,
} from './types';
import type { TgpuNamable } from './namable';
import type { TgpuPlum } from './tgpuPlumTypes';
import { type AnyTgpuData, type TgpuAllocatable, isGPUBuffer } from './types';

// ----------
// Public API
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/src/tgpuCode.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { getBuiltinInfo } from './builtin';
import type { TgpuNamable } from './namable';
import {
type Eventual,
type InlineResolve,
type ResolutionCtx,
type SlotValuePair,
type TgpuNamable,
type TgpuResolvable,
type TgpuSlot,
type Wgsl,
Expand Down
3 changes: 2 additions & 1 deletion packages/typegpu/src/tgpuConstant.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { TgpuNamable } from './namable';
import { code } from './tgpuCode';
import { TgpuIdentifier } from './tgpuIdentifier';
import type { ResolutionCtx, TgpuNamable, TgpuResolvable, Wgsl } from './types';
import type { ResolutionCtx, TgpuResolvable, Wgsl } from './types';

// ----------
// Public API
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/src/tgpuFunction.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { TgpuNamable } from './namable';
import { code } from './tgpuCode';
import { TgpuIdentifier } from './tgpuIdentifier';
import type {
Eventual,
InlineResolve,
ResolutionCtx,
SlotValuePair,
TgpuNamable,
TgpuResolvable,
TgpuSlot,
Wgsl,
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/src/tgpuFunctionExperimental.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { type AsCallable, CallableImpl } from './callable';
import type { TgpuNamable } from './namable';
import { code } from './tgpuCode';
import { TgpuIdentifier } from './tgpuIdentifier';
import { isPointer } from './types';
import type {
AnyTgpuData,
ResolutionCtx,
TgpuFnArgument,
TgpuNamable,
TgpuResolvable,
TgpuValue,
Wgsl,
Expand Down
3 changes: 2 additions & 1 deletion packages/typegpu/src/tgpuIdentifier.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { ResolutionCtx, TgpuNamable, TgpuResolvable } from './types';
import type { TgpuNamable } from './namable';
import type { ResolutionCtx, TgpuResolvable } from './types';

/**
* Helpful when creating new Resolvable types. For internal use.
Expand Down
45 changes: 8 additions & 37 deletions packages/typegpu/src/tgpuPlum.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,17 @@
import { type TgpuSettable, TgpuSettableTrait } from './settableTrait';
import type { TgpuNamable, TgpuResolvable, Wgsl } from './types';
import {
type Getter,
type TgpuExternalPlum,
TgpuExternalPlumTrait,
type TgpuPlum,
type Unsubscribe,
} from './tgpuPlumTypes';
import type { TgpuResolvable, Wgsl } from './types';

// ----------
// Public API
// ----------

export type Getter = <T>(plum: TgpuPlum<T>) => T;
export type Unsubscribe = () => unknown;
export type ExtractPlumValue<T> = T extends TgpuPlum<infer TValue>
? TValue
: never;

export interface TgpuPlum<TValue = unknown> extends TgpuNamable {
readonly __brand: 'TgpuPlum';

/**
* Computes the value of this plum. Circumvents the store
* memoization, so use with care.
*/
compute(get: Getter): TValue;
}

export const TgpuExternalPlumTrait = Symbol(
`This plum's value is sourced from outside the runtime.`,
);
export interface TgpuExternalPlum {
readonly [TgpuExternalPlumTrait]: true;

readonly version: number;
subscribe(listener: () => unknown): Unsubscribe;
}

export function isExternalPlum(
value: unknown | TgpuExternalPlum,
): value is TgpuExternalPlum {
return (value as TgpuExternalPlum)[TgpuExternalPlumTrait] === true;
}

/**
* Creates a computed plum. Its value depends on the plums read using `get`
* inside the `compute` function, so cannot be set imperatively.
Expand Down Expand Up @@ -90,10 +65,6 @@ export function plumFromEvent<T>(
return new TgpuExternalPlumImpl(subscribe, getLatest);
}

export function isPlum<T>(value: TgpuPlum<T> | unknown): value is TgpuPlum<T> {
return (value as TgpuPlum).__brand === 'TgpuPlum';
}

// --------------
// Implementation
// --------------
Expand Down
38 changes: 38 additions & 0 deletions packages/typegpu/src/tgpuPlumTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import type { TgpuNamable } from './namable';

export type Getter = <T>(plum: TgpuPlum<T>) => T;
export type Unsubscribe = () => unknown;
export type ExtractPlumValue<T> = T extends TgpuPlum<infer TValue>
? TValue
: never;

export interface TgpuPlum<TValue = unknown> extends TgpuNamable {
readonly __brand: 'TgpuPlum';

/**
* Computes the value of this plum. Circumvents the store
* memoization, so use with care.
*/
compute(get: Getter): TValue;
}

export const TgpuExternalPlumTrait = Symbol(
`This plum's value is sourced from outside the runtime.`,
);

export interface TgpuExternalPlum {
readonly [TgpuExternalPlumTrait]: true;

readonly version: number;
subscribe(listener: () => unknown): Unsubscribe;
}

export function isExternalPlum(
value: unknown | TgpuExternalPlum,
): value is TgpuExternalPlum {
return (value as TgpuExternalPlum)[TgpuExternalPlumTrait] === true;
}

export function isPlum<T>(value: TgpuPlum<T> | unknown): value is TgpuPlum<T> {
return (value as TgpuPlum).__brand === 'TgpuPlum';
}
2 changes: 1 addition & 1 deletion packages/typegpu/src/tgpuRuntime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { SimpleTgpuData, TgpuArray } from './data';
import type { PlumListener } from './plumStore';
import type { TgpuSettable } from './settableTrait';
import type { BoundTgpuCode, TgpuCode } from './tgpuCode';
import type { ExtractPlumValue, TgpuPlum, Unsubscribe } from './tgpuPlum';
import type { ExtractPlumValue, TgpuPlum, Unsubscribe } from './tgpuPlumTypes';
import type { TgpuSampler } from './tgpuSampler';
import type {
TgpuAnyTexture,
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/src/tgpuSampler.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { TgpuNamable } from './namable';
import { TgpuIdentifier } from './tgpuIdentifier';
import type {
ResolutionCtx,
TgpuNamable,
TgpuRenderResource,
TgpuSamplerType,
} from './types';
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/src/tgpuTexture.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { vec4f, vec4i, vec4u } from './data';
import type { TgpuNamable } from './namable';
import { TgpuIdentifier } from './tgpuIdentifier';
import { isSampler } from './tgpuSampler';
import type {
Expand All @@ -9,7 +10,6 @@ import type {
TexelFormat,
TextureScalarFormat,
TextureUsage,
TgpuNamable,
TgpuRenderResource,
TgpuRenderResourceType,
} from './types';
Expand Down
9 changes: 2 additions & 7 deletions packages/typegpu/src/tgpuVariable.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import type { TgpuNamable } from './namable';
import { code } from './tgpuCode';
import { TgpuIdentifier } from './tgpuIdentifier';
import type {
AnyTgpuData,
ResolutionCtx,
TgpuNamable,
TgpuResolvable,
Wgsl,
} from './types';
import type { AnyTgpuData, ResolutionCtx, TgpuResolvable, Wgsl } from './types';

// ----------
// Public API
Expand Down
19 changes: 2 additions & 17 deletions packages/typegpu/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type { ISchema, Parsed } from 'typed-binary';
import type { Builtin } from './builtin';
import type { F32, I32, U32, Vec4f, Vec4i, Vec4u } from './data';
import type { TgpuNamable } from './namable';
import type { TgpuIdentifier } from './tgpuIdentifier';
import type { TgpuPlum } from './tgpuPlum';
import type { TgpuPlum } from './tgpuPlumTypes';

export type Wgsl = string | number | TgpuResolvable | symbol | boolean;

Expand Down Expand Up @@ -37,14 +38,6 @@ export interface TgpuResolvable {
resolve(ctx: ResolutionCtx): string;
}

/**
* Can be assigned a name. Not to be confused with
* being able to HAVE a name.
*/
export interface TgpuNamable {
$name(label?: string | undefined): this;
}

export function isResolvable(value: unknown): value is TgpuResolvable {
return (
!!value &&
Expand All @@ -53,14 +46,6 @@ export function isResolvable(value: unknown): value is TgpuResolvable {
);
}

export function isNamable(value: unknown): value is TgpuNamable {
return (
!!value &&
(typeof value === 'object' || typeof value === 'function') &&
'$name' in value
);
}

export function isWgsl(value: unknown): value is Wgsl {
return (
typeof value === 'number' ||
Expand Down
3 changes: 2 additions & 1 deletion packages/typegpu/tests/plumStore.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { describe, expect, it, vi } from 'vitest';
import { type PlumListener, PlumStore } from '../src/plumStore';
import { type Getter, plum, plumFromEvent } from '../src/tgpuPlum';
import { plum, plumFromEvent } from '../src/tgpuPlum';
import type { Getter } from '../src/tgpuPlumTypes';

function makeSubject<T>(initial: T) {
let value = initial;
Expand Down
Loading

0 comments on commit b79681b

Please sign in to comment.