1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
13 package org.simantics.utils.datastructures.prioritystack;
15 import java.lang.reflect.Array;
16 import java.lang.reflect.Method;
17 import java.util.ArrayList;
18 import java.util.HashMap;
19 import java.util.LinkedList;
20 import java.util.List;
21 import java.util.ListIterator;
24 import org.simantics.utils.strings.EString;
25 import org.simantics.utils.threads.IThreadWorkQueue;
26 import org.simantics.utils.threads.SyncListenerList;
30 * Implementation to IPriorityStack.
34 * getAllItems() is optimized for result with the penalty of slower add/remove methods.
36 * @author Toni Kalajainen
39 public class PriorityStack<E> implements IPriorityStack<E> {
41 @SuppressWarnings({ "rawtypes" })
42 private SyncListenerList<IPriorityStackListener> listeners =
43 new SyncListenerList<IPriorityStackListener>(IPriorityStackListener.class);
45 private LinkedList<E> list =
48 private E[] snapshotArray;
50 private Map<E, Integer> priorities =
51 new HashMap<E, Integer>();
55 public PriorityStack(Class<E> clazz) {
57 snapshotArray = createArray(0);
61 public void add(E interactor, int priority) {
64 if (list.contains(interactor))
65 throw new IllegalArgumentException("InteractorStack already contains item "+interactor);
67 priorities.put(interactor, priority);
72 snapshotArray = createSnapshot(list);
76 ListIterator<E> li = list.listIterator();
77 while (li.hasNext()) {
79 double w = priorities.get( i );
83 snapshotArray = createSnapshot(list);
87 list.addLast(interactor);
88 snapshotArray = createSnapshot(list);
90 fireInteractorAdded(interactor);
94 public boolean remove(E interactor) {
96 if (!priorities.containsKey(interactor))
98 priorities.remove(interactor);
99 list.remove(interactor);
100 snapshotArray = createSnapshot(list);
102 fireInteractorRemoved(interactor);
107 public synchronized Integer getPriority(E interactor) {
108 return priorities.get(interactor);
111 @SuppressWarnings({ "unchecked" })
112 private E[] createArray(int length)
114 return (E[]) Array.newInstance(clazz, length);
117 E[] createSnapshot(List<E> list) {
118 E[] result = createArray(list.size());
125 public synchronized int indexOf(E item)
127 for (int i=0; i<snapshotArray.length; i++)
128 if (snapshotArray[i]==item)
134 public synchronized E[] toArray() {
135 return snapshotArray;
138 public synchronized <R extends E> R getSingleItem(Class<R> clazz)
140 R array[] = getItemsByClass(clazz);
142 throw new RuntimeException("one "+clazz.getName()+" expected in PriorityStack, got "+array.length);
146 @SuppressWarnings("unchecked")
148 public synchronized <R extends E> R[] getItemsByClass(Class<R> clazz)
150 List<E> result = new ArrayList<E>(list.size());
152 if (clazz.isAssignableFrom(i.getClass()))
154 return (R[])result.toArray(createArray(result.size()));
157 private static Method itemAdded = SyncListenerList.getMethod(IPriorityStackListener.class, "itemAdded");
158 private void fireInteractorAdded(E interactor)
160 listeners.fireEventSync(itemAdded, this, interactor);
163 private static Method itemRemoved = SyncListenerList.getMethod(IPriorityStackListener.class, "itemRemoved");
164 private void fireInteractorRemoved(E interactor)
166 listeners.fireEventSync(itemRemoved, this, interactor);
170 public synchronized void addStackListener(IPriorityStackListener<E> listener) {
171 listeners.add(listener);
175 public synchronized void removeStackListener(IPriorityStackListener<E> listener) {
176 listeners.remove(listener);
180 public synchronized boolean contains(E interactor) {
181 return list.contains(interactor);
185 public void addStackListener(IThreadWorkQueue thread,
186 IPriorityStackListener<E> listener) {
187 listeners.add(thread, listener);
191 public void removeStackListener(IThreadWorkQueue thread,
192 IPriorityStackListener<E> listener) {
193 listeners.remove(thread, listener);
197 public String toString() {
198 return EString.implode(snapshotArray, "\n");