/******************************************************************************* * Copyright (c) 2011 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 *******************************************************************************/ //#ifdef exercises package org.eclipse.cdt.examples.dsf.dataviewer; //#else //#package org.eclipse.cdt.examples.dsf.dataviewer.answers; //#endif import java.util.HashMap; import java.util.Map; import java.util.Set; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.ICache; import org.eclipse.cdt.dsf.concurrent.ImmediateInDsfExecutor; import org.eclipse.cdt.dsf.concurrent.RequestCache; import org.eclipse.cdt.examples.dsf.DsfExamplesPlugin; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; /** * A wrapper class for the {@link IDataGenerator} interface, which returns * ACPM cache objects to use for data retrieval instead of calling * {@link IDataGenerator} asynchronous methods directly. */ public class DataGeneratorCacheManager implements IDataGenerator.Listener { /** Cache class for retrieving the data generator's count. */ private class CountCache extends RequestCache<Integer> { public CountCache() { super(fExecutor); } @Override protected void retrieve(DataRequestMonitor<Integer> rm) { fDataGenerator.getCount(rm); } /** * Reset the cache when the count is changed. */ public void countChanged() { // Make sure that if clients are currently waiting for a count, // they are notified of the update (their request monitors will be // completed with an error). They shoudl then re-request data // from provider again. setAndReset(null, new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Count changed")); } } /** Cache class for retrieving the data generator's values. */ private class ValueCache extends RequestCache<Integer> { private int fIndex; public ValueCache(int index) { super(fExecutor); fIndex = index; } @Override protected void retrieve(org.eclipse.cdt.dsf.concurrent.DataRequestMonitor<Integer> rm) { fDataGenerator.getValue(fIndex, rm); }; /** * @see CountCache#countChanged() */ public void valueChanged() { setAndReset(null, new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Value changed")); } } /** * Executor used to synchronize data access in this cache manager. * It has to be the same executor that is used by the data generators in * order to guarantee data consistency. */ private ImmediateInDsfExecutor fExecutor; /** * Data generator that this cache manager is a wrapper for. */ private IDataGenerator fDataGenerator; /** Cache for data generator's count */ private CountCache fCountCache; /** * Map of caches for retrieving values. Each value index has a separate * cache value object. */ private Map<Integer, ValueCache> fValueCaches = new HashMap<Integer, ValueCache>(); public DataGeneratorCacheManager(ImmediateInDsfExecutor executor, IDataGenerator dataGenerator) { fExecutor = executor; fDataGenerator = dataGenerator; fDataGenerator.addListener(this); } public void dispose() { fDataGenerator.removeListener(this); } /** * Returns the data generator that this cache manager wraps. */ public IDataGenerator getDataGenerator() { return fDataGenerator; } /** * Returns the cache for data generator count. */ public ICache<Integer> getCount() { if (fCountCache == null) { fCountCache = new CountCache(); } return fCountCache; } /** * Returns the cache for a value at given index. * * @param index Index of value to return. * @return Cache object for given value. */ public ICache<Integer> getValue(int index) { ValueCache value = fValueCaches.get(index); if (value == null) { value = new ValueCache(index); fValueCaches.put(index, value); } return value; } @Override public void countChanged() { // Reset the count cache and all the value caches. if (fCountCache != null) { fCountCache.countChanged(); } for (ValueCache value : fValueCaches.values()) { value.valueChanged(); } } @Override public void valuesChanged(Set<Integer> indexes) { // Reset selected value caches. for (Integer index : indexes) { ValueCache value = fValueCaches.get(index); if (value != null) { value.valueChanged(); } } } }