Comments (8)
Hey Mario, thanks for suggesting this idea and taking the time to write a proof of concept! I'm generally in favor of tightening up types and I think the query surface API is now stable enough that the maintenance load should be acceptable. I'm concerned that TypeScript isn't sufficiently expressive to correctly represent the API, though. I couldn't quite figure out how to make the playground work for me so here's a few questions:
- Can you support multi-flavor queries? Doing something like
q.added.changed.removed.with(Foo)
is recommended and more efficient than three separate queries. - Do you lose type safety when the number of component types in
with
exceeds the pre-expanded method type signatures? If so, I think it's a bit risky to provide type safety most of the time only to drop it silently in corner cases. - Can this approach support multiple
with
,without
, andusing
clauses, some withwrite
and some (implicitly or explicitly) justread
? It looks to me like right now it applies thewrite
modifier to all component types. - Can you enforce at least one
track
being required if there are anychanged
-related flavors, and prohibited otherwise?
I'm also willing to consider tweaking the query language to make strong types easier to create but don't really want to get too far from the fluent API approach.
from becsy.
Awesome, looking forward to contributing this. I've iterated a bit further, doing away with pre-expansion (link to playground).
- Can you support multi-flavor queries? Doing something like q.added.changed.removed.with(Foo) is recommended and more efficient than three separate queries.
Yes, the current proof of concept supports this
- Do you lose type safety when the number of component types in with exceeds the pre-expanded method type signatures? If so, I think it's a bit risky to provide type safety most of the time only to drop it silently in corner cases.
Agreed, I've figured out how to avoid the method overrides to avoid this
- Can this approach support multiple with, without, and using clauses, some with write and some (implicitly or explicitly) just read? It looks to me like right now it applies the write modifier to all component types.
I think so! We'd have to come up with a full set of type tests to verify this - I plan to make that test suite the first step of the contribution, we can then work on filling out the gaps as you see them.
- Can you enforce at least one track being required if there are any changed-related flavors, and prohibited otherwise?
Not intuitively, but I'll try to come up with something. Would you want this to be part of the first iteration?
Another thing I haven't covered yet is Entity.prototype.read
throwing when a non-existent component matched via .using
is read. I'm not too sure about how to support that either - could this be a candidate for an API change, e.g. by making it return undefined
in those cases with Entity.prototype.read
giving a way to narrow from T | undefined
to T
?
from becsy.
Can this approach support multiple with, without, and using clauses, some with write and some (implicitly or explicitly) just read? It looks to me like right now it applies the write modifier to all component types.
I think so! We'd have to come up with a full set of type tests to verify this - I plan to make that test suite the first step of the contribution, we can then work on filling out the gaps as you see them.
That would be most impressive!
Can you enforce at least one track being required if there are any changed-related flavors, and prohibited otherwise?
Not intuitively, but I'll try to come up with something. Would you want this to be part of the first iteration?
We'll never be able to enforce everything via types (e.g., you must drop references to a read (write) component before you request the next read (write) component of the same type), so I'm fine with a "best effort" approach. My only concern, as noted earlier, is that I'd prefer not to have "partial enforcement" of a rule -- if it's handled at compile time, there should be no way for that rule to throw a runtime exception. But I could imagine even making exceptions on this point.
Another thing I haven't covered yet is
Entity.prototype.read
throwing when a non-existent component matched via.using
is read. I'm not too sure about how to support that either - could this be a candidate for an API change, e.g. by making it return undefined in those cases withEntity.prototype.read
giving a way to narrow fromT | undefined
toT
?
Hmm, I'm not sure what you have in mind for narrowing the type? The current API is this way for two reasons: 1) to avoid having to suffix every component read/write with !
in TS when you know the component exists (even though it may not be required by the query), and 2) to throw a more informative exception on failure, so you don't need to guess which component was missing if the argument wasn't a class literal.
from becsy.
Very good, I give it a go then. let's defer outstanding questions to when we have the type tests as a means of communication.
from becsy.
First draft of how type tests could look like here https://github.com/LastOliveGames/becsy/pull/8/files, let me know what you think.
from becsy.
Heyho. Just saw this project in the search for a less typescripty awkward/verbose alternative to ecsy.
How is the state of your type-enhancing going? Looks promising so far as I read.
from becsy.
I'm not sure how @marionebl is doing, but note that the library is very much usable in TypeScript as-is: this is just trying to push static typing that little bit further, but runtime checks will remain necessary for a bunch of constraints that just can't be expressed in the type system. I'd encourage you to give it a try!
from becsy.
Not making much progress, busy with other things!
from becsy.
Related Issues (20)
- Question: Tracking / accessing entities by their id HOT 5
- Attach returns system box instead of system HOT 3
- System support for deferring work to be done on next execute HOT 3
- How to use dictionary and other reference type in the component? HOT 1
- Graph.findCycles() does not always find cycles HOT 2
- Terminating the world and creating a new one with the same components results in an error HOT 5
- can this be use in Phaser 3? HOT 3
- Ability to run a `dispose` method on systems in a system group HOT 3
- Command pattern for Systems HOT 7
- World.terminate() never resolves HOT 3
- ChainAlert: npm package release (0.13.1) has no matching tag in this repo
- Cannot read properties of undefined (reading 'trackedWrites') HOT 4
- Ability to refer to entities by identifiers stored in an external data structure HOT 6
- Internal error: Should commit log before counting. Please report a bug! HOT 7
- Is there an API to see if Becsy is currently running in accessRecentlyDeletedData mode? HOT 3
- Injecting dependencies into Systems HOT 2
- Example demo, teypscript version reports error, cannot find attribute `track` on `QueryBuilder` HOT 1
- why use sparse set rather than archetype? HOT 1
- Hello, are you still updating? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from becsy.