Hi,
opposite to the post you linked, you actually *want* a synchronous operation (and with a reason). As a consequence... here's how to do it.
The problem is this. Assume that you have the following code:
Simulator::Schedule (Seconds (1.0), &AdvancePosition, nodeA);
Simulator::Schedule (Seconds (1.0), &AdvancePosition, nodeB);
What's the first node who will advance its position? Totally random (as you noticed).
For real it isn't random, but practically it is.
There are basically two solutions: 1) time advancement and 2) dirty trick.
The "clean" solution (i.e., priority scheduling) is not feasible for a number of reasons. Mostly lack of generality.
The "Time advancement" is based on this. Let's assume that the time is measured in nanoseconds. You can divide the time in a different way, i.e., use nanosecond but think in terms of deca-nanoseconds (i.e., loose one decimal precision).
In this way you can "trick" the simulator to precisely schedule the events in the order you want.
Let's do an example, using seconds and 10th of seconds as time reference.
- Event 1 at time 1.1
- Event 2 at time 1.2
BOTH events will be considered as executed at Time 2.0 (note, you have to advance your timer), and the first will happen before the second.
This method is quite complex, and it requires to carefully consider all the time operations, applying the proper rounding where necessary. I'd classify it as "mostly an academic thing", at least until the Time class will not provide an unified way to split the "Time" between a time and a priority representation.
And this leads to the second option: the trick.
The trick is... don't schedule two events, schedule ONE event :)
Consider this: the following instruction:
Simulator::Schedule (Seconds (1.0), &AdvancePosition, nodeA);
means:
1) Simulator, advance the time. When 1 second is passed, please do this for me:
nodeA->AdvancePosition();
An event is a deferred function call.
If you look at it in this way, you can do this:
1) call a method (a single one) in due time and
2) have it call the receivers in the proper order by directly invoking the right functions.
This will force the right "event" ordering.... by avoiding events.
The bad part of this is that you'll loose all the fancy things of Events (for this particular case), like logging and so on.
There are a number of ways to do this trick. E.g., create a single "channel" instance between all the nodes, and have it arbitrate the messages. Alternatively, don't use events in your channel and have the source handle the delay. Many alternatives, but all share one thing: don't use Events (just for this particular thing).
Hope this helps,
T.