-
Notifications
You must be signed in to change notification settings - Fork 85
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
Dynamically typed queries #69
Comments
This is definitely interesting. I don't have an ultra-specific use case, but I'm drawing out a framework I'd like to make that utilizes the advantages of an ECS architecture but still provides some form of scripting component for fast iteration and smoother workflow. Plus it'd be nice to get around Rust's compile times by writing non-performance-critical systems in a script. |
Concrete use cases are particularly important because they can help inform the exact shape the API could take to solve a specific problem. |
I realize that. When I can write out a concrete case I'll come back to this issue to describe it. |
I'm quite interested in this. I'd like to experiment with hooking hecs into the scripting language in my engine. |
Bevy is exploring a similar effort, which may at least provide inspiration. Of particular interest is the introduction of dynamic components, treated as plain fixed-length data associated with a custom ID. A key question for proceeding with API design here is what's required for passing results to a scripting layer easily and efficiently. Examples of the patterns needed to provide low-overhead and ergonomic access to Rust data from a script would be valuable. |
Another compelling idea from bevy: define a space of These could be feature-gated to allow users who only need static components to avoid the indirection. Dynamic queries could still be available regardless. |
Was chewing on this lately and was able to come up with a solution which essentially works by trait-object-izing |
This is actually the reason I was reading through the issues in the first place. I'm not sure what the state of this is but it is a requirement for my work and the potential of switching the current C++ component storage/query system to hecs. (I'm tired of hunting bugs in C++ and I have rewritten a bunch of my code in Rust, so....) Basically the three key bits I'm looking at as being blockers for my intentions:
Anyway, this enhancement seems like the answer, correct? |
Some of the interfaces discussed here could be applied to those problems, yeah. See also the draft in #202, which has been successfully applied to Lua, which should be a superset of the challenges presented by a C binding. You describe a dynamically varying C API--are you working with a shared library plugin system? |
I'll take a look at that, though one of the key legacy items will be problematic if the performance degradation is significant. I.e. the render instance components tied to the C++ side renderer. I haven't convinced those guys to become Rusty yet, it's on the long term evil corruption todo list though.
No, I won't be using dll's/so's/dylib's etc for this. They are way too problematic in multiple ways., especially with Windows where half the time they won't tear down at all due to PDB's being non unloadable, file locking issues and tons of other problems. When I said "dynamic" I was referring to the hot reload of the behavior tree's because with those the things changing are programically generated. I have a number of similar items which will have the same issues, they don't have a fixed system signature because they are generated from data. The more complicated example would be the LLVM Orc JIT I use during development, it compiles the "plugin" straight to memory and I dig out the handles to the C API functions that will need to have access to the components in hecs based on what I find in the signature. Typically speaking though, with the current system there is very little performance loss when doing this because the bindings are generated just once and reused until such time as something reloads. I'm hoping to get similar behavior here though it's not absolutely required since after things start working you flip a switch and the code side items just get compiled into the final executable and the hot reload is removed, leaving a load/bind only once in it's place. |
Cool; please do leave feedback in the PR regarding its usefulness to you! |
It's a very good idea to use And generally, using Python for the scripting language for Engines it's really cool idea. |
Having come across this issue researching ways to do this, I think it would be a great feature. Being able to author queries in a scripting language would be very useful. |
i'm actually pretty much interested and motivated to put my hands into this, after prior some guidance possibly. my use case is precisely allowing hecs to be more or less usable on the scripting side, where script calls query function on the world wrapper, scripting side then calls native side by decoding type information (TypeId maybe?) and based on that dynamic query would be asked for next components set, yielded back to script side that understands how to operate on given component types. |
My current vision for this has three parts. These don't need to all be solved simultaneously, but care is required to ensure they'll fit together in the end. Dynamic queriesMore or less as described in the original post. Dynamic component IDsPer #69 (comment). This enables scripting languages to introduce new component types. Replace most internal uses of pub enum ComponentId {
#[cfg(feature = "dynamic-components")]
Dynamic(u64),
Static(TypeId),
} Components with dynamic types will be manipulated on the Rust side as blobs of Consistently mapping dynamic IDs to semantics/layout will be important. The first draft should probably leave that up to downstream code (which might maintain e.g. a serialized global registry). FFI bindingsThis is probably the hardest remaining design problem. We need to efficiently pass complex dynamic structures through a well-defined (presumably
|
hmm, wouldn't be good enough to just focus on dynamic queries only now? |
Queries are a good start, but we probably need random access as well, for example. |
hecs could be extended with support for executing queries constructed at runtime rather than specified statically in types. This could be useful for e.g. interactively user-specified queries or for running queries in embedded scripting environments.
An implementation could look something like:
where
DynamicQueryBorrow<'_>
contains an iterator which yieldsDynamicQueryItem
which hasor perhaps
This is complex enough that I'm not likely to work on it unless there's significant demand, so please leave a comment describing your use case if you're interested!
The text was updated successfully, but these errors were encountered: