bevyengine / bevyengine/bevy

Add a getter for SystemMeta::last_run (or help me not need it?)

Open
#22,487 2 comments 0 reactions 0 assignees View on GitHub
A-ECS C-Feature D-Modest S-Ready-For-Implementation
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 16h
Merged PRs (30d)
171

Description

## What problem does this solve or what need does it fill?

I am implementing a custom `SystemParam` for my plugin [Shieldtank](https://github.com/stinkytoe/shieldtank). This is meant to be a framework for loading LDtk files.

LDtk objects provide a UUID for each object in in their document tree, which they call an Iid. Right now I'm adopting their nomenclature. I have added a component which is auto inserted whenever an entity is created from one of these assets, which basically wraps this Uuid. See [iid](https://github.com/stinkytoe/shieldtank/blob/main/src/component/iid.rs).

I though it would be nice to provide the user with a `SystemParam` similar in behavior to `Single` which I currently call [SingleByIid](https://github.com/stinkytoe/shieldtank/blob/04d216a8db91749c9975c2756dc1a987e80b8aea/src/query/by_iid.rs#L19) (might change name later). This object takes the u128 representation of the Uuid as a generic parameter, so that the user can insert it into the signature of their system.

Here's two game demos I'm developing in conjunction with this plugin as proof of concept, both of which use this `SystemParam`: [axe_man_adventure](https://github.com/stinkytoe/axe_man_adventure) [dungeon_of_madness](https://github.com/stinkytoe/dungeon_of_madness).

The problem I'm having is in the manual trait impl for my `SingleByIid` struct. I basically shamelessly copied bits and bobs from Bevy's `Single` and `Populated`. The problem is though, both `Single` and `Populated`, when they implement `SystemParam`, use a line similar to the following:

```rust
let query = unsafe {
state.query_unchecked_with_ticks(world, system_meta.last_run, world.change_tick())
};
```

The field `SystemMeta::last_run` is `pub(crate)`, and therefore not usable to me.

I tried using `UnsafeWorldCell::last_change_tick` in its place, but it would fail to yield when the `QueryFilter` would include a change detection filter, such as `Changed`. (Though it worked with `Changed`?). It would also fail `Changed`, which is one of my components.

Anyways, I forked Bevy and added a `SystemMeta::get_last_run` getter for that field. Using this getter method, change detection now works as I expect, at least in all of the testing and experimentation I've done. [my fork](https://github.com/stinkytoe/bevy)

I would be glad to file a PR from my fork, if y'all would consider excepting it. But, I wanted to write this Issue first to make sure this is the right way to fix this.

Is there another way for me to overload the `validate_param` trait method? Or, another way to generate the query with provided methods that would work?

Am I smoking crack here for trying this?

## What solution would you like?

Add `SytemMeta::get_last_run`, or give me the green light to submit my fork as a PR.

## What alternative(s) have you considered?

Using `UnsafeWorldCell::last_change_tick` works most of the time, but not when the `QuerFilter` has change detection type queries. But only some times.

## Additional context

Y'all are awesome!

Contributor guide

Open the contributing guide

Research direction

Read the SystemMeta and SystemParam implementations, then compare how Single and Populated call query_unchecked_with_ticks with system_meta.last_run. Check UnsafeWorldCell::last_change_tick against the reported Changed filters. Done means identifying a supported public path for custom SystemParam change detection or deciding whether a getter/API change is appropriate.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
api, game-dev
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.