-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Back to Base Sets #16432
Comments
I generally agree with your criticisms of the state of thing here, but I would like to fully remove schedules in a refactor like this, and explicitly pass in a base set in place of the |
I don't think this is feasible. Schedules can't go away really. The most obvious example is We could make schedules lighter weight, especially if we switch to systems as entities. Then a schedule just becomes a system set to run and a cached topo sort. But that's a future ask, and I'm not sure if we need to wait on this. Note this issue requires pretty much no migration guide. |
There definitely needs to be a
This was exactly the sort of thing I had in mind. I don't think we need to wait on systems-as-entities for this, but it sure would be nice to be able to quickly filter by label like that. |
(this is kind of a brain dump)
IIUC where you're coming from, Could I paraphrase what you're proposing like this? "It should be possible to tie a system set to a schedule, such that the schedule is implied by the set and users can just cite the set alone when calling If so, let's say scheduled systems become entities. At that point, it would become possible to analyze constraints between systems in different schedules, as long as there's something attached to the system entity indicating which schedules include it. I say "schedules" (plural) because, with systems being entities, it would be possible to allow using one instance of a system (e.g. There used to be complaints about having to duplicate a set's configuration in multiple schedules. If systems and sets were stored in a single, shared repository (i.e. entities in the So on the surface, tying a system set to one schedule deviates from that, but I'm wondering if that's a genuine deviation or if a system set exclusively belonging to one schedule (just like parent-child) is the right framing. Either way, I think I would prefer that sets relate to schedules in a consistent manner (i.e. It feels kinda sus if some sets are exclusive and others are not). |
I said this on Discord too, but the full scope of a schedule is an exclusive system that runs other systems (using, at the very least, a cached list of systems, possibly augmented with dependency information). I think this executable / "gets treated as an exclusive system" is an essential part of what a schedule is. The The labeling aspect is just how schedules are presented by the scheduling API. System sets are just the labeling aspect, so "a system set you can run" just turns it back into a schedule.
I think it'd make sense to merge sets and schedules into a single concept. A set basically gives an identity to a graph and a schedule is that + a "compiled executable" of the graph, so I see unification as making it so an "executable" can be materialized for any set. The idea of being able to run any system set (i.e. materialize a schedule for any set on-demand) was actually present in an earlier revision of the "stageless" proposal (but it was rejected due to concerns about the proposed implementation). It implies some potentially expensive costs in the presence of a lot of sets, i.e. observers that sort the subgraphs given by these sets whenever systems are added/removed. |
But yeah, getting back on the main topic, I think the suggestion is reasonable, I'd just like some more supporting arguments for why it makes sense for a system set to be optionally vs. always associated with one schedule. (I'm trying to convince myself.) It'd also be nice to share some thoughts about what a dynamic representation of these exclusive/non-exclusive connections would be. (I assume it'd be a relationship, but like would it be |
I just wanted to say... amazing job on the issue description. It's beautifully written. I like how you addressed past feedback and gave examples to show how it would look. I like the advantages and I am interested to see where this goes! |
Background
Today, we have many schedules.
Main
,First
,PreUpdate
,Update
, etc. Primarily, these are used for general ordering of systems. This has necessitated a bunch of sad parts likeMainScheduleOrder
. This is just code duplication. We already have a way to order a bunch of systems: system sets! In theory, instead of Update being a schedule, it could be a system set and get basically the same behaviour. In theory we could even have systems that run between PreUpdate and Update (without needing a schedule in between). Schedules reduce parallelism and system set constraints aren't (currently) shared across schedules.Base Sets
In #8079, we removed base sets. I believe this was the correct move at the time. The main problems listed in that PR:
in_base_set
which was different fromin_set
.add_system(foo.after(TransformPropagate))
would fail because foo is implicitly inCoreSet::Update
"Update
is nowhere to be seen, and no way to really "reach" it with "Go to Definition".I am not trying to bring back base sets as they were. However, they have a nice advantage: there's pretty much one schedule to deal with:
Main
.Bringing them back in style
The current syntax for adding systems is very nice:
Let's keep that! I propose adding a trait like:
Then
add_systems
becomes:So far, nothing has changed: we can still add systems to a schedule like normal. We can also still add systems to system sets like normal:
The kicker comes from the next step. First, we need to bring back the
CoreSet
enum (part of it at least):And finally, we change
Update
and friends, to the following:Now look what this does:
Wait... nothing changed... Exactly! Under the hood,
Update
is no longer a schedule. It is a system set in theMain
schedule. Provided that Bevy adds a.chain()
for all theCoreSet
, #9822 will automatically insert a sync point between the "base sets". Now we've just made some syntactic sugar for:User's don't need to learn anything about base sets, they just silently use them. There's also nothing special about base sets. Users can create their own "base sets" by just making a new struct that impls
SystemLocation
.Even rendering can take advantage of this. As far as I can tell, rendering uses one schedule with a bunch of system sets for performance reasons. Now we can have a nicer API:
MainScheduleOrder
can be replaced with justconfigure_sets
calls:Alternatives
CoreSet
implementSystemLocation
. Then ouradd_systems
calls would look likeapp.add_systems(CoreSet::Update, move_donkey)
.add_systems
. (I'm not a fan of this since it reduces what we can do with system sets).Risks
add_systems
. This can be confusing to learn about the difference betweenUpdate
,CoreSet::Update
, andMain
. (it may be confusing that you can add systems to a system set in two ways). I think this is fine since this is mostly just an implementation detail. From a user's perspective they are doing the same thing that schedules do today.Update
and (assuming itsSystemLocation
impl is close), see that it belongs to theMain
schedule.The text was updated successfully, but these errors were encountered: