I hope you don't mind a bit more discussion on ECS.
Overall, our implementations of ECS seem pretty similar.
One minor, although significant difference is that you store a vector/array of
pointers to components. That will be totally fine for a game which doesn't have a huge number of entities/components operating at once, as looks to be the case with your game, given that it works screen by screen.
For a game that does process a huge number of entities at once, say a large, dynamic, open world game with entities that continue to operate while off-screen, you would lose some performance because of the pointers. It's a cache miss problem, because while the pointers are arranged sequentially in memory, the actual component data is not. So when a system iterates over an array of components, it's jumping all over memory.
It's more optimal to store a straight up array of components, not component pointers. i.e.
class ComponentSystem
{
private:
// not this:
// std::vector<Component*> m_components;
// but this:
std::vector<Component> m_components;
};
Then, when you iterate over m_components, it's all sequential memory, which is really fast. The biggest problem with this approach is that when m_components grows, as can happen when you add new elements, two tricky things happen:
1. It invalidates any Component pointers or references which may currently be in use by your gamesystem code, since the vector moves in memory. This can lead to some nasty dangling pointer/reference bugs if you're not very careful about when you add components to the vector, in relation to when you operate on components within the vector.
2. It calls constructors and destructors on every component in the vector, which can lead to unintended consequences if you treat your constructors and destructors as meaning the entity/component is being created and destroyed in a gameplay sense.
Bottom line, arrays of pointers are easier (avoiding the problems above), provide all the flexibility of an ECS, and work great for most games. They do lose some of the performance benefits of an ECS, but that's only important for a few kinds of massive, open world games. So this is not a critique of your approach at all (it seems really good!), just some of the thoughts I've had.