blob: 6343032836ac21f14012ec57d33966f8aadc1031 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013 Boeing.
* 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:
* Boeing - initial API and implementation
*******************************************************************************/
package org.eclipse.ote.ui.eviewer.view;
import java.util.Arrays;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.osee.framework.ui.swt.PeriodicDisplayTask;
/**
* @author Ken J. Aguilar
*/
public class ViewRefresher extends PeriodicDisplayTask {
private final TableViewer viewer;
private final ElementUpdate[] updates;
private int updateAppendIndex = 0;
private ElementUpdate[] incomingUpdates = new ElementUpdate[2048];
private int incomingCount = 0;
private boolean autoReveal = true;
private boolean updatesWrappedAround = false;
public ViewRefresher(TableViewer viewer, int limit) {
super(viewer.getTable().getDisplay(), 333);
this.viewer = viewer;
this.updates = new ElementUpdate[limit];
}
@Override
protected synchronized void update() {
if (incomingCount == 0) {
return;
}
viewer.getTable().setRedraw(false);
int newTotal = updateAppendIndex + incomingCount;
if (newTotal > updates.length) {
// remove the oldest updates from the viewer
int numberToRemove = newTotal - updates.length;
viewer.remove(Arrays.copyOfRange(updates, 0, numberToRemove));
// the updates array is now wrapping around since we surpassed the arrays capacity
updatesWrappedAround = true;
// find how much capacity with have remaining before we wrap
int remaining = updates.length - updateAppendIndex;
// fill the remaining portion of the updates array with the incoming
System.arraycopy(incomingUpdates, 0, updates, updateAppendIndex, remaining);
// wrap around and fill the part of the updates array that got removed
System.arraycopy(incomingUpdates, remaining, updates, 0, numberToRemove);
updateAppendIndex = numberToRemove;
} else {
if (updatesWrappedAround) {
// if we are wrapping around then for every incoming update we must remove the oldest update from the viewwer
viewer.remove(getUpdatesWithWrapAround(incomingCount));
}
System.arraycopy(incomingUpdates, 0, updates, updateAppendIndex, incomingCount);
updateAppendIndex += incomingCount;
}
viewer.add(Arrays.copyOf(incomingUpdates, incomingCount));
incomingCount = 0;
if (autoReveal) {
viewer.reveal(updates[updateAppendIndex-1]);
}
viewer.getTable().setRedraw(true);
}
public synchronized void addUpdate(ElementUpdate update) {
if (incomingCount >= incomingUpdates.length) {
// force an update to free up space on our incoming array
getDisplay().syncExec(new Runnable() {
@Override
public void run() {
update();
}
});
}
incomingUpdates[incomingCount++] = update;
}
public synchronized void clearUpdates() {
updateAppendIndex = 0;
updatesWrappedAround = false;
viewer.refresh();
}
/**
* @return the autoReveal
*/
public boolean isAutoReveal() {
return autoReveal;
}
/**
* @param autoReveal the autoReveal to set
*/
public synchronized void setAutoReveal(boolean autoReveal) {
this.autoReveal = autoReveal;
}
public synchronized ElementUpdate getUpdate(int index) {
if (updatesWrappedAround) {
int calcIndex = updateAppendIndex + index ;
if (calcIndex >= updates.length) {
calcIndex -= updates.length;
}
return updates[calcIndex];
} else {
return updates[index];
}
}
public synchronized ElementUpdate[] getUpdates() {
if (updatesWrappedAround) {
ElementUpdate[] copy = new ElementUpdate[updates.length];
int remaining = updates.length - updateAppendIndex;
System.arraycopy(updates, updateAppendIndex, copy, 0, remaining);
System.arraycopy(updates, 0, copy, remaining, updateAppendIndex);
return copy;
} else {
return Arrays.copyOf(updates, updateAppendIndex);
}
}
private ElementUpdate[] getUpdatesWithWrapAround(int count) {
ElementUpdate[] copy = new ElementUpdate[count];
if ((count + updateAppendIndex) > updates.length) {
int remaining = updates.length - updateAppendIndex;
System.arraycopy(updates, updateAppendIndex, copy, 0, remaining);
System.arraycopy(updates, 0, copy, remaining, count - remaining);
} else {
System.arraycopy(updates, updateAppendIndex, copy, 0, count);
}
return copy;
}
}