/* * JABM - Java Agent-Based Modeling Toolkit * Copyright (C) 2013 Steve Phelps * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. */ package net.sourceforge.jabm.agent; import java.io.Serializable; import net.sourceforge.jabm.EventScheduler; import net.sourceforge.jabm.event.AgentArrivalEvent; import net.sourceforge.jabm.event.RoundStartingEvent; import net.sourceforge.jabm.event.SimEvent; import net.sourceforge.jabm.event.SimulationFinishedEvent; import net.sourceforge.jabm.strategy.Strategy; /** * An abstract superclass for JABM agents which provides default event-handling * functionality implementing several methods in the <code>Agent</code> * interface. The only requirement for an object to model a JABM agent is that * it implement the <code>Agent</code> interface; agents do not have to subclass * <code>AbstractAgent</code>. * * @author Steve Phelps * */ public abstract class AbstractAgent implements Serializable, Agent { protected boolean interacted; /** * The event scheduler used to fire events originating from this agent. */ protected EventScheduler scheduler; protected Strategy strategy; public AbstractAgent(EventScheduler scheduler) { super(); this.scheduler = scheduler; if (scheduler != null) { subscribeToEvents(); } } public AbstractAgent() { super(); } /** * Subscribe to the specific events that we are interested in. */ public void subscribeToEvents() { scheduler.addListener(AgentArrivalEvent.class, this); scheduler.addListener(SimulationFinishedEvent.class, this); scheduler.addListener(RoundStartingEvent.class, this); Strategy strategy = getStrategy(); if (strategy != null) { strategy.subscribeToEvents(scheduler); } } public void unsubscribeFromEvents() { scheduler.removeListener(this); } @Override public void eventOccurred(SimEvent event) { if (event instanceof AgentArrivalEvent) { AgentArrivalEvent arrivalEvent = (AgentArrivalEvent) event; if (arrivalEvent.getSubject() == this) { onAgentArrival((AgentArrivalEvent) event); } } else if (event instanceof SimulationFinishedEvent) { onSimulationFinished((SimulationFinishedEvent) event); } else if (event instanceof RoundStartingEvent) { onRoundStarting((RoundStartingEvent) event); } } public void onSimulationFinished(SimulationFinishedEvent event) { unsubscribeFromEvents(); } public void onRoundStarting(RoundStartingEvent event) { interacted = false; } public void fireEvent(SimEvent event) { scheduler.fireEvent(event); } public EventScheduler getScheduler() { return scheduler; } @Override public void setScheduler(EventScheduler scheduler) { this.scheduler = scheduler; // Once we have a reference to the scheduler, subscribe // to the events that our agent is interested in. subscribeToEvents(); } public double getPayoffDelta() { return 0.0; } /** * This method is called whenever an agent arrives at the * simulation. The default behaviour is to execute the * agent's strategy. */ public void onAgentArrival(AgentArrivalEvent event) { strategy.execute(event.getObjects()); interacted = true; } @Override public boolean isInteracted() { return interacted; } public Strategy getStrategy() { return strategy; } /** * Configure the strategy for this agent. */ public void setStrategy(Strategy strategy) { this.strategy = strategy; strategy.setAgent(this); } }