Commit 17a830f
committed
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 <[email protected]>1 parent 9749cd9 commit 17a830f
1 file changed
+94
-0
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
70 | 70 | | |
71 | 71 | | |
72 | 72 | | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
73 | 76 | | |
74 | 77 | | |
75 | 78 | | |
76 | 79 | | |
77 | 80 | | |
78 | 81 | | |
79 | 82 | | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
80 | 88 | | |
81 | 89 | | |
82 | 90 | | |
| |||
275 | 283 | | |
276 | 284 | | |
277 | 285 | | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
278 | 332 | | |
279 | 333 | | |
280 | 334 | | |
| |||
497 | 551 | | |
498 | 552 | | |
499 | 553 | | |
| 554 | + | |
| 555 | + | |
| 556 | + | |
| 557 | + | |
| 558 | + | |
| 559 | + | |
| 560 | + | |
| 561 | + | |
| 562 | + | |
| 563 | + | |
| 564 | + | |
| 565 | + | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
| 576 | + | |
| 577 | + | |
| 578 | + | |
| 579 | + | |
| 580 | + | |
| 581 | + | |
| 582 | + | |
| 583 | + | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
500 | 594 | | |
501 | 595 | | |
502 | 596 | | |
| |||
0 commit comments