0

Say at run-time I establish some events with occurrence times. Now I have certain entities in the system and I need to establish which entities were impacted by these events.

So as an example say that I have:

  • Entity1 intialized at time 1
  • EventRed occurs at time 3
  • Entity2 initialized at time 8
  • EventBlue occurs at time 9
  • EventYellow occurs at time 11
  • Entity3 initialized at time 13

This should result in:

  • Entity1 is white
  • Entity2 is green
  • Entity3 is black

I want a case-like control structure to do this which supports fall through and who's cases are evaluated as "greater than or equal to this value". I'd like syntax like this:

for(auto& i : Entity) {
    ?switch(i.GetInitializedTime()) {
    ?case(Red.GetOccuranceTime()):
        i.AddRed();
    ?case(Blue.GetOccranceTime()):
        i.AddBlue();
    ?case(Yellow.GetOccuranceTime()):
        i.AddYellow();
    }
}

Is there a control structure like this or do I have to juggle all the if statements?

Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288

2 Answers2

1

There's nothing that is even remotely like what you need. You'll have to write your own class for this. Practically speaking, it looks like a sorted vector of <time, function> pairs.

Even the GCC "range extension" of the switch statement takes fixed ranges.

MSalters
  • 173,980
  • 10
  • 155
  • 350
0

When the event times are not known at design time, even gcc's range based case statements are not viable solutions. As such the best solution is to contain the events in a map.

Because in the original question an event was only a number that caused a specific method to be called on the entity, this process can be simplified by eleminating the event object; having the map use the number which would have been contained by the event look up the entity method it would have called. For example: map<int, function<void(entity&)>> events can be populated by:

events[3] = mem_fn(&entity::AddRed);
evnets[9] = mem_fn(&entity::AddBlue);
events[11] = mem_fn(&entity::AddYellow);

Once events has been populated, the case statement can be replaced with iterating through events, beginning at entity i's GetInitializedTime():

for(auto j = events.upper_bound(i.GetInitializedTime()); j != events.end(); ++j) {
    j->second(i);
}

upper_bound is used to find the beginning iterator this since it:

Returns an iterator pointing to the first element that is greater than key

This live example uses the functionality above, but in order to showcase that it uses bitwise array indexing. When indexing entity::colorArray the least significant bit is a boolean for whether blue has been added, the middle bit is yellow, and the most significant bit is red.

Community
  • 1
  • 1
Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288