Just for the record I haven't read post above (Boreal Games) when I wrote mine - now I did and it seems to be similar in approach to what I wrote in 2).
I can think of at least 3 approaches to this:
1) Registering components in corresponding systems so you don't have to query scene for objects that have component "Position" - system already has list of these components and its updated when object is added/removed from the scene. This is probably good approach if you plan to have hundreds of thousands of objects. Here you need to decide how component knows which system may be interested in having it - this may work on a listener basis where systems "listen" for certain components being either added/removed from object, or objects with components being added/removed from scene.
This approach requires that removing/adding is properly handled so you don't end up with systems keeping components that were removed, or their owners no longer exist.
2) Querying objects that meet component criteria, based on some "key". In my system I'm using a uint64 bit mask - when component is added to object, this objects sets a mask for component's family (family is a group of same-type components, for example Renderable is family sharing common interface that can be derived from to create TerrainRenderable etc.). When component is removed, it clears the mask. This allows me to know exactly what component types belong to a given game object - I don't have to retrieve exact component when I just need to gather objects that have for example Renderable and Spatial component.
When adding component to object:
m_CompMask |= static_cast<uint64_t>(family);
When checking if object has certain components, for example Comp::RENDERABLE and Comp::SPATIAL:
bool HasComponents(uint64_t mask)
{
return (m_CompMask & mask) == mask;
}
if (obj->HasComponents(Comp::RENDERABLE | Comp::SPATIAL))
{
}
This way you can iterate over scene objects quite efficiently checking only bitmask. This still won't scale too well if you plan on having really A LOT of objects.
I use the second approach for scene on client-side where I don't really plan to have more than maybe few hundreds to a couple of thousands objects at any time. But for something like managing all game objects on some online game server side, this can easily go up to hundreds of thousands of objects and may be too slow - this is where I'd look into first method and register components in systems that require them.
3) System-ownership where systems are owners of components - if they own them, they already know about them so no need to query This may be best considering cache friendliness and speed, but gets complicated if there is system that works on more than 1 component - who owns such component then? Because of this I haven't tried this approach. In my case, object owns its components, and scene queries its objects for certain criteria. If I have render system that requires both - SPATIAL and RENDERABLE components on object, it can ask scene for them easily.