--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2012 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.maps.pojo;
+
+import java.awt.Image;
+import java.util.LinkedList;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+
+import org.simantics.maps.ProvisionException;
+import org.simantics.maps.query.Query;
+import org.simantics.maps.tile.IFilter;
+import org.simantics.maps.tile.ITileProvider;
+import org.simantics.maps.tile.TileKey;
+
+/**
+ * @author Tuukka Lehtonen
+ * @see TileJobQueue
+ */
+public class TileJob implements Runnable {
+
+ LinkedList<Query<TileKey, Image>> queue = new LinkedList<Query<TileKey, Image>>();
+ Executor executor = new ScheduledThreadPoolExecutor(1);
+ ITileProvider provider;
+
+ public TileJob() {
+ }
+
+ public void setTileProvider(ITileProvider provider) {
+ this.provider = provider;
+ }
+
+ protected Image doQuery(TileKey key) throws ProvisionException {
+ return provider.get(key);
+ }
+
+ public void run() {
+ Query<TileKey, Image> job = pullNextJob();
+ do {
+ if (job != null) {
+ try {
+ Image result = doQuery(job.source);
+ job.listener.queryComplete(job, result);
+ } catch (Exception e) {
+ job.listener.queryFailed(job, e);
+ }
+ }
+ // 4. Pick next job
+ job = pullNextJob();
+ } while (job != null);
+ }
+
+ protected synchronized int jobsLeft() {
+ return queue.size();
+ }
+
+ protected synchronized Query<TileKey, Image> pullNextJob() {
+ if (queue.isEmpty())
+ return null;
+ return queue.removeFirst();
+ }
+
+ public synchronized void clear() {
+ @SuppressWarnings("unchecked")
+ Query<TileKey, Image> jobs[] = queue.toArray(new Query[queue.size()]);
+ for (Query<TileKey, Image> j : jobs)
+ removeJob(j);
+ }
+
+ public synchronized void addJob(Query<TileKey, Image> job) {
+ queue.addLast(job);
+ if (queue.size() == 1) {
+ executor.execute(this);
+ }
+ }
+
+ public synchronized void addAsFirstJob(Query<TileKey, Image> job) {
+ queue.addFirst(job);
+ if (queue.size() == 1) {
+ executor.execute(this);
+ }
+ }
+
+ public synchronized boolean removeJob(Query<TileKey, Image> job) {
+ if (queue.remove(job)) {
+ job.listener.queryCanceled(job);
+ return true;
+ }
+ return false;
+ }
+
+ public synchronized void filterQueries(IFilter<TileKey> filter) {
+ if (queue.isEmpty())
+ return;
+
+ LinkedList<Query<TileKey, Image>> result = new LinkedList<Query<TileKey, Image>>();
+ for (Query<TileKey, Image> query : queue) {
+ if (filter.select(query.source))
+ result.add(query);
+ else
+ query.listener.queryCanceled(query);
+ }
+ this.queue = result;
+ }
+
+}