See:
- The class definition simagent.h
- The description Agents
<project-file type=“source”/>
<content> #include “simagent.h” #include “simprocess.h”
#include <iostream> #define DEBUG SimAgent::SimAgent(SimID id) : SimSchedule(SIM_INFINITY) { ID=id; } SimAgent::~SimAgent() { if (Owner != NULL) Owner→removeAgent(this); size_t n = Agents.size(); if (n > 0) { size_t i = n - 1; while (true) { SimAgent *a=Agents[i]; removeAgent(a); delete a; if (i == 0) break; i–; } } for (std::list<SimAgentManager*>::iterator i = Managers.begin(); i != Managers.end(); i++) delete *i; clear(); } void SimAgent::addManager(SimAgentManager *manager) { if (manager == NULL) return; std::list<SimAgentManager*>::iterator i; for (i = Managers.begin(); i != Managers.end() && (*i) != manager; i++); if (i == Managers.end()) Managers.push_back(manager); int n=Agents.size(); for (int i=0; i<n; i++) manager→addAgent(agent(i)); manager→setOwner(this); } void SimAgent::removeManager(SimAgentManager *manager) { if (manager == NULL) return; std::list<SimAgentManager*>::iterator i; for (i = Managers.begin(); i != Managers.end() && (*i) != manager; i++); if (i != Managers.end()) Managers.erase(i); manager→setOwner(NULL); int n=Agents.size(); for (int i=0; i<n; i++) manager→removeAgent(agent(i)); } void SimAgent::addAgent(SimAgent *agent) { if (agent == NULL || agent→Owner != NULL) return; agent→Index = Agents.size(); Agents.push_back(agent); schedule(agent); for (std::list<SimAgentManager*>::iterator i = Managers.begin(); i != Managers.end(); i++) (*i)→addAgent(agent); } void SimAgent::removeAgent(SimAgent *agent) { int n; n=Agents.size(); if (agent == NULL || agent→Owner != this) return; unschedule(agent); SimAgent *last = Agents.back(); Agents[agent→Index] = last; last→Index = agent→Index; Agents.pop_back(); for (std::list<SimAgentManager*>::iterator i = Managers.begin(); i != Managers.end(); i++) { (*i)→removeAgent(agent); (*i)→agentChangedIndex(Agents.size(), agent→Index); } } void SimAgent::die(SimProcess *proc) { if (Owner != NULL) Owner→removeAgent(this); if (proc != NULL) proc→unregisterAgent(this); } void SimAgent::schedule(SimSchedule *e) { if nothing to add, do nothing
if (e == NULL) return; float Time = e->eventTime(); if (e->Owner != NULL && (e->Owner != this || e->EventIndex != Events.end())) e->Owner->unschedule(e); if (e->Owner == NULL) e->Owner = this; if (isInfinity(Time)) { e->EventIndex = Events.end(); return; } e->EventIndex = Events.insert(std::pair<float, SimSchedule*>(Time, e)); setEventTime(Events.begin()->second->eventTime());
}
void SimAgent::unschedule(SimSchedule *e) {
// if nothing to unschedule, do nothing if (e == NULL || e->Owner == NULL || e->Owner != this) return; e->Owner = NULL; // if e is not in the event list, no need to remove it from the list if (e->EventIndex == Events.end()) return; Events.erase(e->EventIndex); e->EventIndex = Events.end(); if (Events.empty()) setEventTime(SIM_INFINITY); else setEventTime(Events.begin()->second->eventTime());
}
void SimAgent::clear() {
std::multimap<float, SimSchedule*>::iterator i; for (i = Events.begin(); i != Events.end(); i++) { i->second->Owner = NULL; delete i->second; } Events.clear(); setEventTime(SIM_INFINITY);
}
void SimAgent::handler(float Time, SimProcess *process) {
if (Events.empty()) return; SimSchedule *e = Events.begin()->second; e->handler(Time, process); // recurrent event is expected to reschedule it self if (e->Owner == NULL) delete e;
}
/* SimAgentManager */
SimAgentManager::SimAgentManager() {
Owner = NULL;
}
SimAgentManager::~SimAgentManager() { }
SimChangeOwnerEvent::SimChangeOwnerEvent(float time, SimID newowner, SimDistribution *rep)
: SimSchedule(time)
{
NewOwner = newowner; Repetition = rep;
}
SimChangeOwnerEvent::~SimChangeOwnerEvent() {
if (Repetition != NULL) delete Repetition;
}
void SimChangeOwnerEvent::handler(float time, SimProcess *proc) {
if (owner() == NULL) return; if (owner()->owner() != NULL) owner()->owner()->removeAgent(owner()); SimAgent *newowner = proc->agentWithID(NewOwner); if (newowner != NULL) newowner->addAgent(owner()); if (proc != NULL) proc->log(time, owner(), this); if (newowner == NULL) proc->addAgent(owner()); if (Repetition != NULL) { // explicitly request for rescheduling setEventTime(Repetition->draw()+time); owner()->schedule(this); } else owner()->unschedule(this);
}
SimDieEvent::SimDieEvent(float time)
: SimSchedule(time)
{ }
SimDieEvent::~SimDieEvent() { }
void SimDieEvent::handler(float time, SimProcess *proc) {
owner()->die(proc); if (proc != NULL) proc->log(time, owner(), this);
} </content> <use name=“simagent.h”/>