diff --git a/src/plugins/qmlprofiler/abstracttimelinemodel.cpp b/src/plugins/qmlprofiler/abstracttimelinemodel.cpp index f9f5fe1874d..a3b486dedc6 100644 --- a/src/plugins/qmlprofiler/abstracttimelinemodel.cpp +++ b/src/plugins/qmlprofiler/abstracttimelinemodel.cpp @@ -35,7 +35,7 @@ namespace QmlProfiler { AbstractTimelineModel::AbstractTimelineModel(AbstractTimelineModelPrivate *dd, const QString &displayName, QmlDebug::Message message, QmlDebug::RangeType rangeType, QObject *parent) : - QObject(parent), d_ptr(dd) + SortedTimelineModel(parent), d_ptr(dd) { Q_D(AbstractTimelineModel); d->q_ptr = this; @@ -61,48 +61,6 @@ void AbstractTimelineModel::setModelManager(QmlProfilerModelManager *modelManage d->modelId = d->modelManager->registerModelProxy(); } -int AbstractTimelineModel::count() const -{ - Q_D(const AbstractTimelineModel); - return d->count(); -} - -int AbstractTimelineModel::firstIndex(qint64 startTime) const -{ - Q_D(const AbstractTimelineModel); - return d->firstIndex(startTime); -} - -int AbstractTimelineModel::firstIndexNoParents(qint64 startTime) const -{ - Q_D(const AbstractTimelineModel); - return d->firstIndexNoParents(startTime); -} - -int AbstractTimelineModel::lastIndex(qint64 endTime) const -{ - Q_D(const AbstractTimelineModel); - return d->lastIndex(endTime); -} - -qint64 AbstractTimelineModel::duration(int index) const -{ - Q_D(const AbstractTimelineModel); - return d->duration(index); -} - -qint64 AbstractTimelineModel::startTime(int index) const -{ - Q_D(const AbstractTimelineModel); - return d->startTime(index); -} - -qint64 AbstractTimelineModel::endTime(int index) const -{ - Q_D(const AbstractTimelineModel); - return d->startTime(index) + d->duration(index); -} - bool AbstractTimelineModel::isEmpty() const { return count() == 0; @@ -241,8 +199,6 @@ void AbstractTimelineModel::dataChanged() default: break; } - - d->rowOffsets.clear(); } bool AbstractTimelineModel::accepted(const QmlProfilerDataModel::QmlEventTypeData &event) const @@ -272,4 +228,19 @@ QString AbstractTimelineModel::displayName() const return d->displayName; } +void AbstractTimelineModel::clear() +{ + Q_D(AbstractTimelineModel); + bool wasExpanded = d->expanded; + bool hadRowHeights = !d->rowOffsets.empty(); + d->rowOffsets.clear(); + d->expanded = false; + SortedTimelineModel::clear(); + if (hadRowHeights) + emit rowHeightChanged(); + if (wasExpanded) + emit expandedChanged(); + d->modelManager->modelProxyCountUpdated(d->modelId, 0, 1); +} + } diff --git a/src/plugins/qmlprofiler/abstracttimelinemodel.h b/src/plugins/qmlprofiler/abstracttimelinemodel.h index d5a2409ad69..525a7263a68 100644 --- a/src/plugins/qmlprofiler/abstracttimelinemodel.h +++ b/src/plugins/qmlprofiler/abstracttimelinemodel.h @@ -34,13 +34,13 @@ #include "qmlprofiler_global.h" #include "qmlprofilermodelmanager.h" #include "qmlprofilerdatamodel.h" -#include +#include "sortedtimelinemodel.h" #include #include namespace QmlProfiler { -class QMLPROFILER_EXPORT AbstractTimelineModel : public QObject +class QMLPROFILER_EXPORT AbstractTimelineModel : public SortedTimelineModel { Q_OBJECT @@ -61,13 +61,6 @@ public: qint64 traceStartTime() const; qint64 traceEndTime() const; qint64 traceDuration() const; - qint64 duration(int index) const; - qint64 startTime(int index) const; - qint64 endTime(int index) const; - int firstIndex(qint64 startTime) const; - int firstIndexNoParents(qint64 startTime) const; - int lastIndex(qint64 endTime) const; - int count() const; bool accepted(const QmlProfilerDataModel::QmlEventTypeData &event) const; bool expanded() const; void setExpanded(bool expanded); @@ -81,7 +74,6 @@ public: virtual QVariantMap details(int index) const = 0; virtual int row(int index) const = 0; virtual void loadData() = 0; - virtual void clear() = 0; // Methods which can optionally be implemented by child models. // returned map should contain "file", "line", "column" properties, or be empty @@ -92,6 +84,7 @@ public: virtual float height(int index) const; virtual int rowMinValue(int rowNumber) const; virtual int rowMaxValue(int rowNumber) const; + virtual void clear(); signals: void expandedChanged(); diff --git a/src/plugins/qmlprofiler/abstracttimelinemodel_p.h b/src/plugins/qmlprofiler/abstracttimelinemodel_p.h index 0ff7c85b577..421adb3b99d 100644 --- a/src/plugins/qmlprofiler/abstracttimelinemodel_p.h +++ b/src/plugins/qmlprofiler/abstracttimelinemodel_p.h @@ -36,17 +36,6 @@ namespace QmlProfiler { class QMLPROFILER_EXPORT AbstractTimelineModel::AbstractTimelineModelPrivate { public: - virtual ~AbstractTimelineModelPrivate() {} - - virtual int count() const = 0; - virtual qint64 duration(int index) const = 0; - virtual qint64 startTime(int index) const = 0; - virtual qint64 lastEndTime() const = 0; - virtual qint64 firstStartTime() const = 0; - virtual int firstIndex(qint64 startTime) const = 0; - virtual int firstIndexNoParents(qint64 startTime) const = 0; - virtual int lastIndex(qint64 endTime) const = 0; - QVector rowOffsets; QmlProfilerModelManager *modelManager; int modelId; diff --git a/src/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.cpp b/src/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.cpp index f958b6ad11b..3d3760170be 100644 --- a/src/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.cpp @@ -30,7 +30,6 @@ #include "qmlprofilerpainteventsmodelproxy.h" #include "qmlprofilermodelmanager.h" #include "qmlprofilerdatamodel.h" -#include "sortedtimelinemodel.h" #include "abstracttimelinemodel_p.h" #include #include @@ -46,12 +45,10 @@ namespace QmlProfiler { namespace Internal { -class PaintEventsModelProxy::PaintEventsModelProxyPrivate : - public SortedTimelineModel +class PaintEventsModelProxy::PaintEventsModelProxyPrivate : public AbstractTimelineModelPrivate { public: - + QVector data; int maxGuiThreadAnimations; int maxRenderThreadAnimations; int rowFromThreadId(QmlDebug::AnimationThread threadId) const; @@ -72,10 +69,9 @@ PaintEventsModelProxy::PaintEventsModelProxy(QObject *parent) void PaintEventsModelProxy::clear() { Q_D(PaintEventsModelProxy); - d->clear(); d->maxGuiThreadAnimations = d->maxRenderThreadAnimations = 0; - d->expanded = false; - d->modelManager->modelProxyCountUpdated(d->modelId, 0, 1); + d->data.clear(); + AbstractTimelineModel::clear(); } bool PaintEventsModelProxy::accepted(const QmlProfilerDataModel::QmlEventTypeData &event) const @@ -125,7 +121,7 @@ void PaintEventsModelProxy::loadData() lastEvent.animationcount = (int)event.numericData2; QTC_ASSERT(lastEvent.animationcount > 0, continue); - d->insert(realStartTime, realEndTime - realStartTime, lastEvent); + d->data.insert(insert(realStartTime, realEndTime - realStartTime), lastEvent); if (lastEvent.threadId == QmlDebug::GuiThread) d->maxGuiThreadAnimations = qMax(lastEvent.animationcount, d->maxGuiThreadAnimations); @@ -135,10 +131,10 @@ void PaintEventsModelProxy::loadData() minNextStartTimes[lastEvent.threadId] = event.startTime + 1; - d->modelManager->modelProxyCountUpdated(d->modelId, d->count(), referenceList.count()); + d->modelManager->modelProxyCountUpdated(d->modelId, count(), referenceList.count()); } - d->computeNesting(); + computeNesting(); d->modelManager->modelProxyCountUpdated(d->modelId, 1, 1); } @@ -163,7 +159,7 @@ int PaintEventsModelProxy::PaintEventsModelProxyPrivate::rowFromThreadId( int PaintEventsModelProxy::row(int index) const { Q_D(const PaintEventsModelProxy); - return d->rowFromThreadId(d->range(index).threadId); + return d->rowFromThreadId(d->data[index].threadId); } int PaintEventsModelProxy::rowMaxValue(int rowNumber) const @@ -183,13 +179,13 @@ int PaintEventsModelProxy::rowMaxValue(int rowNumber) const int PaintEventsModelProxy::eventId(int index) const { Q_D(const PaintEventsModelProxy); - return d->range(index).threadId; + return d->data[index].threadId; } QColor PaintEventsModelProxy::color(int index) const { Q_D(const PaintEventsModelProxy); - double fpsFraction = d->range(index).framerate / 60.0; + double fpsFraction = d->data[index].framerate / 60.0; if (fpsFraction > 1.0) fpsFraction = 1.0; if (fpsFraction < 0.0) @@ -200,16 +196,16 @@ QColor PaintEventsModelProxy::color(int index) const float PaintEventsModelProxy::height(int index) const { Q_D(const PaintEventsModelProxy); - const PaintEventsModelProxyPrivate::Range &range = d->range(index); + const QmlPaintEventData &data = d->data[index]; // Add some height to the events if we're far from the scale threshold of 2 * DefaultRowHeight. // Like that you can see the smaller events more easily. - int scaleThreshold = 2 * DefaultRowHeight - rowHeight(d->rowFromThreadId(range.threadId)); + int scaleThreshold = 2 * DefaultRowHeight - rowHeight(d->rowFromThreadId(data.threadId)); float boost = scaleThreshold > 0 ? (0.15 * scaleThreshold / DefaultRowHeight) : 0; - return boost + (1.0 - boost) * (float)range.animationcount / - (float)(range.threadId == QmlDebug::GuiThread ? d->maxGuiThreadAnimations : - d->maxRenderThreadAnimations); + return boost + (1.0 - boost) * (float)data.animationcount / + (float)(data.threadId == QmlDebug::GuiThread ? d->maxGuiThreadAnimations : + d->maxRenderThreadAnimations); } QVariantList PaintEventsModelProxy::labels() const @@ -242,10 +238,10 @@ QVariantMap PaintEventsModelProxy::details(int index) const QVariantMap result; result.insert(QStringLiteral("displayName"), displayName()); - result.insert(tr("Duration"), QmlProfilerBaseModel::formatTime(d->range(index).duration)); - result.insert(tr("Framerate"), QString::fromLatin1("%1 FPS").arg(d->range(index).framerate)); - result.insert(tr("Animations"), QString::fromLatin1("%1").arg(d->range(index).animationcount)); - result.insert(tr("Context"), tr(d->range(index).threadId == QmlDebug::GuiThread ? + result.insert(tr("Duration"), QmlProfilerBaseModel::formatTime(range(index).duration)); + result.insert(tr("Framerate"), QString::fromLatin1("%1 FPS").arg(d->data[index].framerate)); + result.insert(tr("Animations"), QString::fromLatin1("%1").arg(d->data[index].animationcount)); + result.insert(tr("Context"), tr(d->data[index].threadId == QmlDebug::GuiThread ? "GUI Thread" : "Render Thread")); return result; } diff --git a/src/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.cpp b/src/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.cpp index 58455f80ca1..3482025e3c6 100644 --- a/src/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.cpp @@ -30,7 +30,6 @@ #include "qmlprofilertimelinemodelproxy.h" #include "qmlprofilermodelmanager.h" #include "qmlprofilerdatamodel.h" -#include "sortedtimelinemodel.h" #include "abstracttimelinemodel_p.h" #include @@ -45,9 +44,7 @@ namespace QmlProfiler { namespace Internal { -class RangeTimelineModel::RangeTimelineModelPrivate : - public SortedTimelineModel +class RangeTimelineModel::RangeTimelineModelPrivate : public AbstractTimelineModelPrivate { public: // convenience functions @@ -55,6 +52,7 @@ public: void computeExpandedLevels(); void findBindingLoops(); + QVector data; QVector expandedRowTypes; int contractedRows; bool seenPaintEvent; @@ -68,7 +66,6 @@ RangeTimelineModel::RangeTimelineModel(QmlDebug::RangeType rangeType, QObject *p { Q_D(RangeTimelineModel); d->seenPaintEvent = false; - d->expandedRowTypes.clear(); d->expandedRowTypes << -1; d->contractedRows = 1; } @@ -76,14 +73,12 @@ RangeTimelineModel::RangeTimelineModel(QmlDebug::RangeType rangeType, QObject *p void RangeTimelineModel::clear() { Q_D(RangeTimelineModel); - d->clear(); d->expandedRowTypes.clear(); d->expandedRowTypes << -1; d->contractedRows = 1; d->seenPaintEvent = false; - d->expanded = false; - - d->modelManager->modelProxyCountUpdated(d->modelId, 0, 1); + d->data.clear(); + AbstractTimelineModel::clear(); } void RangeTimelineModel::loadData() @@ -105,15 +100,15 @@ void RangeTimelineModel::loadData() d->seenPaintEvent = true; // store starttime-based instance - d->insert(event.startTime, event.duration, QmlRangeEventStartInstance(event.typeIndex)); - - d->modelManager->modelProxyCountUpdated(d->modelId, d->count(), eventList.count() * 6); + d->data.insert(insert(event.startTime, event.duration), + QmlRangeEventStartInstance(event.typeIndex)); + d->modelManager->modelProxyCountUpdated(d->modelId, count(), eventList.count() * 6); } d->modelManager->modelProxyCountUpdated(d->modelId, 2, 6); // compute range nesting - d->computeNesting(); + computeNesting(); // compute nestingLevel - nonexpanded d->computeNestingContracted(); @@ -134,8 +129,9 @@ void RangeTimelineModel::loadData() void RangeTimelineModel::RangeTimelineModelPrivate::computeNestingContracted() { + Q_Q(RangeTimelineModel); int i; - int eventCount = count(); + int eventCount = q->count(); int nestingLevels = QmlDebug::Constants::QML_MIN_LEVEL; contractedRows = nestingLevels + 1; @@ -143,7 +139,7 @@ void RangeTimelineModel::RangeTimelineModelPrivate::computeNestingContracted() nestingEndTimes.fill(0, nestingLevels + 1); for (i = 0; i < eventCount; i++) { - qint64 st = ranges[i].start; + qint64 st = q->ranges[i].start; // per type if (nestingEndTimes[nestingLevels] > st) { @@ -156,57 +152,57 @@ void RangeTimelineModel::RangeTimelineModelPrivate::computeNestingContracted() nestingEndTimes[nestingLevels-1] <= st) nestingLevels--; } - nestingEndTimes[nestingLevels] = st + ranges[i].duration; + nestingEndTimes[nestingLevels] = st + q->ranges[i].duration; - ranges[i].displayRowCollapsed = nestingLevels; + data[i].displayRowCollapsed = nestingLevels; } } void RangeTimelineModel::RangeTimelineModelPrivate::computeExpandedLevels() { + Q_Q(RangeTimelineModel); QHash eventRow; - int eventCount = count(); + int eventCount = q->count(); for (int i = 0; i < eventCount; i++) { - int eventId = ranges[i].eventId; + int eventId = data[i].eventId; if (!eventRow.contains(eventId)) { eventRow[eventId] = expandedRowTypes.size(); expandedRowTypes << eventId; } - ranges[i].displayRowExpanded = eventRow[eventId]; + data[i].displayRowExpanded = eventRow[eventId]; } } void RangeTimelineModel::RangeTimelineModelPrivate::findBindingLoops() { + Q_Q(RangeTimelineModel); if (rangeType != QmlDebug::Binding && rangeType != QmlDebug::HandlingSignal) return; typedef QPair CallStackEntry; QStack callStack; - for (int i = 0; i < count(); ++i) { - Range *event = &ranges[i]; - + for (int i = 0; i < q->count(); ++i) { const Range *potentialParent = callStack.isEmpty() - ? 0 : &ranges[callStack.top().second]; + ? 0 : &q->ranges[callStack.top().second]; while (potentialParent - && !(potentialParent->start + potentialParent->duration > event->start)) { + && !(potentialParent->start + potentialParent->duration > q->ranges[i].start)) { callStack.pop(); potentialParent = callStack.isEmpty() ? 0 - : &ranges[callStack.top().second]; + : &q->ranges[callStack.top().second]; } // check whether event is already in stack for (int ii = 0; ii < callStack.size(); ++ii) { - if (callStack.at(ii).first == event->eventId) { - event->bindingLoopHead = callStack.at(ii).second; + if (callStack.at(ii).first == data[i].eventId) { + data[i].bindingLoopHead = callStack.at(ii).second; break; } } - CallStackEntry newEntry(event->eventId, i); + CallStackEntry newEntry(data[i].eventId, i); callStack.push(newEntry); } @@ -243,21 +239,21 @@ int RangeTimelineModel::row(int index) const { Q_D(const RangeTimelineModel); if (d->expanded) - return d->range(index).displayRowExpanded; + return d->data[index].displayRowExpanded; else - return d->range(index).displayRowCollapsed; + return d->data[index].displayRowCollapsed; } int RangeTimelineModel::eventId(int index) const { Q_D(const RangeTimelineModel); - return d->range(index).eventId; + return d->data[index].eventId; } int RangeTimelineModel::bindingLoopDest(int index) const { Q_D(const RangeTimelineModel); - return d->range(index).bindingLoopHead; + return d->data[index].bindingLoopHead; } QColor RangeTimelineModel::color(int index) const @@ -296,7 +292,7 @@ QVariantMap RangeTimelineModel::details(int index) const d->modelManager->qmlModel()->getEventTypes(); result.insert(QStringLiteral("displayName"), categoryLabel(d->rangeType)); - result.insert(tr("Duration"), QmlProfilerBaseModel::formatTime(d->range(index).duration)); + result.insert(tr("Duration"), QmlProfilerBaseModel::formatTime(range(index).duration)); QString detailsString = types[id].data; if (detailsString.length() > 40) diff --git a/src/plugins/qmlprofiler/sortedtimelinemodel.cpp b/src/plugins/qmlprofiler/sortedtimelinemodel.cpp index 2e13417b845..3ee4e27d045 100644 --- a/src/plugins/qmlprofiler/sortedtimelinemodel.cpp +++ b/src/plugins/qmlprofiler/sortedtimelinemodel.cpp @@ -27,6 +27,9 @@ ** ****************************************************************************/ +#include "sortedtimelinemodel.h" +namespace QmlProfiler { + /*! \class QmlProfiler::SortedTimelineModel \brief The SortedTimelineModel class provides a sorted model for timeline data. @@ -49,6 +52,11 @@ \fn SortedTimelineModel::clear() Clears the ranges and their end times. */ +void SortedTimelineModel::clear() +{ + ranges.clear(); + endTimes.clear(); +} /*! \fn int SortedTimelineModel::count() const @@ -66,18 +74,13 @@ */ /*! - \fn const SortedTimelineModel::Range &SortedTimelineModel::range(int index) const + \fn const SortedTimelineModel::Range &SortedTimelineModel::range(int index) const Returns the range data at the specified index. */ /*! - \fn Data &SortedTimelineModel::data(int index) - Returns modifiable user data for the range at the specified index. -*/ - -/*! - \fn int SortedTimelineModel::insert(qint64 startTime, qint64 duration, const Data &item) - Inserts the given data at the given time position and returns its index. + \fn int SortedTimelineModel::insert(qint64 startTime, qint64 duration) + Inserts a range at the given time position and returns its index. */ /*! @@ -114,7 +117,48 @@ */ /*! - \fn void computeNesting() + \fn void SortedTimelineModel::computeNesting() Compute all ranges' parents. \sa findFirstIndex */ +void SortedTimelineModel::computeNesting() +{ + QLinkedList parents; + for (int range = 0; range != count(); ++range) { + Range ¤t = ranges[range]; + for (QLinkedList::iterator parentIt = parents.begin();;) { + Range &parent = ranges[*parentIt]; + qint64 parentEnd = parent.start + parent.duration; + if (parentEnd < current.start) { + if (parent.start == current.start) { + if (parent.parent == -1) { + parent.parent = range; + } else { + Range &ancestor = ranges[parent.parent]; + if (ancestor.start == current.start && + ancestor.duration < current.duration) + parent.parent = range; + } + // Just switch the old parent range for the new, larger one + *parentIt = range; + break; + } else { + parentIt = parents.erase(parentIt); + } + } else if (parentEnd >= current.start + current.duration) { + // no need to insert + current.parent = *parentIt; + break; + } else { + ++parentIt; + } + + if (parentIt == parents.end()) { + parents.append(range); + break; + } + } + } +} + +} diff --git a/src/plugins/qmlprofiler/sortedtimelinemodel.h b/src/plugins/qmlprofiler/sortedtimelinemodel.h index 9412a457469..627cce62aa8 100644 --- a/src/plugins/qmlprofiler/sortedtimelinemodel.h +++ b/src/plugins/qmlprofiler/sortedtimelinemodel.h @@ -30,22 +30,21 @@ #ifndef SORTEDTIMELINEMODEL_H #define SORTEDTIMELINEMODEL_H -#include "abstracttimelinemodel_p.h" +#include "qmlprofiler_global.h" +#include #include #include namespace QmlProfiler { -// The template has to be inserted into the hierarchy of public/private classes when Data is known. -// Otherwise we'd have to add implementation details to the public headers. This is why the class to -// be derived from is given as template parameter. -template -class SortedTimelineModel : public Base { +class QMLPROFILER_EXPORT SortedTimelineModel : public QObject { + Q_OBJECT + public: - struct Range : public Data { - Range() : Data(), start(-1), duration(-1), parent(-1) {} - Range(qint64 start, qint64 duration, const Data &item) : - Data(item), start(start), duration(duration), parent(-1) {} + struct Range { + Range() : start(-1), duration(-1), parent(-1) {} + Range(qint64 start, qint64 duration) : + start(start), duration(duration), parent(-1) {} qint64 start; qint64 duration; int parent; @@ -61,37 +60,35 @@ public: inline qint64 timestamp() const {return end;} }; - void clear() - { - ranges.clear(); - endTimes.clear(); - } + SortedTimelineModel(QObject *parent = 0) : QObject(parent) {} + + void clear(); inline int count() const { return ranges.count(); } - qint64 duration(int index) const { return range(index).duration; } - qint64 startTime(int index) const { return range(index).start; } + qint64 duration(int index) const { return ranges[index].duration; } + qint64 startTime(int index) const { return ranges[index].start; } + qint64 endTime(int index) const { return ranges[index].start + ranges[index].duration; } inline qint64 lastEndTime() const { return endTimes.last().end; } inline qint64 firstStartTime() const { return ranges.first().start; } inline const Range &range(int index) const { return ranges[index]; } - inline Data &data(int index) { return ranges[index]; } - inline int insert(qint64 startTime, qint64 duration, const Data &item) + inline int insert(qint64 startTime, qint64 duration) { /* Doing insert-sort here is preferable as most of the time the times will actually be * presorted in the right way. So usually this will just result in appending. */ - int index = insertSorted(ranges, Range(startTime, duration, item)); + int index = insertSorted(ranges, Range(startTime, duration)); if (index < ranges.size() - 1) incrementStartIndices(index); insertSorted(endTimes, RangeEnd(index, startTime + duration)); return index; } - inline int insertStart(qint64 startTime, const Data &item) + inline int insertStart(qint64 startTime) { - int index = insertSorted(ranges, Range(startTime, 0, item)); + int index = insertSorted(ranges, Range(startTime, 0)); if (index < ranges.size() - 1) incrementStartIndices(index); return index; @@ -138,47 +135,9 @@ public: return lowerBound(ranges, endTime); } - inline void computeNesting() - { - QLinkedList parents; - for (int range = 0; range != count(); ++range) { - Range ¤t = ranges[range]; - for (QLinkedList::iterator parentIt = parents.begin();;) { - Range &parent = ranges[*parentIt]; - qint64 parentEnd = parent.start + parent.duration; - if (parentEnd < current.start) { - if (parent.start == current.start) { - if (parent.parent == -1) { - parent.parent = range; - } else { - Range &ancestor = ranges[parent.parent]; - if (ancestor.start == current.start && - ancestor.duration < current.duration) - parent.parent = range; - } - // Just switch the old parent range for the new, larger one - *parentIt = range; - break; - } else { - parentIt = parents.erase(parentIt); - } - } else if (parentEnd >= current.start + current.duration) { - // no need to insert - current.parent = *parentIt; - break; - } else { - ++parentIt; - } - - if (parentIt == parents.end()) { - parents.append(range); - break; - } - } - } - } - protected: + void computeNesting(); + void incrementStartIndices(int index) { for (int i = 0; i < endTimes.size(); ++i) {