No description
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>
|
||
|---|---|---|
| .github | ||
| examples | ||
| src | ||
| .gitattributes | ||
| .gitignore | ||
| .zigversion | ||
| build.zig | ||
| build.zig.zon | ||
| LICENSE | ||
| LICENSE-APACHE | ||
| LICENSE-MIT | ||
| README.md | ||
Zig game engine & graphics toolkit for building high-performance, truly cross-platform, robust & modular games, visualizations, and desktop/mobile GUI apps.
Learn more
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.


