diff --git a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRendering.java b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRendering.java index f18cb2d5c7c..5692f7f0e35 100644 --- a/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRendering.java +++ b/memory/org.eclipse.cdt.debug.ui.memory.traditional/src/org/eclipse/cdt/debug/ui/memory/traditional/TraditionalRendering.java @@ -13,7 +13,6 @@ package org.eclipse.cdt.debug.ui.memory.traditional; import java.lang.reflect.Method; import java.math.BigInteger; -import java.util.HashMap; import org.eclipse.cdt.debug.core.model.provisional.IMemoryRenderingViewportProvider; import org.eclipse.core.commands.AbstractHandler; @@ -23,9 +22,7 @@ import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; -import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugException; -import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.model.IMemoryBlock; import org.eclipse.debug.core.model.IMemoryBlockExtension; import org.eclipse.debug.core.model.MemoryByte; @@ -200,124 +197,79 @@ public class TraditionalRendering extends AbstractMemoryRendering implements IRe /* * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener#modelChanged(org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta, org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy) */ - public void modelChanged(IModelDelta delta, IModelProxy proxy) - { - /* - * The event model in the traditional renderer is written to expect a suspend first - * which will cause it to save its current data set away in an archive. Then when - * the state change comes through it will compare and refresh showing a difference. - */ - int flags = delta.getFlags(); - if ( ( flags & IModelDelta.STATE ) != 0 ) { - DebugEvent debugEvent = new DebugEvent(delta.getElement(), DebugEvent.SUSPEND, DebugEvent.CONTENT); - DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { debugEvent }); - } + public void modelChanged(IModelDelta delta, IModelProxy proxy) + { + /* + * The event model in the traditional renderer is written to expect a suspend first + * which will cause it to save its current data set away in an archive. Then when + * the state change comes through it will compare and refresh showing a difference. + */ + int flags = delta.getFlags(); + if ( ( flags & IModelDelta.STATE ) != 0 ) { + fRendering.handleSuspend(false); + } - DebugEvent debugEvent = new DebugEvent(delta.getElement(), DebugEvent.CHANGE, DebugEvent.CONTENT); - DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { debugEvent }); - } + fRendering.handleChange(); + } /* - * These hashes make sure we do not create a separate model proxy for the same memory block. If - * we did then we would get duplicate state changes which would hide the actual changes since - * the renderer would be notified of state change too many times and wipe out the difference - * calculation it does. If we create multiple renderers against the same memory block we will - * use the same Model Proxy for all of them. So we need to keep a count to know when the last - * renderer has been torn down and we can freeup the proxy for that memory block. These stores - * are always manipulate and tested on the UI dispatch thread for data integrity. + * We use the model proxy which is supplied by the TCF implementation to provide the knowledge of memory + * change notifications. The older backends ( the reference model, Wind River Systems Inc. ) are written + * to generate the Debug Model events. TCF follows the "ModelDelta/IModelProxy" implementation that the + * platform renderers use. So this implementation acts as a shim. If the older Debug Events come in then + * fine. If the newer model deltas come in fine also. */ - private static HashMap proxies = new HashMap(); // MemoryBlock --> Proxy - private static HashMap proxies_cnt = new HashMap(); // MemoryBlock --> count - + private IModelProxy fModel; + @Override - public void dispose() + public void dispose() { - /* - * We use the UI dispatch thread to protect the proxy information. Even though I believe the - * dispose routine is always called in the UI dispatch thread. I am going to make sure. - */ + /* + * We use the UI dispatch thread to protect the proxy information. Even though I believe the + * dispose routine is always called in the UI dispatch thread. I am going to make sure. + */ Display.getDefault().asyncExec(new Runnable() { - public void run() { - IMemoryBlock block = getMemoryBlock(); - - /* - * See if we already know about this block and already have a proxy for it. - */ - if ( proxies_cnt.containsKey( block ) ) { - Integer cur_cnt = proxies_cnt.get( block ); - cur_cnt -- ; - - /* - * If the count is zero this is the last render associated with this block. - * We can clean out this block/proxy. - */ - if ( cur_cnt == 0 ) { - - proxies_cnt.remove( block ); - IModelProxy proxy = proxies.remove( block ); - - /* - * Before disposal make sure we take down the listener so we do not get - * any phantom notifications. - */ - proxy.removeModelChangedListener(TraditionalRendering.this); - proxy.dispose(); - - } - else { - /* - * Not the last so just put back the reduced count. - */ - proxies_cnt.put( block, cur_cnt ); - } - } - }}); - + public void run() { + if ( fModel != null ) { + fModel.removeModelChangedListener(TraditionalRendering.this); + fModel.dispose(); + } + }}); + if(this.fRendering != null) this.fRendering.dispose(); disposeColors(); super.dispose(); } - -// private IModelProxy fModel; + @Override public void init(final IMemoryRenderingContainer container, final IMemoryBlock block) { super.init(container, block); + /* + * Working with the model proxy must be done on the UI dispatch thread. + */ if ( block instanceof IModelProxyFactory ) { Display.getDefault().asyncExec(new Runnable() { public void run() { - - if ( proxies.containsKey( block ) ) { - /* - * Increment the count and reuse the proxy again. - */ - proxies_cnt.put( block, proxies_cnt.get( block ) + 1 ); - } - else { - /* - * We need to create a new proxy. First generate an acceptable Presentation Context. - */ - IMemoryRenderingSite site = container.getMemoryRenderingSite(); - MemoryViewPresentationContext context = new MemoryViewPresentationContext(site, container, TraditionalRendering.this); - /* - * Get a new proxy and perform the initialization sequence so we are known the - * the model provider. - */ - IModelProxyFactory factory = (IModelProxyFactory) block; - IModelProxy proxy = factory.createModelProxy(block, context); - proxy.installed(null); - proxy.addModelChangedListener(TraditionalRendering.this); - - /* - * Now note this block/proxy so we can reuse it later if more renderers are create - * with the same block. - */ - proxies.put( block , proxy ); - proxies_cnt.put( block, new Integer(1) ); - } + /* + * The asynchronous model assumes we have an asynchronous viewer that has an IPresentationContext + * to represent it. The Platform memory subsystem provides a way to create one without a viewewr. + */ + IMemoryRenderingSite site = container.getMemoryRenderingSite(); + MemoryViewPresentationContext context = new MemoryViewPresentationContext(site, container, TraditionalRendering.this); + + /* + * Get a new proxy and perform the initialization sequence so we are known the + * the model provider. + */ + IModelProxyFactory factory = (IModelProxyFactory) block; + fModel = factory.createModelProxy(block, context); + fModel.installed(null); + fModel.addModelChangedListener(TraditionalRendering.this); + }}); }