Hodgman
Re:OOP Is Dead, Long Live OOP
on Thursday October 18, 2018 @10:58PM (#18253959)
This is called the actor model, and we actually implemented it in a prototype game engine once. We made one thread per CPU core and collected messages in "cycles" - where you'd process a batch of messages in parallel, which could produce the next batch. Messages would be sorted/grouped by target object address and then partitioned among the thread pool for execution. Most of the architecture was wait-free (no locks/atomics) so it really was quite fast.
This resulted in a C++ framework where you could write 'typical' OOP code and it would automatically be deconstructed into call-graphs and safely scheduled for execution across any number of threads in a completely deterministic way, without locks.
We abandoned the prototype because the "typical" OO behaviour of having deep call graphs is not actually something we want to keep, making the purpose of the framework kind of shaky.
Also, while performance was good, the characteristics weren't quite suitable for games -- it worked best if you had large objects, receiving multiple messages each, doing computationally complex work. In our games though, we typically have huge numbers of very simple objects, so batching messages by class instead of by object typically gives the best performance.
Re:OOP Is Dead, Long Live OOP
on Thursday October 18, 2018 @07:29PM (#18253219)
Follow up articles in that series are going to show how to make it multi-threading and OO-compliant.
"Typical" bad OOP code is a threading nightmare because the flow of control and flow of data becomes impossible to follow - it's all just random objects calling random objects calling random objects. Not spaghetti code, but spaghetti flow.
To write threadable OOP, you need to avoid fine grained polymorphism and deep call graphs. Instead of doing work immediately by calling out to the next object, return some results to your caller and allow them to make the call. This also allows your caller to collect large batches of work a'la DOD... which often actually increases performance (much better I$ and D$ usage) AND it's also much closer to old school OO message passing theory, and assist in writing simple, decoupled components.
I'd go as far to say that even if you're not targeting multiple threads, accounting for them in this way (NOT the stupid "just put a lock on each object" way) results in much better/simpler code.
Re:OOP Is Dead, Long Live OOP
on Thursday October 18, 2018 @07:20PM (#18253181)
It's because every single article that's promoting ECS does so by comparing it against incorrect inheritance-based code.
The amount of time you see newbies jumping on the ECS bandwagon because inheritance is bad, while they don't yet understand OOP, ECS, procedural, relational, or functional... is infuriating.
Do both. Teach how to use composition. Teach how to use the relational model. Don't avoid teaching either by using misleading sales tactics.
Re:OOP Is Dead, Long Live OOP
on Thursday October 18, 2018 @07:16PM (#18253158)
The fact the the original code is a straw-man is discussed. The fact the flexibility is being removed is discussed too, along with why it was there and hits on better ways to re-achieve it later. It's mentioned that these were going to be covered in a follow-up.
You need to work on your speed reading skills before throwing shade...
Re:OOP Is Dead, Long Live OOP
on Thursday October 18, 2018 @07:12PM (#18253139)
If cross-cutting concerns are making your architecture unwieldy, you likely haven't used composition enough / are doing OOP the bad way (tm).
Re:OOP Is Dead, Long Live OOP
on Thursday October 18, 2018 @07:10PM (#18253123)
Dungeon siege used an "Entity/Component" framework. That's a very different thing to an "Entity/Component/System" framework.