// ************************************************************** // * * // * Spheres.h -- Version 1.0 * // * * // * (C) Christian Scheideler, 2003 * // * * // ************************************************************** // room for definitions... // -------------------------------------------------------------- // Do not change anything below this line // -------------------------------------------------------------- // Sphere class enables non-blocking method invokation (NMI) class Sphere; // SphereCall can be used for pointing to a Sphere function typedef void (Sphere::*_SphereCall)(void *); // Send adds an event to the event queue ES #define Send(SpherePtr, Method, ParList) \ _ES->Add(new _Event(dynamic_cast(SpherePtr), (_SphereCall) &Method, (void*) ParList)) // Simulate starts the simulation for time many rounds #define Simulate(time) \ _ES->Run(time) // definition of class Sphere class Sphere { public: // Call performs calls to methods in classes derived from Sphere virtual void Call(_SphereCall CallPtr, void* PListPtr) { (this->*CallPtr)(PListPtr); } }; // An Event stores a NMI request for a Sphere object class _Event { public: Sphere *SpherePtr; // pointer to Sphere to be activated _SphereCall CallPtr; // function within ID to be called void *PListPtr; // pointer to parameter list _Event *next; // next event in event list _Event(Sphere *s, _SphereCall c, void *pl) { SpherePtr = s; CallPtr = c; PListPtr = pl; next = NULL; } }; // The Scheduler inserts Events and executes them in the order of their time class _Scheduler { private: _Event *_OldEvents; // pointer to list of current events _Event *_NewEvents; // pointer to list of new events _Event *_NewEnd; // pointer to last event in new event list public: _Scheduler() { _OldEvents = NULL; _NewEvents = NULL; _NewEnd = NULL; } // Add adds a new event to the new events list void Add(_Event *e) { if (_NewEvents == NULL) _NewEvents = e; else _NewEnd->next = e; _NewEnd = e; } // Remove removes an event from the old events list _Event *Remove() { _Event *e = _OldEvents; _OldEvents = _OldEvents->next; return e; } // Run executes the RMI requests until the queue is empty or time is reached void Run(long time) { _Event *e; long t; t=1; while (t<=time && _NewEvents != NULL) { _OldEvents = _NewEvents; _NewEvents = NULL; _NewEnd = NULL; while (_OldEvents != NULL) { e = Remove(); (e->SpherePtr)->Call(e->CallPtr, e->PListPtr); delete e; } t++; } } }; // ES is the object handling the RMI requests _Scheduler *_ES = new _Scheduler();