No description
Find a file
Emi Gutekanst 17a830f857 object: add ability to tag arbitrary objects with arbitrary tags and values
Modules define lists of objects, e.g. a `SpriteRenderer` module may define

```zig
sprites: mach.Objects(struct {
    // ...
}),
```

Previously, the only way for another Mach module to 'attach data to a sprite object' or 'tag a sprite' would be to (ab)use the graph relations system, creating their own object and using parent/child relations to express that the sprite has some tag/data associated with it. For example:

```zig
// Game.zig

is_monster: mach.Object(struct{}), // empty object just to indicate 'some other object is a monster'

// ...

// Create a 'tag object'
const is_monster_tag_obj_id = game.is_monster.new(.{});

// Add the 'tag object' as a child of our sprite
sprite_renderer.sprites.addChild(my_sprite_id, is_monster_tag_obj_id);

// ...
```

This usage of the API was quite ugly/usage, and importantly eliminated your ability to use the parent/child relations for _other_ things where they are more appropriate. However, it did mean that you didn't have to go and fork+modify the `SpriteRenderer` module that you e.g. imported as a reusable package.

With this change, we add object _tags_ and _tags with values_. Any module can add their own tags or tags with values to any object, whether it is from their module or not. For example, the `is_monster` example above could now be written as:

```zig
// Game.zig

pub const mach_tags = .{ .is_monster };

// ...

try sprite_renderer.sprites.setTag(sprite_id, Game, .is_monster, null);
const is_monster: bool = sprite_renderer.sprites.hasTag(sprite_id, Game, .is_monster);
// is_monster == true!

// No longer a monster
try sprite_renderer.sprites.removeTag(sprite_id, Game, .is_monster);
```

This allows for effectively tagging objects as distinct kinds, states, etc. even though they aren't our object and we can't modify their `struct {}` type to include an `is_monster: bool` field of our own.

Internally, the implementation stores tags using a hashmap under the assumption that not all objects in a list will have a tag.

Tags with values work almost identically, the only difference is that the last parameter to `setTag` is set to another `mach.ObjectID` which points to whatever arbitrary data you'd like to attach to the object, and `getTag` returns it. For example:

```zig
// Game.zig

pub const mach_tags = .{
    /// Whether a sprite is a monster
    .is_monster,

    /// Whether a sprite has a friendly sprite attached to it
    .{ .friend, Sprite, .sprites },
};

// ...

try sprite_renderer.sprites.setTag(sprite_id, Game, .friend, friendly_sprite_id);

const has_friend: bool = sprite_renderer.sprites.hasTag(sprite_id, Game, .friend);
// has_friend == true!

// Get our friend
const friend_id: mach.ObjectID = sprite_renderer.sprites.getTag(sprite_id, Game, .friend);
// friend_id == friendly_sprite_id

// Delete our friend
try sprite_renderer.sprites.removeTag(sprite_id, Game, .friend);
```

Signed-off-by: Emi Gutekanst <emi@hexops.com>
2025-02-08 19:13:12 -07:00
.github github: update zig nomination template 2024-12-30 20:53:05 -07:00
examples core: remove option to support non-blocking and only allow platform to control main loop 2025-01-12 09:05:09 -07:00
src object: add ability to tag arbitrary objects with arbitrary tags and values 2025-02-08 19:13:12 -07:00
.gitattributes use mach-model3d via package manager 2023-07-01 22:33:35 -07:00
.gitignore update .gitignore for Zig 2024.05 2024-06-02 09:35:13 -07:00
.zigversion nominate Zig 2024.11.0-mach 2024-12-30 20:50:39 -07:00
build.zig core: windows: refactor everything 2025-01-19 13:37:48 -07:00
build.zig.zon core: Update to latest mach-objc 2025-01-31 08:09:23 -08:00
LICENSE LICENSE: note directories with a separate LICENSE file 2021-07-05 12:46:20 -07:00
LICENSE-APACHE initialize repository 2021-07-04 10:36:34 -07:00
LICENSE-MIT initialize repository 2021-07-04 10:36:34 -07:00
README.md README: fix link 2025-02-01 20:53:42 -07:00

mach-opus

Zig game engine & graphics toolkit for building high-performance, truly cross-platform, robust & modular games, visualizations, and desktop/mobile GUI apps.

gen-texture-light boids textured-cube

Learn more

machengine.org

Join the community

Join the Mach community on Discord to discuss this project, ask questions, get help, etc.

We're here to make games and have fun, so please help keep the community focused on that. No politics/heated topics are allowed. Unfortunately, the political landscape today makes it such that we must also state: fascists can go f*k themselves, we support LGBTQ+ and minorities here - their existence is not political.