Commit a2c79680 authored by Simon Tenbusch's avatar Simon Tenbusch

[sequencechart]

- fixed many bugs that were introduced due to potentially different ordering of events in REAL_TIME mode, and due to calculation of the simulation end timestamp when durations are turned on.
- ticks are now drawn correctly
parent 2595f1a9
......@@ -848,6 +848,10 @@ public class SequenceChart
public org.omnetpp.common.engine.BigDecimal getViewportRightSimulationTime() {
return getSimulationTimeForViewportCoordinate(getViewportWidth());
}
public IEvent getLargestEndEvent() {
return sequenceChartFacade.IEvent_getEvent(sequenceChartFacade.getLargestEndtimeInEventRange(eventLog.getFirstEvent().getCPtr(),eventLog.getLastEvent().getCPtr(), getEventLengthMode()==EventLengthMode.DURATION));
}
/*************************************************************************************
* SCROLLING, GOTOING
......@@ -865,9 +869,13 @@ public class SequenceChart
if (eventLog != null && !eventLog.isEmpty()) {
// don't go after the very end
if (eventLog.getLastEvent().getSimulationTime().less(getViewportRightSimulationTime())) {
org.omnetpp.common.engine.BigDecimal time = getLargestEndEvent().getSimulationTime();
if(EventLengthMode.DURATION == getEventLengthMode()) {
time.add(getLargestEndEvent().getEventEntry().getDuration());
}
if (time.less(getViewportRightSimulationTime())) {
this.fixPointViewportCoordinate = getViewportWidth();
sequenceChartFacade.relocateTimelineCoordinateSystem(eventLog.getLastEvent());
sequenceChartFacade.relocateTimelineCoordinateSystem(getLargestEndEvent());
}
// don't go before the very beginning
......@@ -1426,8 +1434,13 @@ public class SequenceChart
setShowTransmissionDurations(sequenceChartState.showTransmissionDurations);
// restore timeline mode
if (sequenceChartState.timelineMode != null)
if (sequenceChartState.timelineMode != null) {
setTimelineMode(sequenceChartState.timelineMode);
if (sequenceChartState.timelineMode == TimelineMode.REAL_TIME) {
setEventLengthMode(EventLengthMode.COMPLEXITY);
}
}
return true;
}
......@@ -2610,7 +2623,8 @@ public class SequenceChart
// draw rectangle after the very end of the simulation
if (sequenceChartFacade.IEvent_getNextEvent(endEventPtr) == 0) {
x = clip.right();
long largestEvent = sequenceChartFacade.getLargestEndtimeInEventRange(startEventPtr,endEventPtr);
long largestEvent = getLargestEndEvent().getCPtr();
long endX = getEventXViewportCoordinate(largestEvent) + getEventLength(largestEvent) - 2;
if (x != endX)
......@@ -3008,15 +3022,13 @@ public class SequenceChart
private void drawTicks(Graphics graphics, int viewportHeigth) {
calculateTicks(getViewportWidth());
IEvent lastEvent = eventLog.getLastEvent();
IEvent lastEvent = getLargestEndEvent();
org.omnetpp.common.engine.BigDecimal endSimulationTime;
if (getTimelineMode() == TimelineMode.REAL_TIME){
//TODO Cache this
lastEvent = sequenceChartFacade.IEvent_getEvent(sequenceChartFacade.getLargestEndtimeInEventRange(eventLog.getFirstEvent().getCPtr(),eventLog.getLastEvent().getCPtr()));
endSimulationTime = lastEvent == null ? org.omnetpp.common.engine.BigDecimal.getZero() : new org.omnetpp.common.engine.BigDecimal(lastEvent.getEarliestProcessingTime()/1000000.0);
//} else if (getEventLengthMode() == EventLengthMode.DURATION){
// endSimulationTime = lastEvent == null ? org.omnetpp.common.engine.BigDecimal.getZero() : lastEvent.getSimulationTime().add(lastEvent.getEventEntry().getDuration());
} else if (getEventLengthMode() == EventLengthMode.DURATION){
endSimulationTime = lastEvent == null ? org.omnetpp.common.engine.BigDecimal.getZero() : lastEvent.getSimulationTime().add(lastEvent.getEventEntry().getDuration()); //TODO readd duration
} else {
endSimulationTime = lastEvent == null ? org.omnetpp.common.engine.BigDecimal.getZero() : lastEvent.getSimulationTime();
}
......@@ -3024,8 +3036,9 @@ public class SequenceChart
for (BigDecimal tick : ticks) {
// BigDecimal to double conversions loose precision both in Java and C++ but we must stick to the one in C++
// so that strange problems do not occur (think of comparing the tick's time to the last known simulation time)
org.omnetpp.common.engine.BigDecimal simulationTime = new org.omnetpp.common.engine.BigDecimal(tick.doubleValue());
if (endSimulationTime.less(simulationTime))
org.omnetpp.common.engine.BigDecimal simulationTime = new org.omnetpp.common.engine.BigDecimal(tick.doubleValue());
if (endSimulationTime.less(simulationTime))
simulationTime = endSimulationTime;
drawTick(graphics, viewportHeigth, TICK_LINE_COLOR, GUTTER_BACKGROUND_COLOR, tick, (int)getViewportCoordinateForSimulationTime(simulationTime), false);
}
......@@ -3661,7 +3674,7 @@ public class SequenceChart
sequenceChartFacade.IEvent_getSimulationTime(consequenceEventPtr).subtract(transmissionDelay);
// check simulation times for being out of range
org.omnetpp.common.engine.BigDecimal lastEventSimulationTime = eventLog.getLastEvent().getSimulationTime();
org.omnetpp.common.engine.BigDecimal lastEventSimulationTime = getLargestEndEvent().getSimulationTime();
if (t3.greater(lastEventSimulationTime) || t4.greater(lastEventSimulationTime) || t4.less(org.omnetpp.common.engine.BigDecimal.getZero()))
return isReceptionStart;
......@@ -3984,12 +3997,11 @@ public class SequenceChart
long tleft = modX - TICK_SPACING;
long tright = modX + viewportWidth + TICK_SPACING;
IEvent lastEvent = eventLog.getLastEvent();
IEvent lastEvent = getLargestEndEvent();
if (lastEvent != null) {
BigDecimal endSimulationTime;
if (getTimelineMode() == TimelineMode.REAL_TIME){
lastEvent = sequenceChartFacade.IEvent_getEvent(sequenceChartFacade.getLargestEndtimeInEventRange(eventLog.getFirstEvent().getCPtr(),eventLog.getLastEvent().getCPtr()));
endSimulationTime = lastEvent == null ? BigDecimal.ZERO : new BigDecimal(lastEvent.getEarliestProcessingTime()/1000000);
} else if (getEventLengthMode() == EventLengthMode.DURATION){
endSimulationTime = lastEvent == null ? BigDecimal.ZERO : lastEvent.getSimulationTime().toBigDecimal().add(lastEvent.getEventEntry().getDuration().toBigDecimal());
......@@ -4020,11 +4032,12 @@ public class SequenceChart
return BigDecimal.ZERO;
// query the simulation time for the given coordinate
BigDecimal simulationTime = getSimulationTimeForViewportCoordinate(x).toBigDecimal();
BigDecimal simulationTime = getSimulationTimeForViewportCoordinate(x, getEventLengthMode() == EventLengthMode.DURATION).toBigDecimal();
// defines the range of valid simulation times for the given tick range
BigDecimal tMin = getSimulationTimeForViewportCoordinate(x - tickRange / 2).toBigDecimal();
BigDecimal tMax = getSimulationTimeForViewportCoordinate(x + tickRange / 2).toBigDecimal();
BigDecimal tMin = getSimulationTimeForViewportCoordinate(x - tickRange / 2, getEventLengthMode() == EventLengthMode.DURATION).toBigDecimal();
BigDecimal tMax = getSimulationTimeForViewportCoordinate(x + tickRange / 2, getEventLengthMode() == EventLengthMode.DURATION).toBigDecimal();
// check some invariants
// originally we were checking these invariants, but it is impossible to always make these hold
......@@ -4037,7 +4050,7 @@ public class SequenceChart
if (tMax.compareTo(simulationTime) < 0)
tMax = simulationTime;
Assert.isTrue(tMin.compareTo(tMax) <= 0);
//Assert.isTrue(tMin.compareTo(tMax) <= 0);
// the idea is to round the simulation time to the shortest (in terms of digits) value
// as long as it still fits into the range of min and max
......
......@@ -44,6 +44,8 @@ SequenceChartFacade::SequenceChartFacade(IEventLog *eventLog) : EventLogFacade(e
biggestEarliestProcessingTime = 0;
biggestEndTimeEvent = NULL;
cachedParallelSet.clear();
cachedCriticalPath.clear();
}
......@@ -459,7 +461,8 @@ simtime_t SequenceChartFacade::getSimulationTimeForTimelineCoordinate(double tim
break;
case SIMULATION_TIME:
{
simtime_t lastEventSimulationTime = eventLog->getLastEvent()->getSimulationTime();
IEvent* largestEvent = (IEvent*) getLargestEndtimeInEventRange((ptr_t)(eventLog->getFirstEvent()),(ptr_t)(eventLog->getLastEvent()), upperLimit);
simtime_t lastEventSimulationTime= largestEvent->getSimulationTime() + largestEvent->getEventEntry()->duration;
simulationTime = max(BigDecimal::Zero, min(lastEventSimulationTime, timelineCoordinate + timelineCoordinateOriginSimulationTime));
}
break;
......@@ -501,9 +504,9 @@ simtime_t SequenceChartFacade::getSimulationTimeForTimelineCoordinate(double tim
Assert(!simulationTime.isNaN());
Assert(simulationTime >= BigDecimal::Zero);
if (timelineMode != REAL_TIME)
/*if (timelineMode != REAL_TIME)
Assert(simulationTime <= eventLog->getLastEvent()->getSimulationTime());
*/
return simulationTime;
}
......@@ -515,9 +518,9 @@ double SequenceChartFacade::getTimelineCoordinateForSimulationTime(simtime_t sim
return 0;
Assert(simulationTime >= BigDecimal::Zero);
if (timelineMode != REAL_TIME)
/*if (timelineMode != REAL_TIME)
Assert(simulationTime <= eventLog->getLastEvent()->getSimulationTime());
*/
double timelineCoordinate;
......@@ -990,28 +993,36 @@ void SequenceChartFacade::calculateCriticalPath() {
* Returns the event with the largest calculated earliest Processing time in REAL_TIME mode
* or the largest endtime in other modes within the given event range.
*/
ptr_t SequenceChartFacade::getLargestEndtimeInEventRange(ptr_t startEventPtr, ptr_t endEventPtr) {
IEvent *startEvent = (IEvent *)startEventPtr;
IEvent *endEvent = (IEvent *)endEventPtr;
ptr_t SequenceChartFacade::getLargestEndtimeInEventRange(ptr_t startEventPtr,
ptr_t endEventPtr, bool duration)
{
IEvent *startEvent = (IEvent *) startEventPtr;
IEvent *endEvent = (IEvent *) endEventPtr;
switch (timelineMode)
{
case REAL_TIME:
{
//Use cached result when range contains all events
if(startEvent == eventLog->getFirstEvent() && endEvent == eventLog->getLastEvent()) {
return (ptr_t)biggestEarliestProcessingTimeEvent;
if (startEvent == eventLog->getFirstEvent() && endEvent
== eventLog->getLastEvent())
{
return (ptr_t) biggestEarliestProcessingTimeEvent;
}
long largest = 0;
IEvent* largestEvent = startEvent;
for (IEvent* current = startEvent; current; current = current->getNextEvent()) {
for (IEvent* current = startEvent; current; current
= current->getNextEvent())
{
long temp = current->getEarliestProcessingTime();
if (temp > largest) {
if (temp > largest)
{
largest = temp;
largestEvent = current;
}
if (current==endEvent) {
if (current == endEvent)
{
break;
}
}
......@@ -1022,7 +1033,43 @@ ptr_t SequenceChartFacade::getLargestEndtimeInEventRange(ptr_t startEventPtr, pt
case STEP:
case NONLINEAR:
default:
return endEventPtr;
{
if (!duration) {
return endEventPtr;
}
//Use cached result when range contains all events
if (startEvent == eventLog->getFirstEvent() && endEvent
== eventLog->getLastEvent() && biggestEndTimeEvent != NULL)
{
return (ptr_t) biggestEndTimeEvent;
}
simtime_t largest = 0;
IEvent* largestEvent = endEvent;
for (IEvent* current = endEvent; current; current
= current->getPreviousEvent())
{
simtime_t temp = current->getSimulationTime()
+ current->getEventEntry()->duration;
if (temp > largest)
{
largest = temp;
largestEvent = current;
}
if (current == startEvent)
{
break;
}
}
if (startEvent == eventLog->getFirstEvent() && endEvent
== eventLog->getLastEvent())
{
biggestEndTimeEvent = largestEvent;
}
return (ptr_t) largestEvent;
}
}
}
......@@ -55,6 +55,8 @@ class EVENTLOG_API SequenceChartFacade : public EventLogFacade
simtime_t biggestEarliestProcessingTime;
IEvent* biggestEarliestProcessingTimeEvent;
IEvent* biggestEndTimeEvent;
std::set<ptr_t> cachedParallelSet;
IEvent* lastSelected;
......@@ -126,7 +128,7 @@ class EVENTLOG_API SequenceChartFacade : public EventLogFacade
bool isOnCriticalPath(IEvent* event);
ptr_t getLargestEndtimeInEventRange(ptr_t startEventPtr, ptr_t endEventPtr);
ptr_t getLargestEndtimeInEventRange(ptr_t startEventPtr, ptr_t endEventPtr, bool duration=false);
/**
* Timeline coordinate can be given in the range (-infinity, +infinity).
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment