From 444418e8c183af6536c567238d610e04cd9ebd12 Mon Sep 17 00:00:00 2001 From: Paul Date: Sun, 15 Sep 2024 14:06:47 -0400 Subject: [PATCH] Fix a problem with optimization 5bcfdb5400 (#1330) --- src/engine/group.cpp | 46 +++++++++++++++++++++++++------------------- src/engine/group.h | 2 ++ 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/engine/group.cpp b/src/engine/group.cpp index ce39b391..fef52710 100644 --- a/src/engine/group.cpp +++ b/src/engine/group.cpp @@ -179,11 +179,16 @@ template void Group::processWithOS(scxt::engine::Engine &e) } modMatrix.process(); + auto oAZ = activeZones; + rescanWeakRefs = 0; for (int i = 0; i < activeZones; ++i) { auto z = activeZoneWeakRefs[i]; assert(z->isActive()); z->process(e); + assert(z->isActive() || rescanWeakRefs > 0); + assert(oAZ == activeZones); + /* * This is just an optimization to not accumulate. The zone will * have already routed to the approprite other bus and output will @@ -204,6 +209,11 @@ template void Group::processWithOS(scxt::engine::Engine &e) } } + if (rescanWeakRefs) + { + postZoneTraversalRemoveHandler(); + } + // Groups are always unpitched and stereo auto fpitch = 0; bool processorConsumesMono[4]{false, false, false, false}; @@ -384,37 +394,33 @@ void Group::addActiveZone(engine::Zone *zwp) void Group::removeActiveZone(engine::Zone *zwp) { assert(activeZones); + rescanWeakRefs++; +} - // Manage the weak refs - // First find the zone - int zidx{-1}; - for (int idx = 0; idx < activeZones; ++idx) +void Group::postZoneTraversalRemoveHandler() +{ + /* + * Go backwards down the weak refs removing inactive ones + */ + assert(rescanWeakRefs); + assert(activeZones); + assert(activeZones >= rescanWeakRefs); + for (int i = activeZones - 1; i >= 0; --i) { - if (activeZoneWeakRefs[idx] == zwp) + if (!activeZoneWeakRefs[i]->isActive()) { - zidx = idx; - break; + rescanWeakRefs--; + activeZoneWeakRefs[i] = activeZoneWeakRefs[activeZones - 1]; + activeZones--; } } - assert(zidx >= 0); - // OK so now we want to swap the active zone from the end into my slot - activeZoneWeakRefs[zidx] = activeZoneWeakRefs[activeZones - 1]; - - activeZones--; + assert(rescanWeakRefs == 0); if (activeZones == 0) { ringoutMax = 0; ringoutTime = 0; updateRingout(); } - - /* - SCLOG("removeZone " << SCD(activeZones)); - for (int i = 0; i < activeZones; ++i) - { - SCLOG("removeZone " << activeZoneWeakRefs[i] << " " << activeZoneWeakRefs[i]->getName()); - } - */ } engine::Engine *Group::getEngine() diff --git a/src/engine/group.h b/src/engine/group.h index 6dcfc7c3..f80ea254 100644 --- a/src/engine/group.h +++ b/src/engine/group.h @@ -249,6 +249,8 @@ struct Group : MoveableOnly, private: zoneContainer_t zones; std::vector activeZoneWeakRefs; + uint32_t rescanWeakRefs{0}; + void postZoneTraversalRemoveHandler(); }; } // namespace scxt::engine