# Smithay ECS concept
The proposal is to rework Smithay's Wayland abstractions to be based on an ECS pattern.
## Why?
The current state machine pattern in Smithay requires a huge amount of generics, opaque UserDataMaps and user data on objects which are not ideal to use.
### Generics
With the current pattern of smithay, some protocol implementations require generics directly on the delegate type and or the user data. The main issue with this pattern is a cancer-like spread of generic types.
### Opaque user data maps
Inside of Smithay there is a reliance on opaque user data maps, especially for the compositor module. Some of the opaque user data maps also cause Arc cycles because an object has a user data map, but the user data map contains the object.
### User data on objects
User data has to be statically defined by the implementation of Dispatch. This means that users of Smithay cannot hang extra data onto objects unless a UserDataMap is used. Also user data requires interior mutability.
## Why does ECS make sense in the context of a Wayland compositor?
Wayland's protocol and how extension protocols work lends itself well to ECS as a concept.
For example let's consider creating a window that can use fractional scale, with these protocol objects: `wl_surface`, `wp_viewport`, `wp_fractional_scale_v1`, `xdg_surface` and `xdg_toplevel`.
A client would first create a `wl_surface` protocol object. A `wl_surface` would contain things like the attached buffer, damage boxes, which outputs the surface are inside.
To realize a window, the client needs to create a `xdg_surface` role object and then an `xdg_toplevel`. This attaches more data to the `wl_surface` since the `wl_surface::commit` needs to apply double buffered state from itself and role object/other extension interfaces. An `xdg_surface` contains more data such the geometry of the window. Like `xdg_surface`, `xdg_toplevel` also needs more data to be assoicated with the surface.
`wp_viewport` and `wp_fractional_scale_v1` like the previous objects requires more data be attached to the surface.
Given each extension object beyond `wl_surface` attached more and more data, this can be a great spot for using ECS. Assuming `wl_surface` is the entity in the ECS, we could consider the `xdg_surface`, `xdg_toplevel`, `wp_viewport` and etc to be components we attached to the entity.
> What about mutually exclusive extension objects, like wl_subsurface and xdg_toplevel being incompatible?
This would require some special care. A way to tag a component as some type of "role" component could be used. Also `xdg_surface` is a sort of pseudo role, it forbids any role which doesn't extend `xdg_surface` but allows extending roles, such as `xdg_toplevel` and `xdg_popup`. So a way to replace a role would be needed, though this is just an implementation detail.
Not every component that would be assoicated with an entity is strictly going to be a protocol object. A compositor could attach some internal data on the object.
What ECS allows in this context is an easy way to assoicate data with some entity. This works for both some of Smithay's abstractions needing some internal state and users of Smithay which may have their own data.
## Where does ECS feel weird or fuzzy in Smithay
*Note: Not super familar with ECS, just writing some things I considered*
Not every system needs to exclusively use ECS. It is actually quite common in game engines where ECS is more widely used to have some systems not use ECS for the sake of usability or performance.
Some protocol objects aren't going to exist in many instances. ECS is known for storing components effeciently in memory to allow fast iteration without cache line hits.
Wayland object lifetimes can also be a bit bizzare. Client death would need to be considered when designing the ECS framework.
Some protocol objects when represented logically as a single object on the server with multiple client instances would need a way to handle multiple entities as one logical entity.
With extension interfaces, an entity may also need to be treated like a component. This isn't a new thing as [DECS](https://crates.io/crates/dces) (which is used in orbtk) but is can be uncommon.
In ECS when deabbrivated is Entity Component System. This proposal has entities and components, but systems feel left out. The closest thing I could think of being system-like would be a way to dispatch some requests on the components itself. For example when a `wl_surface` is committed, a way to notify it's components that it was committed can be very useful. But this does not strictly match the concept of a "system" in ECS.