Skip to content

Commit

Permalink
Collect all time spanning descendants on first measure visit
Browse files Browse the repository at this point in the history
  • Loading branch information
brdvd committed Jan 31, 2024
1 parent a6d436e commit dd22633
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 24 deletions.
7 changes: 6 additions & 1 deletion include/vrv/preparedatafunctor.h
Original file line number Diff line number Diff line change
Expand Up @@ -493,18 +493,23 @@ class PrepareTimeSpanningFunctor : public Functor, public CollectAndProcess {
FunctorCode VisitF(F *f) override;
FunctorCode VisitFloatingObject(FloatingObject *floatingObject) override;
FunctorCode VisitLayerElement(LayerElement *layerElement) override;
FunctorCode VisitMeasure(Measure *measure) override;
FunctorCode VisitMeasureEnd(Measure *measure) override;
///@}

protected:
//
private:
//
// Delegates to the pseudo functor of the interface
FunctorCode CallPseudoFunctor(Object *timeSpanningObject);

public:
//
private:
// The interface list that holds the current elements to match
ListOfSpanningInterOwnerPairs m_timeSpanningInterfaces;
// Indicates whether we currently traverse a measure
bool m_insideMeasure;
};

//----------------------------------------------------------------------------
Expand Down
67 changes: 44 additions & 23 deletions src/preparedatafunctor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,10 @@ FunctorCode PrepareTimePointingFunctor::VisitMeasureEnd(Measure *measure)
// PrepareTimeSpanningFunctor
//----------------------------------------------------------------------------

PrepareTimeSpanningFunctor::PrepareTimeSpanningFunctor() : Functor(), CollectAndProcess() {}
PrepareTimeSpanningFunctor::PrepareTimeSpanningFunctor() : Functor(), CollectAndProcess()
{
m_insideMeasure = false;
}

void PrepareTimeSpanningFunctor::InsertInterfaceOwnerPair(Object *owner, TimeSpanningInterface *interface)
{
Expand All @@ -659,19 +662,16 @@ void PrepareTimeSpanningFunctor::InsertInterfaceOwnerPair(Object *owner, TimeSpa

FunctorCode PrepareTimeSpanningFunctor::VisitF(F *f)
{
// Pass it to the pseudo functor of the interface
TimeSpanningInterface *interface = f->GetTimeSpanningInterface();
assert(interface);
return interface->InterfacePrepareTimeSpanning(*this, f);
if (!m_insideMeasure) {
return this->CallPseudoFunctor(f);
}
return FUNCTOR_CONTINUE;
}

FunctorCode PrepareTimeSpanningFunctor::VisitFloatingObject(FloatingObject *floatingObject)
{
// Pass it to the pseudo functor of the interface
if (floatingObject->HasInterface(INTERFACE_TIME_SPANNING)) {
TimeSpanningInterface *interface = floatingObject->GetTimeSpanningInterface();
assert(interface);
return interface->InterfacePrepareTimeSpanning(*this, floatingObject);
if (!m_insideMeasure && floatingObject->HasInterface(INTERFACE_TIME_SPANNING)) {
return this->CallPseudoFunctor(floatingObject);
}
return FUNCTOR_CONTINUE;
}
Expand Down Expand Up @@ -699,28 +699,49 @@ FunctorCode PrepareTimeSpanningFunctor::VisitLayerElement(LayerElement *layerEle
return FUNCTOR_CONTINUE;
}

FunctorCode PrepareTimeSpanningFunctor::VisitMeasureEnd(Measure *measure)
FunctorCode PrepareTimeSpanningFunctor::VisitMeasure(Measure *measure)
{
if (this->IsProcessingData()) {
return FUNCTOR_CONTINUE;
if (this->IsCollectingData()) {
ListOfObjects timeSpanningObjects;
InterfaceComparison ic(INTERFACE_TIME_SPANNING);
measure->FindAllDescendantsByComparison(&timeSpanningObjects, &ic);
for (Object *object : timeSpanningObjects) {
this->CallPseudoFunctor(object);
}
}
m_insideMeasure = true;

ListOfSpanningInterOwnerPairs::iterator iter = m_timeSpanningInterfaces.begin();
while (iter != m_timeSpanningInterfaces.end()) {
// At the end of the measure (going backward) we remove elements for which we do not need to match the end (for
// now). Eventually, we could consider them, for example if we want to display their spanning or for improved
// midi output
if (iter->second->GetClassId() == HARM) {
iter = m_timeSpanningInterfaces.erase(iter);
}
else {
++iter;
return FUNCTOR_CONTINUE;
}

FunctorCode PrepareTimeSpanningFunctor::VisitMeasureEnd(Measure *measure)
{
if (this->IsCollectingData()) {
ListOfSpanningInterOwnerPairs::iterator iter = m_timeSpanningInterfaces.begin();
while (iter != m_timeSpanningInterfaces.end()) {
// At the end of the measure we remove elements for which we do not need to match the end (for now).
// Eventually, we could consider them, for example if we want to display their spanning or for
// improved midi output
if (iter->second->GetClassId() == HARM) {
iter = m_timeSpanningInterfaces.erase(iter);
}
else {
++iter;
}
}
}
m_insideMeasure = false;

return FUNCTOR_CONTINUE;
}

FunctorCode PrepareTimeSpanningFunctor::CallPseudoFunctor(Object *timeSpanningObject)
{
TimeSpanningInterface *interface = timeSpanningObject->GetTimeSpanningInterface();
assert(interface);
return interface->InterfacePrepareTimeSpanning(*this, timeSpanningObject);
}

//----------------------------------------------------------------------------
// PrepareTimestampsFunctor
//----------------------------------------------------------------------------
Expand Down

0 comments on commit dd22633

Please sign in to comment.