/******************************************************************************* * Copyright (c) 2009 Wind River Systems 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: * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.dsf.debug.service.command; import java.util.ArrayList; import java.util.List; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DsfExecutor; import org.eclipse.cdt.dsf.concurrent.DsfRunnable; import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor; /** * A command control which delays the <strong>results</strong> of commands * sent to a command control, as well as events from the command control. * The delay is specified in the constructor using a number of executor * dispatch cycles. * * @since 2.1 */ public class BufferedCommandControl implements ICommandControl { private DsfExecutor fExecutor; private ICommandControl fControlDelegate; private int fDepth; private ICommandListener fCommandListener = new ICommandListener() { public void commandQueued(ICommandToken token) { for (ICommandListener processor : fCommandProcessors) { processor.commandQueued(token); } }; public void commandRemoved(ICommandToken token) { for (ICommandListener processor : fCommandProcessors) { processor.commandRemoved(token); } }; public void commandSent(final ICommandToken token) { for (ICommandListener processor : fCommandProcessors) { processor.commandSent(token); } }; public void commandDone(final ICommandToken token, final ICommandResult result) { buffer(fDepth, new DsfRunnable() { public void run() { for (ICommandListener processor : fCommandProcessors) { processor.commandDone(token, result); } }; }); }; }; private IEventListener fEventListener = new IEventListener() { public void eventReceived(final Object output) { buffer(fDepth, new DsfRunnable() { public void run() { for (IEventListener processor : fEventProcessors) { processor.eventReceived(output); } }; }); } }; private final List<ICommandListener> fCommandProcessors = new ArrayList<ICommandListener>(); private final List<IEventListener> fEventProcessors = new ArrayList<IEventListener>(); public BufferedCommandControl(ICommandControl controlDelegate, DsfExecutor executor, int depth) { fControlDelegate = controlDelegate; fExecutor = executor; fDepth = depth; assert fDepth > 0; } public void addCommandListener(ICommandListener listener) { if (fCommandProcessors.isEmpty()) { fControlDelegate.addCommandListener(fCommandListener); } fCommandProcessors.add(listener); } public void removeCommandListener(ICommandListener listener) { fCommandProcessors.remove(listener); if (fCommandProcessors.isEmpty()) { fControlDelegate.removeCommandListener(fCommandListener); } } public void addEventListener(IEventListener listener) { if (fEventProcessors.isEmpty()) { fControlDelegate.addEventListener(fEventListener); } fEventProcessors.add(listener); } public void removeEventListener(IEventListener listener) { fEventProcessors.remove(listener); if (fEventProcessors.isEmpty()) { fControlDelegate.removeEventListener(fEventListener); } } public <V extends ICommandResult> ICommandToken queueCommand(final ICommand<V> command, final DataRequestMonitor<V> rm) { return fControlDelegate.queueCommand( command, new DataRequestMonitor<V>(ImmediateExecutor.getInstance(), rm) { @Override protected void handleCompleted() { buffer(fDepth, new DsfRunnable() { public void run() { rm.setData(getData()); rm.setStatus(getStatus()); rm.done(); } }); } }); } public void removeCommand(ICommandToken token) { fControlDelegate.removeCommand(token); } private void buffer(final int depth, final DsfRunnable runnable) { if (depth == 0) { runnable.run(); } else { fExecutor.execute(new DsfRunnable() { public void run() { buffer(depth - 1, runnable); } }); } } }