How to Write Simulations with MiniscSim
Event-based Simulation
This section refers to the atikokan version of the source.In this approach, the interface (API) of the appplication to the scheduler is expressed through Events. These events are objects, which are given to the scheduler with the
Schedule function. This call specifies the
event to schedule, and when to schedule it.
The scheduler, at the specified simulation time, dispatches the
event, by calling the Event::Happen() function. This looks pretty simple in C++. You can declare a class
FishEat,
which is an event, calling the Eatfunction of a Fish
object, and then schedule this new kind of event:
class Fish {
...
void Eat(Worm& w);
};
...
class FishEat: public Event {
public:
FishEat (Fish * f, Worm& wrm):pFish(f),myWorm(wrm){}
Happen() { pFish->Eat(myWorm);}
private:
Fish * pFish;
Worm& myWorm;
};
...
Worm Dennis; Fish Nemo;
...
FishEat Lunch (&Nemo,Dennis);
S.Schedule (&Lunch,SimTime(1130));
Or, you can simply schedule a function call. Although this is less interesting, seeing that the function can't take any parameters. For some purposes, its still useful, e.g.
void Krasch(){ ... /* bring down system */...)
...
Scheduler Vindoss();
...
Vindoss.Schedule (Krasch,SimTime(1700));
...
Fish,
they can use the same FishEat event, provided that Eat is
either the same for all of them, or it is a virtual function (which is why the
first argument of the FishEat constructor is a pointer, not a reference).
Caveat
The scheduler doesn't help you in managing your event objects, other than
making the function calls you want. Used as in the example, the
event object data members are set when the constructor is called, and used
when the scheduler calls Happen. You can change the values between
those times if you want. It can make for interesting, timing dependent
behaviour, and that might be just want you want the simulation for.
Or, it could be a bug you have a hard time tracking down.
You also have to manage allocation and deallocation of event objects
yourself. So if you do something funky, like
S.Schedule(new FishEat(&Nemo,Dennis))
you can introduce memory leaks quite conveniently, so be careful.
Entity-based Simulation
Note that this describes the original release. The "atikokan" version is described above.We will have some number of initial starting points for this interface, to consider some alternative approaches. They have (meaningless) names, so they can be correlated with file releases. Generally speaking, it can help if you read the header files of the code release. Here are hints about how to use the first one:
In a first version, we have Entities. These are persistent things, like an individual fish in a aquarium simulation, or a single computer in a network simulation. Or a trade union in an economic simulation. These occasionally wake up and do something.
To model this, there is a base class Entity, and
you derive your own class from Entity,
and implement a Entity::Wakeup function.
Then, you allocate a Scheduler (or more than one), and schedule waking up the entities with calls to
Scheduler::WakeupAt. Call one of the Scheduler::Run
methods to start the scheduler, and it will wake up entities at it has been told.
What do the entities do when they wake up? Mostly, that's up to
the application, the scheduler doesn't care. However, a useful
thing to do is schedule one's next wakeup,
with a Scheduler::WakeupAt(this,time) call. Or
Scheduler::WakeupIn(...) works similarly.
Entities can wake up other entities, not just themselves.
Anyone can call Entity::Wakeup, not just a scheduler.
An entity can contain a scheduler, but it cannot be one directly. This has not been tested, so your mileage may vary.
