I read the front page of this site, and I still have a general question about ECSes. For what it's worth, I'm developing a DAW (digital audio workstation) in Rust.
It seems that ECS helps compose "things" (an entity) out of groups of data (each a component), and then operates upon combinations of those components (using systems). My domain is organized around behavior (many musical instruments implementing a Rust trait or interface, such as MIDI), but the data constituting each instrument is totally different. So the behaviors are the same, but the data is different. It seems that ECS isn't a fit, which is a shame because the implementations I've seen offer cool features like easy parallel processing, querying, and so on.
Is there a design pattern like ECS but for common behaviors instead of common data? Or am I being dense and not seeing how ECS actually is a good fit for this situation?
The way you frame the question already suggests a solution, and one that indeed doesn't fit ECS that well. That doesn't mean you couldn't design a DAW using ECS, but you'd have to redesign how it works.
For example:
- create custom components for different instruments
- create systems for specific instruments that match the necessary components
- write the result to a common component (e.g. "ChannelOutput")
You could then add components for EQ, effects, routing, ... and introduce systems that match those. The advantage of this approach would be that you end up with a bunch of loosely coupled systems (for instruments, effects, mixing, ...) and an in-memory representation that's cache & parallelization friendly.
One other datapoint would be that Unreal's animation sequencer uses an ECS design, which has a lot of things in common with a DAW.
Glossing over lots of details here, you can't of course design a DAW in one paragraph.
Thanks (and thanks especially for responding to what should have been a Stack Overflow question). I do see potential for certain ECS systems that span instruments, like DCA, effects wet/dry, routing, and mute. That makes sense. Your suggestion for component/system per instrument was what I felt ECS was asking me to do, but the libraries I investigated seemed to contemplate dozens but not hundreds of components, and that's where I began to think I was putting the cart before the horse.
I had an epiphany a while ago that a modern interactive DAW is a video game, except parts of it run at 44,100 fps. And even the "except" part is misleading, because games have sound as well. That opened up my mind to game development as another domain to steal designs from.
It seems that ECS helps compose "things" (an entity) out of groups of data (each a component), and then operates upon combinations of those components (using systems). My domain is organized around behavior (many musical instruments implementing a Rust trait or interface, such as MIDI), but the data constituting each instrument is totally different. So the behaviors are the same, but the data is different. It seems that ECS isn't a fit, which is a shame because the implementations I've seen offer cool features like easy parallel processing, querying, and so on.
Is there a design pattern like ECS but for common behaviors instead of common data? Or am I being dense and not seeing how ECS actually is a good fit for this situation?