/******************************************************************************* * Copyright (c) 2007, 2010 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 *******************************************************************************/ /* * 25.1.2007 */ package org.simantics.utils.ui.gfx.rasterize; import java.util.LinkedList; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.swt.graphics.ImageData; /** * LazyRasterizer * * @author Toni Kalajainen */ public class LazyRasterizer { public static void addJob(RasterJob job) { getJob().addJob(job); } public static void addAsFirstJob(RasterJob job) { getJob().addAsFirstJob(job); } public static void removeJob(RasterJob job) { getJob().removeJob(job); } static RasterizeJob job; synchronized static RasterizeJob getJob() { if (job == null) job = new RasterizeJob(); return job; } static class RasterizeJob extends Job { LinkedList queue = new LinkedList(); @SuppressWarnings("unused") private boolean isRunning; public RasterizeJob() { super("Rasterize Job"); } @Override protected IStatus run(IProgressMonitor monitor) { //System.out.println(Thread.currentThread()); setThread(Thread.currentThread()); int taskLeft = 10000; isRunning = true; monitor.beginTask("Rasterizing", taskLeft); try { // 1. Pick a job RasterJob job = pullNextJob(); do { // 2. Check if canceled if (monitor.isCanceled()) { cancel(); return Status.CANCEL_STATUS; } // 3. rasterize if (job != null) { try { monitor.subTask(job.raster.toString()); ImageData id = job.raster.rasterize(job.width, job.height); job.listener.rasterizationComplete(job, id); } catch (Exception e) { job.listener.rasterizationFailed(job, e); } int jobsLeft = jobsLeft(); double workLeft; if (jobsLeft == 0) { workLeft = taskLeft; } else { workLeft = ((double) taskLeft) / ((double) jobsLeft()); } int worked = (int) workLeft; monitor.worked(worked); taskLeft -= worked; } monitor.subTask(""); // 4. Pick next job job = pullNextJob(); } while (job != null); isRunning = false; } finally { monitor.done(); } return Status.OK_STATUS; } protected synchronized int jobsLeft() { return queue.size(); } protected synchronized RasterJob pullNextJob() { if (queue.isEmpty()) return null; return queue.removeFirst(); } public synchronized void clear() { RasterJob jobs[] = queue.toArray(new RasterJob[0]); for (RasterJob j : jobs) removeJob(j); } public synchronized void addJob(RasterJob job) { queue.addLast(job); job.status = RasterJobStatus.QUEUED; //if (!isRunning && queue.size()==1) schedule(); } public synchronized void addAsFirstJob(RasterJob job) { queue.addFirst(job); job.status = RasterJobStatus.QUEUED; //if (!isRunning && queue.size()==1) schedule(); } public synchronized boolean removeJob(RasterJob job) { if (queue.remove(job)) { job.status = RasterJobStatus.COMPLETE; job.listener.rasterizationCanceled(job); return true; } return false; } } }