Java tutorial
/* * Copyright (C) 2010 Daniel Waeber <wabu@inf.fu-berlin.de> * * 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. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/> */ package de.javauni.jarcade.model.scene; import com.google.common.base.Function; import com.google.common.base.Predicates; import com.google.common.collect.Iterables; import com.google.inject.Inject; import java.util.NoSuchElementException; import java.util.SortedMap; import java.util.TreeMap; import javax.annotation.Nullable; import de.javauni.jarcade.geom.Bound; import de.javauni.jarcade.geom.immutable.BoundI; import de.javauni.jarcade.model.entities.Entity; import de.javauni.jarcade.model.event.Broadcastor; import de.javauni.jarcade.model.event.Channel; import de.javauni.jarcade.model.scene.event.SceneChangeListener; import de.javauni.jarcade.model.scene.event.ViewportListener; import de.javauni.jarcade.utils.IdList; import de.javauni.jarcade.utils.guice.ManagedScope; /** * @author Daniel Waeber <wabu@inf.fu-berlin.de> */ @ManagedScope public class SceneImpl implements Scene, SceneEdit { private final IdList<Entity> entities; private final SortedMap<Integer, LayerEdit> layers; // XXX when to get t3h zero layer @Nullable private LayerEdit zero; @Nullable private Bound size; private final Channel<SceneChangeListener> chan; private final Viewport view; @Inject public SceneImpl(Channel<SceneChangeListener> chan, Channel<ViewportListener> viewChan) { this.chan = chan; this.entities = new IdList<Entity>(); this.layers = new TreeMap<Integer, LayerEdit>(); this.view = new WholeSceneView(viewChan, this); this.zero = null; } @Override public Bound getWorldSize() { return size; } public void setBounds(float x, float y, float w, float h) { this.size = new BoundI(x, y, w, h); } @Override public Channel<SceneChangeListener> getSceneChannel() { return chan; } @Override public LayerEdit getLayer(int index) { if (!layers.containsKey(index)) { throw new IndexOutOfBoundsException("no layer with index " + index + " in this space"); } return layers.get(index); } @Override public Iterable<? extends LayerEdit> getLayers() { return layers.values(); } @Override public LayerEdit getZeroLayer() { return zero; } @Override public Entity getEntity(int id) { return entities.get(id); } @Override public Iterable<Entity> getAllEntities() { return Iterables.filter(entities, Predicates.notNull()); } @Override public int addLayer(final LayerEdit lay) throws IllegalArgumentException { if (layers.containsKey(lay.getIndex())) { throw new IllegalArgumentException("space already contains a layer with index " + lay.getIndex()); } if (lay.getIndex() == 0) { zero = lay; } layers.put(lay.getIndex(), lay); chan.broadcast(new Broadcastor<SceneChangeListener>() { @Override public void apply(SceneChangeListener l) { l.onLayerAdded(lay); } }); return lay.getIndex(); } @Override public <E extends Entity> E addEntity(Function<Integer, E> construct, final int layerIndex) throws IndexOutOfBoundsException { final LayerEdit layer = getLayer(layerIndex); final E entity = entities.add(construct); layer.add(entity); chan.broadcast(new Broadcastor<SceneChangeListener>() { @Override public void apply(SceneChangeListener l) { l.onEntitySpawned(entity, layer); } }); return entity; } @Override public void moveEntity(final Entity e, int oldLayer, int newLayer) throws NoSuchElementException, IndexOutOfBoundsException { final LayerEdit l1 = getLayer(oldLayer); final LayerEdit l2 = getLayer(newLayer); l1.remove(e); l2.add(e); chan.broadcast(new Broadcastor<SceneChangeListener>() { @Override public void apply(SceneChangeListener l) { l.onEntityLayerChange(e, l1, l2); } }); } @Override public void removeEnity(final Entity e, int layerIndex) throws NoSuchElementException, IndexOutOfBoundsException { final LayerEdit layer = getLayer(layerIndex); layer.remove(e); entities.remove(e); chan.broadcast(new Broadcastor<SceneChangeListener>() { @Override public void apply(SceneChangeListener l) { l.onEntitySpawned(e, layer); } }); } @Override public Viewport getViewport() { return view; } }