/*******************************************************************************
 * Copyright (c) 2013 Pivotal Software, Inc.
 * 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:
 * Pivotal Software, Inc. - initial API and implementation
 *******************************************************************************/
package org.springsource.ide.eclipse.commons.livexp.core;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.ui.progress.UIJob;

/**
 * This class should be used instead of ValueListener when the code it
 * wants to execute upon receiving a 'gotValue' event is required
 * to run in the UIThread (i.e. typically this is code that needs to
 * update or read widgets in the UI).
 */
public abstract class UIValueListener<T> implements ValueListener<T> {
	
	private class NotifyingJob extends UIJob {
		
		LiveExpression<T> exp;
		
		public NotifyingJob(LiveExpression<T> exp) {
			super("Notifying Job");
			this.exp = exp;
			setSystem(true);
		}

		@Override
		public IStatus runInUIThread(IProgressMonitor monitor) {
			uiGotValue(exp, exp.getValue());
			return Status.OK_STATUS;
		}
		
	}

	private NotifyingJob job = null;
	
	/**
	 * This method is final. Implement 'uiGotValue' instead.
	 */
	public final void gotValue(final LiveExpression<T> exp, final T value) {
		NotifyingJob job = this.job;
		if (job == null || job.exp != exp) {
			job = new NotifyingJob(exp);
			this.job = job;
		}
		job.schedule();
	}

	/**
	 * Subclasses should implement. This method will always be called in the UIThread.
	 */
	protected abstract void uiGotValue(LiveExpression<T> exp, T value);

}

/*******************************************************************************
 * Copyright (c) 2013 Pivotal Software, Inc.
 * 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:
 * Pivotal Software, Inc. - initial API and implementation
 *******************************************************************************/
package org.springsource.ide.eclipse.commons.livexp.core;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.ui.progress.UIJob;

/**
 * This class should be used instead of ValueListener when the code it
 * wants to execute upon receiving a 'gotValue' event is required
 * to run in the UIThread (i.e. typically this is code that needs to
 * update or read widgets in the UI).
 */
public abstract class UIValueListener<T> implements ValueListener<T> {

	private class NotifyingJob extends UIJob {

		LiveExpression<T> exp;

		public NotifyingJob(LiveExpression<T> exp) {
			super("Notifying Job");
			this.exp = exp;
			setSystem(true);
		}

		@Override
		public IStatus runInUIThread(IProgressMonitor monitor) {
			uiGotValue(exp, exp.getValue());
			return Status.OK_STATUS;
		}

	}

	private NotifyingJob job = null;

	/**
	 * This method is final. Implement 'uiGotValue' instead.
	 */
	public final void gotValue(final LiveExpression<T> exp, final T value) {
		NotifyingJob job = this.job;
		if (job == null || job.exp != exp) {
			job = new NotifyingJob(exp);
			this.job = job;
		}
		job.schedule();
	}

	/**
	 * Subclasses should implement. This method will always be called in the UIThread.
	 */
	protected abstract void uiGotValue(LiveExpression<T> exp, T value);

	/**
	 * A Lambda-friendly way to creat {@link UIValueListener}
	 */
	public static <T> UIValueListener<T> from(ValueListener<T> l) {
		return new UIValueListener<T>() {
			@Override
			protected void uiGotValue(LiveExpression<T> exp, T value) {
				l.gotValue(exp, value);
			}
		};
	}

}

Add a lamba-friendly method for creating UIValueListener