package org.jactr.eclipse.runtime.playback.internal;
/*
* default logging
*/
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.jactr.eclipse.runtime.RuntimePlugin;
import org.jactr.eclipse.runtime.debug.elements.ACTRDebugElement;
import org.jactr.eclipse.runtime.marker.MarkerIndex.MarkerRecord;
import org.jactr.eclipse.runtime.preferences.RuntimePreferences;
import org.jactr.eclipse.runtime.session.ISession;
import org.jactr.eclipse.runtime.session.control.DefaultRunForContentProvider;
import org.jactr.eclipse.runtime.session.control.ISessionController2;
public class ArchiveController implements ISessionController2
{
/**
* Logger definition
*/
static private final transient Log LOGGER = LogFactory
.getLog(ArchiveController.class);
private final ArchivalIndex _index;
private final EventPumper _pumper;
private double _currentTime;
private boolean _terminated = false;
private final ISession _session;
private ITreeContentProvider _runForContent;
private ITreeContentProvider _runToContent;
private boolean _canSkipAhead = true;
private double _currentStepSize;
public ArchiveController(ISession session, ArchivalIndex index,
EventPumper pumper)
{
_index = index;
_session = session;
_pumper = pumper;
_currentTime = _index.getStartTime();
_currentStepSize = RuntimePlugin.getDefault().getPreferenceStore()
.getInt(RuntimePreferences.RUNTIME_DATA_WINDOW);
// currently the number of rows, assuming 50ms per row, would be /20
// let's give ourselves a little slop
_currentStepSize = _currentStepSize / 30;
setRunForContentProvider(new DefaultRunForContentProvider());
}
public void setRunForContentProvider(ITreeContentProvider provider)
{
_runForContent = provider;
}
public void setRunToContentProvider(ITreeContentProvider provider)
{
_runToContent = provider;
}
public double getCurrentTime()
{
return _currentTime;
}
public boolean isRunning()
{
return !isTerminated();
}
public boolean isTerminated()
{
return _terminated;
}
public boolean canTerminate()
{
return !isTerminated() && _currentTime >= _index.getStartTime()
&& _currentTime < _index.getEndTime();
}
public boolean terminate() throws Exception
{
if (!canTerminate()) return true;
_currentTime = Double.MAX_VALUE;
_terminated = true;
_index.close();
ACTRDebugElement.fireTerminateEvent(_session);
return true;
}
public boolean isSuspended()
{
boolean isFree = _pumper.isFree();
if (LOGGER.isDebugEnabled())
LOGGER.debug(String.format("event pumper is free: %s", isFree));
return _pumper.isFree() && isRunning();
}
public boolean canSuspend()
{
return false;
}
public boolean suspend() throws Exception
{
return false;
}
public boolean canResume()
{
return isSuspended();
}
public void runFully() throws Exception
{
if (!canResume()) throw new RuntimeException("Must be suspended first");
double startTime = _currentTime;
ACTRDebugElement.fireResumeEvent(_session, 0);
_index.pump(startTime, _index.getEndTime(), _pumper);
}
public boolean resume() throws Exception
{
if (!canResume()) throw new RuntimeException("Must be suspended first");
double windowSize = _currentStepSize;
double startTime = _currentTime;
double endTime = _currentTime + windowSize;
if (LOGGER.isDebugEnabled())
LOGGER.debug(String.format("Resuming @ %.2f for %.2f", startTime,
windowSize));
ACTRDebugElement.fireResumeEvent(_session, 0);
_index.pump(startTime, endTime, _pumper);
return true;
}
public boolean canStep()
{
return false;
}
public boolean step() throws Exception
{
return false;
}
protected void setCurrentTime(double currentTime)
{
_currentTime = currentTime;
}
public void setStepSize(double stepSize)
{
_currentStepSize = stepSize;
}
public boolean canRunTo(Object destination)
{
if (destination instanceof Number)
return canRunToInternal(((Number) destination).doubleValue());
if (destination instanceof MarkerRecord)
return canRunToInternal((MarkerRecord) destination);
return false;
}
public void runTo(Object destination) throws Exception
{
double targetTime = _currentTime;
if (destination instanceof Number)
targetTime = ((Number) destination).doubleValue();
if (destination instanceof MarkerRecord)
targetTime = ((MarkerRecord) destination)._time + 0.1;
if (targetTime <= _currentTime)
throw new IllegalArgumentException(String.format(
"Target time %.2f has already passed %.2f", targetTime, _currentTime));
double startTime = _currentTime;
if (_canSkipAhead)
{
double fullWindow = RuntimePlugin.getDefault().getPreferenceStore()
.getInt(RuntimePreferences.RUNTIME_DATA_WINDOW);
if (targetTime > startTime + fullWindow)
startTime = targetTime - fullWindow;
}
_index.pump(startTime, targetTime, _pumper);
// ACTRDebugElement.fireResumeEvent(_session, 0);
}
public boolean canRunFor(Object duration)
{
if (duration instanceof Number)
{
double targetDuration = ((Number) duration).doubleValue();
return targetDuration + _currentTime <= _index.getEndTime()
&& canResume();
}
return false;
}
public void runFor(Object duration) throws Exception
{
if (duration instanceof Number)
{
double targetDuration = ((Number) duration).doubleValue();
double targetTime = targetDuration + _currentTime;
if (targetTime > _index.getEndTime())
throw new IllegalArgumentException(String.format(
"Running for %.2f will exceed total run time (%.2f)",
targetDuration, _index.getEndTime()));
_index.pump(_currentTime, targetTime, _pumper);
// ACTRDebugElement.fireResumeEvent(_session, 0);
}
else
throw new IllegalArgumentException(String.format(
"No clue how to run for %s", duration));
}
protected boolean canRunToInternal(double time)
{
return canResume() && time > _currentTime && time <= _index.getEndTime();
}
protected boolean canRunToInternal(MarkerRecord record)
{
return canRunToInternal(record._time + 1);
}
public ITreeContentProvider getRunToContentProvider()
{
return _runToContent;
}
public ITreeContentProvider getRunForContentProvider()
{
return _runForContent;
}
public ISession getSession()
{
return _session;
}
}