Home | History | Annotate | Download | only in utils
      1 /*******************************************************************************
      2  * Copyright 2011 See AUTHORS file.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *   http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  ******************************************************************************/
     16 
     17 package com.badlogic.gdx.utils;
     18 
     19 import java.util.Comparator;
     20 
     21 /** Queues any removals done after {@link #begin()} is called to occur once {@link #end()} is called. This can allow code out of
     22  * your control to remove items without affecting iteration. Between begin and end, most mutator methods will throw
     23  * IllegalStateException. Only {@link #removeIndex(int)}, {@link #removeValue(Object, boolean)}, and add methods are allowed.
     24  * <p>
     25  * Code using this class must not rely on items being removed immediately. Consider using {@link SnapshotArray} if this is a
     26  * problem.
     27  * @author Nathan Sweet */
     28 public class DelayedRemovalArray<T> extends Array<T> {
     29 	private int iterating;
     30 	private IntArray remove = new IntArray(0);
     31 
     32 	public DelayedRemovalArray () {
     33 		super();
     34 	}
     35 
     36 	public DelayedRemovalArray (Array array) {
     37 		super(array);
     38 	}
     39 
     40 	public DelayedRemovalArray (boolean ordered, int capacity, Class arrayType) {
     41 		super(ordered, capacity, arrayType);
     42 	}
     43 
     44 	public DelayedRemovalArray (boolean ordered, int capacity) {
     45 		super(ordered, capacity);
     46 	}
     47 
     48 	public DelayedRemovalArray (boolean ordered, T[] array, int startIndex, int count) {
     49 		super(ordered, array, startIndex, count);
     50 	}
     51 
     52 	public DelayedRemovalArray (Class arrayType) {
     53 		super(arrayType);
     54 	}
     55 
     56 	public DelayedRemovalArray (int capacity) {
     57 		super(capacity);
     58 	}
     59 
     60 	public DelayedRemovalArray (T[] array) {
     61 		super(array);
     62 	}
     63 
     64 	public void begin () {
     65 		iterating++;
     66 	}
     67 
     68 	public void end () {
     69 		if (iterating == 0) throw new IllegalStateException("begin must be called before end.");
     70 		iterating--;
     71 		if (iterating == 0) {
     72 			for (int i = 0, n = remove.size; i < n; i++)
     73 				removeIndex(remove.pop());
     74 		}
     75 	}
     76 
     77 	private void remove (int index) {
     78 		for (int i = 0, n = remove.size; i < n; i++) {
     79 			int removeIndex = remove.get(i);
     80 			if (index == removeIndex) return;
     81 			if (index < removeIndex) {
     82 				remove.insert(i, index);
     83 				return;
     84 			}
     85 		}
     86 		remove.add(index);
     87 	}
     88 
     89 	public boolean removeValue (T value, boolean identity) {
     90 		if (iterating > 0) {
     91 			int index = indexOf(value, identity);
     92 			if (index == -1) return false;
     93 			remove(index);
     94 			return true;
     95 		}
     96 		return super.removeValue(value, identity);
     97 	}
     98 
     99 	public T removeIndex (int index) {
    100 		if (iterating > 0) {
    101 			remove(index);
    102 			return get(index);
    103 		}
    104 		return super.removeIndex(index);
    105 	}
    106 
    107 	public void removeRange (int start, int end) {
    108 		if (iterating > 0) {
    109 			for (int i = end; i >= start; i--)
    110 				remove(i);
    111 		} else
    112 			super.removeRange(start, end);
    113 	}
    114 
    115 	public void set (int index, T value) {
    116 		if (iterating > 0) throw new IllegalStateException("Invalid between begin/end.");
    117 		super.set(index, value);
    118 	}
    119 
    120 	public void insert (int index, T value) {
    121 		if (iterating > 0) throw new IllegalStateException("Invalid between begin/end.");
    122 		super.insert(index, value);
    123 	}
    124 
    125 	public void swap (int first, int second) {
    126 		if (iterating > 0) throw new IllegalStateException("Invalid between begin/end.");
    127 		super.swap(first, second);
    128 	}
    129 
    130 	public T pop () {
    131 		if (iterating > 0) throw new IllegalStateException("Invalid between begin/end.");
    132 		return super.pop();
    133 	}
    134 
    135 	public void clear () {
    136 		if (iterating > 0) throw new IllegalStateException("Invalid between begin/end.");
    137 		super.clear();
    138 	}
    139 
    140 	public void sort () {
    141 		if (iterating > 0) throw new IllegalStateException("Invalid between begin/end.");
    142 		super.sort();
    143 	}
    144 
    145 	public void sort (Comparator<? super T> comparator) {
    146 		if (iterating > 0) throw new IllegalStateException("Invalid between begin/end.");
    147 		super.sort(comparator);
    148 	}
    149 
    150 	public void reverse () {
    151 		if (iterating > 0) throw new IllegalStateException("Invalid between begin/end.");
    152 		super.reverse();
    153 	}
    154 
    155 	public void shuffle () {
    156 		if (iterating > 0) throw new IllegalStateException("Invalid between begin/end.");
    157 		super.shuffle();
    158 	}
    159 
    160 	public void truncate (int newSize) {
    161 		if (iterating > 0) throw new IllegalStateException("Invalid between begin/end.");
    162 		super.truncate(newSize);
    163 	}
    164 
    165 	public T[] setSize (int newSize) {
    166 		if (iterating > 0) throw new IllegalStateException("Invalid between begin/end.");
    167 		return super.setSize(newSize);
    168 	}
    169 
    170 	/** @see #DelayedRemovalArray(Object[]) */
    171 	static public <T> DelayedRemovalArray<T> with (T... array) {
    172 		return new DelayedRemovalArray(array);
    173 	}
    174 }
    175