blob: 019db8882d9056b16c8a4841ab73d2bfa3ff532a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006 IBM Corporation 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.debug.internal.ui.views.memory.renderings;
import java.math.BigInteger;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IMemoryBlock;
import org.eclipse.debug.core.model.IMemoryBlockExtension;
import org.eclipse.debug.internal.ui.memory.provisional.AbstractAsyncTableRendering;
import org.eclipse.debug.internal.ui.memory.provisional.MemoryViewPresentationContext;
import org.eclipse.debug.internal.ui.viewers.TableUpdatePolicy;
import org.eclipse.debug.internal.ui.viewers.provisional.IModelChangedListener;
import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta;
import org.eclipse.debug.ui.memory.IMemoryRendering;
import org.eclipse.ui.progress.UIJob;
/**
* This update policy updates immediately after a model changed event. The update policy will
* only update if the rendering is visible. Cache from the content manager is cleared
* when the memory block has changed when the rendering is not visible
*
*/
public class AsyncTableRenderingUpdatePolicy extends TableUpdatePolicy
{
public void modelChanged(IModelDelta node) {
// clear current cache as it becomes invalid when the memory block is changed
AbstractVirtualContentTableModel model = getTableViewer().getVirtualContentModel();
if (model != null)
{
IContentChangeComputer computer = null;
if (model instanceof IContentChangeComputer)
computer = (IContentChangeComputer)model;
clearCache(computer);
if (!containsEvent(node))
{
return;
}
if (node.getElement() instanceof IMemoryBlock && (node.getFlags() & IModelDelta.CONTENT) != 0)
{
if (computer != null && getTableViewer() != null)
{
// only cache if the rendering is not currently displaying error
if (!getTableViewer().getRendering().isDisplayingError())
{
// cache visible elelements
computer.cache(model.getElements());
}
}
// update policy figured out what's changed in the memory block
// and will tell rendering to update accordinly.
// Updating the rendering indirectly update the table viewer
notifyRendering(node);
handleMemoryBlockChanged((IMemoryBlock)node.getElement(), node);
return;
}
else if (node.getElement() instanceof IMemoryBlock && (node.getFlags() & IModelDelta.STATE) != 0)
{
// override handling of state change event
// let the super class deals with the rest of the changes
handleMemoryBlockChanged((IMemoryBlock)node.getElement(), node);
return;
}
}
super.modelChanged(node);
}
/**
* @param computer
*/
protected void clearCache(IContentChangeComputer computer) {
if (computer != null)
computer.clearCache();
}
private void notifyRendering(IModelDelta node) {
if (getTableViewer() != null)
{
IModelChangedListener listener = (IModelChangedListener)getTableViewer().getRendering().getAdapter(IModelChangedListener.class);
if (listener != null)
listener.modelChanged(node);
}
}
protected void handleMemoryBlockChanged(IMemoryBlock mb, IModelDelta delta)
{
try {
if (getViewer().getPresentationContext() instanceof MemoryViewPresentationContext)
{
MemoryViewPresentationContext context = (MemoryViewPresentationContext)getViewer().getPresentationContext();
final AbstractAsyncTableRendering rendering = getTableRendering(context);
if (rendering != null)
{
if ((delta.getFlags() & IModelDelta.CONTENT) != 0)
{
TableRenderingContentDescriptor descriptor = (TableRenderingContentDescriptor)rendering.getAdapter(TableRenderingContentDescriptor.class);
if (descriptor != null)
{
final BigInteger address = getMemoryBlockBaseAddress(mb);
if (!descriptor.isMemoryBlockBaseAddressInitialized() || !address.equals(descriptor.getContentBaseAddress()))
{
descriptor.updateContentBaseAddress();
UIJob job = new UIJob("go to address"){ //$NON-NLS-1$
public IStatus runInUIThread(IProgressMonitor monitor) {
try {
rendering.goToAddress(address);
} catch (DebugException e) {
if (getTableViewer() != null)
getTableViewer().handlePresentationFailure(null, e.getStatus());
}
return Status.OK_STATUS;
}};
job.setSystem(true);
job.schedule();
}
else
{
rendering.refresh();
}
}
}
else
{
rendering.updateLabels();
}
}
}
} catch (DebugException e) {
if (getTableViewer() != null)
getTableViewer().handlePresentationFailure(null, e.getStatus());
}
}
private BigInteger getMemoryBlockBaseAddress(IMemoryBlock mb) throws DebugException
{
if (mb instanceof IMemoryBlockExtension)
return ((IMemoryBlockExtension)mb).getBigBaseAddress();
else
return BigInteger.valueOf(mb.getStartAddress());
}
private AsyncTableRenderingViewer getTableViewer()
{
if (getViewer() instanceof AsyncTableRenderingViewer)
return (AsyncTableRenderingViewer)getViewer();
return null;
}
private boolean containsEvent(IModelDelta delta)
{
if (getViewer().getPresentationContext() instanceof MemoryViewPresentationContext)
{
MemoryViewPresentationContext context = (MemoryViewPresentationContext) getViewer().getPresentationContext();
if (context.getRendering() instanceof AbstractAsyncTableRendering)
{
AbstractAsyncTableRendering rendering = (AbstractAsyncTableRendering)context.getRendering();
if (!rendering.isVisible())
return false;
}
}
return true;
}
protected AbstractAsyncTableRendering getTableRendering(MemoryViewPresentationContext context)
{
IMemoryRendering memRendering = context.getRendering();
if (memRendering != null && memRendering instanceof AbstractAsyncTableRendering)
{
return (AbstractAsyncTableRendering)memRendering;
}
return null;
}
}