Replies: 1 comment
-
Yeah, mainly because you don't need to synchronize anything at all in many cases and with a good scheduling.
Yes and no. In theory, in-place deletion could be fully thread safe. Though, not sure it's worth it as a feature since deleting is a transparent operation that doesn't require the caller to know about the nature of the storage.
👍
Yeah, exactly, it boils down to accessing concurrently an instance of an object. It doesn't really depend on EnTT actually.
Ehm, again, yes and no. There is a class called
Technically speaking, if you pass a whole registry to a system, you can't easily limit the types of components it can access. On the other hand, if you only pass views to systems, it works (almost) out of the box, since the component types are part of their signatures with the right constness.
If registering T before U means giving T a higher priority than U, you're done. You don't need blocks nor phases nor anything else. With a proper way of setting global sync points (that literally define your sections eventually), you can just construct the graph from the system dependencies and make it safe to run then. When you want T to run after U necessarily, just set a shared resource and you've it.
Not sure what kind of facilities would help but I'm open to discussing it, of course. Any ideas?
See above. 🙂
Technically speaking, the |
Beta Was this translation helpful? Give feedback.
-
This is less of a thing where I have questions that need answers, and more of a thing where I think it would be useful to discuss the general idea.
Imagine you have some arbitrary application that is built around an ECS, such as EnTT. Imagine further that you want this application to take advantage of multiple CPU cores where it makes sense to do so.
If I understand the design of EnTT correctly, the following are true, or close enough to true for purposes of discussion anyway:
Keeping the above concerns in mind, even if they aren't 100% accurate, raises the following discussion points.
As far as I know, EnTT does not try to provide any kind of facilities to make the above easier to achieve, either in terms of building blocks or algorithms, or in terms of debugging facilities to ensure correctness.
So what I'm hoping to discuss is:
For some additional motivation behind this topic, I'm looking to integrate a library like https://github.com/taskflow/taskflow with an EnTT based game engine, where I hope to be able to have the execution graph that's fed to taskflow every frame be calculated automatically using a declarative style interface. Obviously the reason why I would want this calculated automatically is because: Lazyness. Why make a human do something when an algorithm can do it for us?
I'm also hoping to help junior contributors to the game engine avoid screwing up the execution plan by mistake by adding a dependency on a component (e.g. using the component some how) without declaring it.
So maybe what a solution to this discussion topic looks like is some kind of template-metaprogramming registration for a system and it's components, and then a wrapper around EnTT that requires the system that's accessing the data to include the System's type (e.g. whatever was used to declare it in the system<->component dependency registry) in the call to EnTT to get the component(s) the system wants to access. This would allow either a compile-error, or a runtime assert, to inform the junior contributor that they goofed. Presumably this checking could be disabled for debug builds, or could be compile time only.
Beta Was this translation helpful? Give feedback.
All reactions