software-mansion / software-mansion/TypeGPU

feat: Object spreading in 'use gpu' functions

Open
#2,686 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
3.2k
Forks
122
Avg merge
3d 5h
Merged PRs (30d)
34

Description

There are cases where we want to create a new struct where almost all properties match an existing struct, but a few need to be updated:

const Entity = d.struct({
  pos: d.vec3f,
  vel: d.vec3f,
  health: d.f32,
  bodyAngle: d.f32,
  headAngle: d.f32,
});

const entities = root.createBuffer(d.arrayOf(Entity, 32)).$usage('storage');
const entitiesMutable = entities.as('mutable');
const entitiesReadonly = entities.as('readonly');

function main() {
  'use gpu';
  const entity = Entity(entitiesReadonly.$[0]);
  entity.health = 1; // same as entity#0, but with 1 health
  // ...
}

The ways to do this currently are either copying the whole struct 1-to-1, and updating the fields we want to differ as separate statements:

const entity = Entity(entitiesReadonly.$[0]);
entity.health = 1; // same as entity#0, but with 1 health

Or listing all the properties out:

const entity = Entity({
  pos: entitiesReadonly.$[0].pos,
  vel: entitiesReadonly.$[0].vel,
  health: 1,
  bodyAngle: entitiesReadonly.$[0].bodyAngle,
  headAngle: entitiesReadonly.$[0].headAngle,
});

Object spreading

If we supported object spreading, we could just do the following:

const entity = Entity({ ...entitiesReadonly.$[0], health: 1 });

Which would generate:

var entity = Entity(entitiesReadonly[0].pos, entitiesReadonly[0].vel, 1, entitiesReadonly[0].bodyAngle, entitiesReadonly[0].headAngle);

In an object expression, there can be an arbitrary amount of spreads, located before or after regular object properties. A spread is essentially just setting the props contained on another object, replacing any previously defined values on keys that already exist.

Requirements for foo in ...foo expressions:

  • It has to be side-effects free, since we're going to be generating potentially many foo.* expressions.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the compiler path for object expressions inside 'use gpu' functions; the issue does not name an entry file or test. Use the examples as the behavioral guide: support arbitrary spreads before or after properties, apply later values over earlier ones, emit the expanded field expressions, and reject side-effectful spread operands.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
compilers, computer-graphics
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.