/******************************************************************************* * Copyright (c) 2006-2013 The RCP Company and others. * 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: * The RCP Company - initial API and implementation *******************************************************************************/ package com.rcpcompany.uibindings.internal.utils; import java.util.ArrayList; import java.util.List; import org.eclipse.ui.PlatformUI; import com.rcpcompany.uibindings.IManager; import com.rcpcompany.uibindings.model.utils.BasicUtils; import com.rcpcompany.uibindings.utils.IManagerRunnable; import com.rcpcompany.uibindings.utils.IManagerRunnableManager; import com.rcpcompany.utils.logging.LogUtils; /** * Implementation of {@link IManagerRunnableManager}. * * @author Tonny Madsen, The RCP Company */ public class ManagerRunnableManager implements IManagerRunnableManager { public ManagerRunnableManager() { IManager.Factory.getManager().registerService(this); } @Override public void dispose() { /* * Cancel all... */ for (final Record r : myRecords.toArray(new Record[myRecords.size()])) { r.cancel(); } IManager.Factory.getManager().unregisterService(this); } @Override public void asyncExec(String type, Object key, Runnable runnable) { final Record r = findRecord(type, key); if (r != null) { r.replaceRunnable(runnable); return; } new Record(type, key, runnable); startDisplayRunnable(); } @Override public boolean isEmpty() { return myRecords.isEmpty(); } /** * Starts a new Display runnable if needed. */ private void startDisplayRunnable() { if (displayRunnableAdded) return; displayRunnableAdded = true; PlatformUI.getWorkbench().getDisplay().asyncExec(displayRunnable); } boolean displayRunnableAdded = false; Runnable displayRunnable = new Runnable() { @Override public void run() { displayRunnableAdded = false; final long start = System.currentTimeMillis(); while (!isEmpty() && (System.currentTimeMillis() - start < MAX_TIME)) { final Record r = myRecords.get(0); // LogUtils.debug(r, "started"); try { r.run(); } catch (final Exception ex) { LogUtils.error(r.runnable, ex); } } if (!isEmpty()) { startDisplayRunnable(); } } }; @Override public void cancelAsyncExec(String type, Object key) { final Record r = findRecord(type, key); if (r != null) { r.cancel(); } } private Record findRecord(String type, Object key) { if (type == null) return null; for (final Record r : myRecords) { if (BasicUtils.equals(type, r.type) && BasicUtils.equals(key, r.key)) return r; } return null; } /** * All registered records. */ private final List<Record> myRecords = new ArrayList<Record>(); /** * Record of a single registered {@link Runnable}. */ public class Record { String type; Object key; Runnable runnable; public Record(String type, Object key, Runnable runnable) { this.type = type; this.key = key; this.runnable = runnable; myRecords.add(this); } /** * Cancels this record. */ public void run() { myRecords.remove(this); try { runnable.run(); } catch (final Exception ex) { LogUtils.error(runnable, ex); } if (runnable instanceof IManagerRunnable) { // TODO ? } } /** * Replaces the current {@link Runnable} with a new. * * @param newRunnable the new runnable */ public void replaceRunnable(Runnable newRunnable) { final Runnable oldRunnable = runnable; runnable = newRunnable; if (oldRunnable instanceof IManagerRunnable) { } } /** * Cancels this record. */ public void cancel() { myRecords.remove(this); if (runnable instanceof IManagerRunnable) { } } @Override public String toString() { return "Record [type=" + type + ", key=" + key + "]"; } } }