20 package net.sf.gridarta.model.baseobject;
22 import java.io.IOException;
23 import java.io.ObjectInputStream;
24 import java.io.Serializable;
25 import java.util.ArrayList;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.ListIterator;
34 import org.jetbrains.annotations.NotNull;
35 import org.jetbrains.annotations.Nullable;
49 @SuppressWarnings(
"ClassReferencesSubclass")
55 private static final long serialVersionUID = 1L;
93 contents =
new ArrayList<>(0);
94 recursive =
new Iterable<G>() {
97 public Iterator<G> iterator() {
102 reverse =
new Iterable<G>() {
105 public Iterator<G> iterator() {
106 return new ReverseIterator<>(contents);
122 return new Iterator<G>() {
128 private final Iterator<G> delegate = contents.iterator();
138 public boolean hasNext() {
139 return delegate.hasNext();
144 current = delegate.next();
145 assert current != null;
150 public void remove() {
151 final G tmp = current;
153 throw new IllegalStateException();
159 if (contents.size() >= 2 && contents.get(0) == tmp) {
160 contents.get(1).propagateElevation(tmp);
163 tmp.setContainer(null, 0, 0);
197 return contents.isEmpty();
207 return contents.isEmpty() ? null : contents.get(0);
217 public G
getPrev(@NotNull
final G gameObject) {
218 final Iterator<G> it = contents.iterator();
219 while (it.hasNext()) {
220 if (it.next() == gameObject) {
221 return it.hasNext() ? it.next() : null;
234 public G
getNext(@NotNull
final G gameObject) {
235 G prevGameObject = null;
236 for (
final G tmpGameObject : contents) {
237 if (tmpGameObject == gameObject) {
238 return prevGameObject;
240 prevGameObject = tmpGameObject;
255 return contents.isEmpty() ? null : contents.get(contents.size() - 1);
265 public void remove(@NotNull
final G gameObject) {
269 if (contents.size() >= 2 && contents.get(0) == gameObject) {
270 contents.get(1).propagateElevation(gameObject);
272 if (!contents.remove(gameObject)) {
275 gameObject.setContainer(null, 0, 0);
286 if (contents.size() <= 0) {
293 gameObject.setContainer(null, 0, 0);
308 public boolean isTop(@NotNull
final G gameObject) {
309 return !contents.isEmpty() && contents.get(contents.size() - 1) == gameObject;
319 public boolean isBottom(@NotNull
final G gameObject) {
320 return !contents.isEmpty() && contents.get(0) == gameObject;
329 public void moveTop(@NotNull
final G gameObject) {
330 final int oldIndex = contents.indexOf(gameObject);
331 if (oldIndex != contents.size() - 1) {
334 if (!contents.remove(gameObject)) {
338 assert contents.size() >= 1;
339 contents.get(0).propagateElevation(gameObject);
341 contents.add(gameObject);
354 public void moveUp(@NotNull
final G gameObject) {
355 final int oldIndex = contents.indexOf(gameObject);
356 if (oldIndex < contents.size() - 1) {
359 if (!contents.remove(gameObject)) {
363 assert contents.size() >= 1;
364 contents.get(0).propagateElevation(gameObject);
366 contents.add(oldIndex + 1, gameObject);
379 public void moveDown(@NotNull
final G gameObject) {
380 final int oldIndex = contents.indexOf(gameObject);
384 if (!contents.remove(gameObject)) {
388 assert contents.size() >= 1;
389 gameObject.propagateElevation(contents.get(0));
391 contents.add(oldIndex - 1, gameObject);
405 final int oldIndex = contents.indexOf(gameObject);
409 if (!contents.remove(gameObject)) {
412 assert contents.size() >= 1;
413 gameObject.propagateElevation(contents.get(0));
414 contents.add(0, gameObject);
428 public void addLast(@NotNull
final G gameObject) {
429 if (gameObject.isInContainer()) {
430 throw new IllegalArgumentException(
"Can't add " + gameObject +
" to " +
this +
" because it's already inside " + gameObject.getContainer());
435 contents.add(gameObject);
436 setThisContainer(gameObject);
437 gameObject.markModified();
450 public void addFirst(@NotNull
final G gameObject) {
451 if (gameObject.isInContainer()) {
452 throw new IllegalArgumentException(
"Can't add " + gameObject +
" to " +
this +
" because it's already inside " + gameObject.getContainer());
457 if (!contents.isEmpty()) {
458 gameObject.propagateElevation(contents.get(0));
460 contents.add(0, gameObject);
461 setThisContainer(gameObject);
462 gameObject.markModified();
477 public void insertAfter(@Nullable
final G previousGameObject, @NotNull
final G gameObject) {
478 if (gameObject.isInContainer()) {
479 throw new IllegalArgumentException(
"Can't add " + gameObject +
" to " +
this +
" because it's already inside " + gameObject.getContainer());
482 if (previousGameObject == null) {
487 if (!previousGameObject.isHead()) {
488 throw new IllegalArgumentException();
493 boolean added =
false;
495 for (
final G tmpGameObject : contents) {
496 if (tmpGameObject.getHead() == previousGameObject) {
498 gameObject.propagateElevation(contents.get(0));
500 contents.add(index, gameObject);
507 throw new IllegalArgumentException(
"Can't add " + gameObject +
" to " +
this +
" because " + previousGameObject +
" is not inside");
509 setThisContainer(gameObject);
510 gameObject.markModified();
523 public void insertBefore(@NotNull
final G gameObject, @Nullable
final G nextGameObject) {
524 if (gameObject.isInContainer()) {
525 throw new IllegalArgumentException(
"Can't add " + gameObject +
" to " +
this +
" because it's already inside " + gameObject.getContainer());
528 if (nextGameObject == null) {
529 addFirst(gameObject);
533 if (!nextGameObject.isHead()) {
534 throw new IllegalArgumentException();
539 final int insertIndex = contents.indexOf(nextGameObject);
540 if (insertIndex == -1) {
541 throw new IllegalArgumentException(
"Can't insert " + gameObject +
" before " + nextGameObject +
" because that isn't inside " +
this);
543 contents.add(insertIndex + 1, gameObject);
544 setThisContainer(gameObject);
545 gameObject.markModified();
558 public void replace(@NotNull
final G oldGameObject, @NotNull
final G newGameObject) {
559 if (oldGameObject.isMulti()) {
560 throw new IllegalArgumentException();
565 final int insertIndex = contents.indexOf(oldGameObject);
566 if (insertIndex == -1) {
569 if (insertIndex == 0) {
570 newGameObject.propagateElevation(oldGameObject);
572 contents.remove(oldGameObject);
573 oldGameObject.setContainer(null, 0, 0);
574 contents.add(insertIndex, newGameObject);
575 setThisContainer(newGameObject);
576 newGameObject.markModified();
594 protected abstract void notifyBeginChange();
599 protected abstract void notifyEndChange();
603 @SuppressWarnings(
"unchecked")
604 protected Object clone() {
610 final G clonedGameObject = gameObject.clone();
611 clone.
contents.add(clonedGameObject);
615 }
catch (
final CloneNotSupportedException e) {
616 assert false :
"This class must be cloneable" + e;
617 throw new AssertionError(e);
623 private void readObject(@NotNull
final ObjectInputStream stream)
throws IOException, ClassNotFoundException {
624 stream.defaultReadObject();
635 if (gameObjectContainer.contents.size() != contents.size()) {
639 for (
int i = 0; i < contents.size(); i++) {
640 if (!gameObjectContainer.contents.get(i).isEqual(contents.get(i))) {
652 protected abstract void setThisContainer(@NotNull G gameObject);
660 public abstract G asGameObject();
665 final StringBuilder sb =
new StringBuilder();
667 final Iterator<G> it = contents.iterator();
669 sb.append(it.next());
670 while (it.hasNext()) {
672 sb.append(it.next());
676 return sb.toString();
703 delegate = list.listIterator(list.size());
708 return delegate.hasPrevious();
712 @SuppressWarnings(
"IteratorNextCanNotThrowNoSuchElementException")
716 return delegate.previous();
720 public void remove() {
721 if (delegate.nextIndex() == 0 && list.size() >= 2) {
722 list.get(1).propagateElevation(list.get(0));
transient Iterable< G > recursive
Iterable implementation for recursive traversal.
Iterable< G > reverse()
Return an object that is the reverse representation.
G getNext(@NotNull final G gameObject)
Return the GameObject succeeding a given game object.
void addLast(@NotNull final G gameObject)
Add the given GameObject at the end of this Container.
boolean isEmpty()
Check whether this square is empty.
void initData()
Initialize the fields.
void insertBefore(@NotNull final G gameObject, @Nullable final G nextGameObject)
Add a GameObject before another.
void removeAll()
Removes all GameObjects from this container.
ReverseIterator(@NotNull final List< T > list)
Create a reverse iterator.
GameObjectContainer()
Create a new GameObjectContainer.
void addFirst(@NotNull final G gameObject)
Add the given GameObject at the end of this Container.
Base class for classes that contain GameObjects as children in the sense of containment.
final ListIterator< T > delegate
The iterator used for delegation.
void moveTop(@NotNull final G gameObject)
Move an item to top.
boolean isTop(@NotNull final G gameObject)
Returns whether this game object is the top-most one.
Base package of all Gridarta classes.
boolean isBottom(@NotNull final G gameObject)
Returns whether this game object is the bottom-most one.
This exception is thrown in case a method of a GameObject without a container or the wrong container ...
Reflects a game object (object on a map).
An iterator for iterating over a list in reverse order.
G getFirst()
Return the first GameObject contained in this container.
GameObjects are the objects based on Archetypes found on maps.
transient Iterable< G > reverse
Iterable implementation for reverse traversal.
void insertAfter(@Nullable final G previousGameObject, @NotNull final G gameObject)
Add a GameObject after another.
Iterator for recursively iterating over GameObjectContainers.
void moveUp(@NotNull final G gameObject)
Move an item up.
Iterator< G > iterator()
The Iterator returned does not recurse, it only contains objects on the first level.
void readObject(@NotNull final ObjectInputStream stream)
void moveDown(@NotNull final G gameObject)
Move an item down.
G getPrev(@NotNull final G gameObject)
Return the GameObject preceding a given game object.
boolean hasSameContents(@NotNull final GameObjectContainer<?, ?, ?> gameObjectContainer)
Compare this object to another game object container.
final List< T > list
The list being iterated over.
List< G > contents
The contents of this container.
abstract void setThisContainer(@NotNull G gameObject)
Sets a GameObject's container to this container.
void replace(@NotNull final G oldGameObject, @NotNull final G newGameObject)
Replace an GameObject with another one.
Iterable< G > recursive()
Return an object that is a recursive representation.
Interface for MapArchObjects.
void moveBottom(@NotNull final G gameObject)
Move an item to bottom.
G getLast()
Return the last GameObject contained in this container.