I'm trying to create an entity/component system that automatically matches suitable entities suitable systems. I'm using std::bitset and RTTI to automatically assign a bit value to every component type.

A system is defined like this: MovementSystem : System<Position, Velocity>.

MovementSystem, in this example, accepts any entity that has both the Position and the Velocity components (and any other component).

To check if an entity is suitable, I compare the system's bitset to the entity's bitset.

It seems to work, but I found it after doodling bitsets on a whiteboard. Is it correct? Can it be improved any further? (Entities will be created and destroyed an immense amount of times in my games, so performance is very important!)

Code is here if needed (shouldn't be), but it's almost impossible to read.

@SJuan76: I tried messing around with XOR but couldn't get it to work. Should I XOR the entity bitset with the system bitset or viceversa? And should I .all() or .any() the XOR result?
– Vittorio RomeoOct 8 '13 at 21:20

@VittorioRomeo sorry I think I misread it
– aaronmanOct 8 '13 at 21:20

1 Answer
1

checks whether b is a subset of a, or equivalent, whether a contains/includes b. Note that you are creating one temporary followed by the break-early operator==.

This is equivalent to checking whether the difference of b and a is empty (note the order!)

(b & ~a).none();

This will be equally fast: a temporary followed by a break-early .none()

Given the interface of std::bitset, this is as fast you can get. The problem with std::bitset is that all its bitwise members (&, |, ^ and ~ loop over every word. The early termination operations like none(), any(), == or <, cannot be intertwined with them. This is because std::bitset does not expose the underyling word storage so you cannot perform the iteration yourself.

However, if you would write your own bitset class, you could write a special-purpose includes() algorithm that loops over each of the words, doing the & until you break-early

A similar algorithm missing from std::bitset would be intersects(), to efficiently test a & b != 0. Currently you have to first do bitwise and, and then the test for zero, whereas that would be more efficiently done in one loop. If std::bitset ever gets updated, it would be nice if they include includes() and intersects() primitives.

I know it has an equality operator. My question is about the correctness of my solution and possible ways of improving it. In fact, I already use the equality operator in my solution: if(entityBitset & systemBitset) == systemBitset))
– Vittorio RomeoOct 8 '13 at 21:23