Open WinstonHartnett opened 2 years ago
This design works well AFAICT:
mySystem =
emap (optional @Whatever @IO <..> write @(Velocity, Flying, VelocityUpdated))
(do
MkVelocity v <- with
if v >= 50
then branch @(Whatever, VelocityUpdated) >> tag MkFlying >> untag @VelocityUpdated
else tag (MkVelocity $ v + 1.0)
The first argument to emap
is a Query x m a
type that tracks (1) store access rights in its type and (2) specifies the filtering routine for runtime archetype graph traversal. Theoretically, you could run some code in the Query
itself but that might be a tad dangerous. The <..>
is a dummy helper that joins two queries.~
The do
block is a System x m a
. The x
parameter makes sure the system only accesses components that have been declared. branch
is a helper that short-circuits when the optional target components are not attached to an entity.
The above posted example is, equivalently:
emap (read @(Position, Velocity) <..> optional @Whatever <..> write @Flying) $ do
MkVelocity v <- with
when (v.x >= 50) (branch @Whatever >> set MkFlying)
Question: (see above TODO) Any way to infer x
without explicit dependencies? Maybe a typechecker plugin?
With parallel systems, we can't allow unrestricted component access, so I need some mechanism of scoping resources in systems. Something like:
or with a snazzy
ecstasy
-like API:shortened to
and the underlying type stores the read & write union... <- this is the hard part
TODO