Java tutorial
/********************************************************************************************* * * 'GamlAgent.java, in plugin msi.gama.core, is part of the source code of the GAMA modeling and simulation platform. * (c) 2007-2016 UMI 209 UMMISCO IRD/UPMC & Partners * * Visit https://github.com/gama-platform/gama for license information and developers contact. * * **********************************************************************************************/ package msi.gama.metamodel.agent; import java.util.Arrays; import java.util.List; import com.google.common.collect.Iterables; import msi.gama.metamodel.population.GamaPopulation; import msi.gama.metamodel.population.IPopulation; import msi.gama.metamodel.population.MetaPopulation; import msi.gama.metamodel.shape.IShape; import msi.gama.runtime.IScope; import msi.gama.runtime.exceptions.GamaRuntimeException; import msi.gama.util.GamaListFactory; import msi.gama.util.GamaMap; import msi.gama.util.GamaMapFactory; import msi.gama.util.IContainer; import msi.gama.util.IList; import msi.gama.util.graph.GamaGraph; import msi.gaml.descriptions.ModelDescription; import msi.gaml.species.ISpecies; import msi.gaml.types.Types; import msi.gaml.variables.IVariable; /** * The Class GamlAgent. Represents agents that can be manipulated in GAML. They are provided with everything their * species defines . */ @SuppressWarnings("unchecked") public class GamlAgent extends MinimalAgent implements IMacroAgent { // hqnghi manipulate micro-models AD put it to null to have lazy // initialization (saves some bytes in each agent) protected GamaMap<String, IPopulation<? extends IAgent>> externMicroPopulations; // Added to optimize the traversal of "non-minimal" agents that contain // micropopulations protected IPopulation<? extends IAgent>[] microPopulations; static final IPopulation<? extends IAgent>[] NO_POP = new IPopulation[0]; // end-hqnghi /** * @param s * the population used to prototype the agent. */ public GamlAgent(final IPopulation<? extends IAgent> s) { super(s); } /** * @param gridPopulation * @param geometry */ public GamlAgent(final IPopulation<? extends IAgent> gridPopulation, final IShape geometry) { super(gridPopulation, geometry); } private Boolean isPopulation(final String name) { final IVariable v = getSpecies().getVar(name); if (v == null) return false; if (v.isMicroPopulation()) return true; return false; } @Override public IPopulation<? extends IAgent>[] getMicroPopulations() { if (getAttributes() == null) { return NO_POP; } if (microPopulations == null) { microPopulations = Iterables.toArray( Iterables.transform(Iterables.filter(getAttributes().keySet(), input -> isPopulation(input)), input -> (IPopulation<?>) getAttributes().get(input)), IPopulation.class); if (microPopulations.length == 0) microPopulations = NO_POP; Arrays.sort(microPopulations, (p1, p2) -> p1.isGrid() ? p2.isGrid() ? 0 : 1 : p2.isGrid() ? -1 : 0); } return microPopulations; } @Override protected boolean stepSubPopulations(final IScope scope) { for (final IPopulation<? extends IAgent> pop : getMicroPopulations()) { if (!scope.step(pop).passed()) return false; } return true; } @Override public IList<IAgent> captureMicroAgents(final IScope scope, final ISpecies microSpecies, final IList<IAgent> microAgents) throws GamaRuntimeException { if (microAgents == null || microAgents.isEmpty() || microSpecies == null || !this.getSpecies().getMicroSpecies().contains(microSpecies)) { return GamaListFactory.create(); } final List<IAgent> candidates = GamaListFactory.create(Types.AGENT); for (final IAgent a : microAgents.iterable(scope)) { if (this.canCapture(a, microSpecies)) { candidates.add(a); } } final IList<IAgent> capturedAgents = GamaListFactory.create(Types.AGENT); final IPopulation<? extends IAgent> microSpeciesPopulation = this.getPopulationFor(microSpecies); for (final IAgent micro : candidates) { final SavedAgent savedMicro = new SavedAgent(scope, micro); micro.dispose(); capturedAgents.add(savedMicro.restoreTo(scope, microSpeciesPopulation)); } return capturedAgents; } @Override public IAgent captureMicroAgent(final IScope scope, final ISpecies microSpecies, final IAgent microAgent) throws GamaRuntimeException { if (this.canCapture(microAgent, microSpecies)) { final IPopulation<? extends IAgent> microSpeciesPopulation = this.getMicroPopulation(microSpecies); final SavedAgent savedMicro = new SavedAgent(scope, microAgent); microAgent.dispose(); return savedMicro.restoreTo(scope, microSpeciesPopulation); } return null; } @Override public IList<IAgent> releaseMicroAgents(final IScope scope, final IList<IAgent> microAgents) throws GamaRuntimeException { IPopulation<? extends IAgent> originalSpeciesPopulation; final IList<IAgent> releasedAgents = GamaListFactory.create(Types.AGENT); for (final IAgent micro : microAgents.iterable(scope)) { final SavedAgent savedMicro = new SavedAgent(scope, micro); originalSpeciesPopulation = micro.getPopulationFor(micro.getSpecies().getParentSpecies()); micro.dispose(); releasedAgents.add(savedMicro.restoreTo(scope, originalSpeciesPopulation)); } return releasedAgents; } /** * Migrates some micro-agents from one micro-species to another micro-species of this agent's species. * * @param microAgent * @param newMicroSpecies * @return */ @Override public IList<IAgent> migrateMicroAgents(final IScope scope, final IList<IAgent> microAgents, final ISpecies newMicroSpecies) { final List<IAgent> immigrantCandidates = GamaListFactory.create(Types.AGENT); for (final IAgent m : microAgents.iterable(scope)) { if (m.getSpecies().isPeer(newMicroSpecies)) { immigrantCandidates.add(m); } } final IList<IAgent> immigrants = GamaListFactory.create(Types.AGENT); if (!immigrantCandidates.isEmpty()) { final IPopulation<? extends IAgent> microSpeciesPopulation = this.getPopulationFor(newMicroSpecies); for (final IAgent micro : immigrantCandidates) { final SavedAgent savedMicro = new SavedAgent(scope, micro); micro.dispose(); immigrants.add(savedMicro.restoreTo(scope, microSpeciesPopulation)); } } return immigrants; } /** * Migrates some micro-agents from one micro-species to another micro-species of this agent's species. * * @param microAgent * @param newMicroSpecies * @return */ @Override public IList<IAgent> migrateMicroAgents(final IScope scope, final ISpecies oldMicroSpecies, final ISpecies newMicroSpecies) { final IPopulation<? extends IAgent> oldMicroPop = this.getPopulationFor(oldMicroSpecies); final IPopulation<? extends IAgent> newMicroPop = this.getPopulationFor(newMicroSpecies); final IList<IAgent> immigrants = GamaListFactory.create(Types.AGENT); // final Iterator<IAgent> it = oldMicroPop.iterator(); while (!oldMicroPop.isEmpty()) { // while (it.hasNext()) { final IAgent m = oldMicroPop.get(0); final SavedAgent savedMicro = new SavedAgent(scope, m); m.dispose(); immigrants.add(savedMicro.restoreTo(scope, newMicroPop)); } return immigrants; } @Override public void initializeMicroPopulation(final IScope scope, final String name) { final ISpecies microSpec = getModel().getSpecies(name); final IPopulation<? extends IAgent> microPop = GamaPopulation.createPopulation(scope, this, microSpec); // System.out.println("Micro-pop added to attributes: " + name); setAttribute(microSpec.getName(), microPop); microPop.initializeFor(scope); } @SuppressWarnings("rawtypes") @Override public void dispose() { if (dead) { return; } final IPopulation[] microPops = getMicroPopulations(); for (final IPopulation pop : microPops) { pop.dispose(); } final Object graph = getAttribute("attached_graph"); if (graph instanceof GamaGraph) { ((GamaGraph) graph).disposeVertex(this); } super.dispose(); } @Override public synchronized IPopulation<? extends IAgent> getMicroPopulation(final String microSpeciesName) { if (getAttributes() == null) { return null; } final Object o = getAttributes().get(microSpeciesName); if (o instanceof IPopulation) return (IPopulation<? extends IAgent>) o; return null; } @Override public IPopulation<? extends IAgent> getMicroPopulation(final ISpecies microSpecies) { if (getAttributes() == null) { return null; } final Object o = getAttributes().get(microSpecies.getName()); return o instanceof IPopulation ? (IPopulation<IAgent>) o : null; } @Override public boolean hasMembers() { if (dead() || getAttributes() == null) { return false; } for (final Object pop : getAttributes().getRawValues()) { if (pop instanceof IPopulation && ((IPopulation<? extends IAgent>) pop).size() > 0) { return true; } } return false; } @Override public IContainer<?, IAgent> getMembers(final IScope scope) { if (dead() || getAttributes() == null) { return GamaListFactory.create(); } final MetaPopulation mp = new MetaPopulation(); for (final Object pop : getAttributes().values()) { if (pop instanceof IPopulation && ((IPopulation<? extends IAgent>) pop).size() > 0) { mp.addPopulation((IPopulation<? extends IAgent>) pop); } } return mp; } @Override public void setMembers(final IList<IAgent> newMembers) { // Directly changing "members" not supported } /* * Returns the number of agents for which this agent is the direct host */ @Override public int getMembersSize(final IScope scope) { int result = 0; for (final Object pop : getAttributes().values()) { if (pop instanceof IPopulation) { result += ((IPopulation<? extends IAgent>) pop).length(scope); } } return result; } @Override public void setAgents(final IList<IAgent> agents) { // "agents" is read-only attribute } @Override public IList<IAgent> getAgents(final IScope scope) { if (!hasMembers()) { return GamaListFactory.create(); } final IContainer<?, IAgent> members = getMembers(scope); final IList<IAgent> agents = GamaListFactory.create(Types.AGENT); agents.addAll(members.listValue(scope, Types.NO_TYPE, false)); for (final IAgent m : members.iterable(scope)) { if (m != null && m instanceof IMacroAgent) { agents.addAll(((IMacroAgent) m).getAgents(scope)); } } return agents; } @Override public IPopulation<? extends IAgent> getPopulationFor(final ISpecies species) { // hqnghi adjust to get population for species which come from main as // well micro models final ModelDescription micro = species.getDescription().getModelDescription(); final ModelDescription main = (ModelDescription) this.getModel().getDescription(); IPopulation<? extends IAgent> microPopulation = null; if (main.getMicroModel(micro.getAlias()) == null) { microPopulation = this.getMicroPopulation(species); if (microPopulation == null && getHost() != null) { microPopulation = getHost().getPopulationFor(species); } } else { microPopulation = this.getExternMicroPopulationFor(micro.getAlias() + "." + species.getName()); } // end-hqnghi return microPopulation; } @Override public IPopulation<? extends IAgent> getPopulationFor(final String speciesName) { final IPopulation<? extends IAgent> microPopulation = this.getMicroPopulation(speciesName); if (microPopulation == null && getHost() != null) { return getHost().getPopulationFor(speciesName); } return microPopulation; } /** * Verifies if this agent can capture other agent as newSpecies. * * @return true if the following conditions are correct: 1. newSpecies is one micro-species of this agent's species; * 2. newSpecies is a sub-species of this agent's species or other species is a sub-species of this agent's * species; 3. the "other" agent is not macro-agent of this agent; 4. the "other" agent is not a micro-agent * of this agent. */ @Override public boolean canCapture(final IAgent other, final ISpecies newSpecies) { if (other == null || other.dead() || newSpecies == null || !this.getSpecies().containMicroSpecies(newSpecies)) { return false; } if (this.getMacroAgents().contains(other)) { return false; } if (other.getHost().equals(this)) { return false; } return true; } @Override public void addExternMicroPopulation(final String expName, final IPopulation<? extends IAgent> pop) { if (externMicroPopulations == null) { externMicroPopulations = GamaMapFactory.create(Types.STRING, Types.LIST.of(Types.AGENT)); } externMicroPopulations.put(expName, pop); } @Override public IPopulation<? extends IAgent> getExternMicroPopulationFor(final String expName) { if (externMicroPopulations != null) { return externMicroPopulations.get(expName); } return null; } // // @Override // public GamaMap<String, IPopulation<? extends IAgent>> // getExternMicroPopulations() { // if (externMicroPopulations == null) { // return GamaMapFactory.create(); // } // return externMicroPopulations; // } // @Override // public int getNbAgents() { // return nbSubAgents; // } // // @Override // public void addSubAgents(final int nb) { // nbSubAgents += nb; // } // // @Override // public void removeAgent() { // nbSubAgents--; // } }