From 1f7c1e22c0f70c403140e7c04d28dc3b92ce94e1 Mon Sep 17 00:00:00 2001 From: Ben Kuper Date: Mon, 23 Dec 2024 19:44:40 +0100 Subject: [PATCH] Revamp Stagger Launchered, improved and stabilized --- Builds/VisualStudio2022/Chataigne_App.vcxproj | 4 + .../VisualStudio2022_CI/Chataigne_App.vcxproj | 4 + .../Chataigne_App.vcxproj | 4 + Chataigne.jucer | 6 +- JuceLibraryCode/AppConfig.h | 4 +- Source/ChataigneEngine.cpp | 2 + Source/Common/Processor/Action/Action.cpp | 4 +- .../Action/Consequence/ConsequenceManager.cpp | 532 +++++++++--------- .../Action/Consequence/ConsequenceManager.h | 193 ++++--- 9 files changed, 398 insertions(+), 355 deletions(-) diff --git a/Builds/VisualStudio2022/Chataigne_App.vcxproj b/Builds/VisualStudio2022/Chataigne_App.vcxproj index 2d9218ca0..f26d9db19 100644 --- a/Builds/VisualStudio2022/Chataigne_App.vcxproj +++ b/Builds/VisualStudio2022/Chataigne_App.vcxproj @@ -48,11 +48,15 @@ Chataigne true $(LibraryPath);../../External/kinect/lib;../../External/joycon/lib/win;../../External/servus/lib/win/x64/debug;../../External/dnssd/lib;../../External/sdl/lib/win;../../External/hidapi/lib/win/x64;../../External/mosquitto/lib/win;../../External/simpleble/lib/win/debug;..\..\Modules\juce_sharedtexture\libs\VisualStudio2022\$(Platform)\MDd;..\..\Modules\juce_simpleweb\libs\VisualStudio2022\$(Platform)\MDd + true + true .\..\..\Binaries\App\ $(Platform)\$(Configuration)\App\ Chataigne true $(LibraryPath);../../External/kinect/lib;../../External/joycon/lib/win;../../External/servus/lib/win/x64/release;../../External/dnssd/lib;../../External/sdl/lib/win;../../External/hidapi/lib/win/x64;../../External/mosquitto/lib/win;../../External/simpleble/lib/win/release;..\..\Modules\juce_sharedtexture\libs\VisualStudio2022\$(Platform)\MD;..\..\Modules\juce_simpleweb\libs\VisualStudio2022\$(Platform)\MD + true + true diff --git a/Builds/VisualStudio2022_CI/Chataigne_App.vcxproj b/Builds/VisualStudio2022_CI/Chataigne_App.vcxproj index 788a20e9b..93ac449a3 100644 --- a/Builds/VisualStudio2022_CI/Chataigne_App.vcxproj +++ b/Builds/VisualStudio2022_CI/Chataigne_App.vcxproj @@ -48,11 +48,15 @@ Chataigne true $(LibraryPath);../../External/kinect/lib;../../External/joycon/lib/win;../../External/servus/lib/win/x64/debug;../../External/dnssd/lib;../../External/sdl/lib/win;../../External/hidapi/lib/win/x64;../../External/mosquitto/lib/win;..\..\Modules\juce_sharedtexture\libs\VisualStudio2022\$(Platform)\MDd;..\..\Modules\juce_simpleweb\libs\VisualStudio2022\$(Platform)\MDd + true + true .\..\..\Binaries\CI\App\ $(Platform)\$(Configuration)\App\ Chataigne true $(LibraryPath);../../External/kinect/lib;../../External/joycon/lib/win;../../External/servus/lib/win/x64/release;../../External/dnssd/lib;../../External/sdl/lib/win;../../External/hidapi/lib/win/x64;../../External/mosquitto/lib/win;..\..\Modules\juce_sharedtexture\libs\VisualStudio2022\$(Platform)\MD;..\..\Modules\juce_simpleweb\libs\VisualStudio2022\$(Platform)\MD + true + true diff --git a/Builds/VisualStudio2022_Win7CI/Chataigne_App.vcxproj b/Builds/VisualStudio2022_Win7CI/Chataigne_App.vcxproj index d9ab3cf7a..8229167bd 100644 --- a/Builds/VisualStudio2022_Win7CI/Chataigne_App.vcxproj +++ b/Builds/VisualStudio2022_Win7CI/Chataigne_App.vcxproj @@ -48,11 +48,15 @@ Chataigne true $(LibraryPath);../../External/joycon/lib/win;../../External/servus/lib/win/x64/debug;../../External/dnssd/lib;../../External/sdl/lib/win;../../External/hidapi/lib/win/x64;../../External/mosquitto/lib/win;..\..\Modules\juce_sharedtexture\libs\VisualStudio2022\$(Platform)\MDd;..\..\Modules\juce_simpleweb\libs\VisualStudio2022\$(Platform)\MDd + true + true .\..\..\Binaries\CI\App\ $(Platform)\$(Configuration)\App\ Chataigne true $(LibraryPath);../../External/joycon/lib/win;../../External/servus/lib/win/x64/release;../../External/dnssd/lib;../../External/sdl/lib/win;../../External/hidapi/lib/win/x64;../../External/mosquitto/lib/win;..\..\Modules\juce_sharedtexture\libs\VisualStudio2022\$(Platform)\MD;..\..\Modules\juce_simpleweb\libs\VisualStudio2022\$(Platform)\MD + true + true diff --git a/Chataigne.jucer b/Chataigne.jucer index 596691b0b..46d9c3ef1 100644 --- a/Chataigne.jucer +++ b/Chataigne.jucer @@ -2011,9 +2011,9 @@ - boolValue() || forceDisabled) return; - + if (isClearing) return; + if (!forceChecking) { if (triggerTrue) csmOn->triggerAll(multiplexIndex); @@ -239,6 +240,7 @@ void Action::notifyActionTriggered(bool triggerTrue, int multiplexIndex) void Action::conditionManagerValidationChanged(ConditionManager*, int multiplexIndex, bool dispatchOnChangeOnly) { if (forceChecking) return; + if (isClearing) return; if (autoTriggerWhenAllConditionAreActives) { diff --git a/Source/Common/Processor/Action/Consequence/ConsequenceManager.cpp b/Source/Common/Processor/Action/Consequence/ConsequenceManager.cpp index 2822669d3..315037682 100644 --- a/Source/Common/Processor/Action/Consequence/ConsequenceManager.cpp +++ b/Source/Common/Processor/Action/Consequence/ConsequenceManager.cpp @@ -1,258 +1,274 @@ -/* - ============================================================================== - - ConsequenceManager.cpp - Created: 28 Oct 2016 8:07:30pm - Author: bkupe - - ============================================================================== -*/ - -#include "Common/Processor/ProcessorIncludes.h" - -ConsequenceManager::ConsequenceManager(const String& name, Multiplex* multiplex) : - BaseManager(name), - MultiplexTarget(multiplex), - killDelaysOnTrigger(nullptr), - forceDisabled(false), - csmNotifier(5) -{ - canBeDisabled = false; - canBeCopiedAndPasted = true; - - selectItemWhenCreated = false; - - factory.defs.add(MultiplexTargetDefinition::createDef("", "Consequence", multiplex)); - factory.defs.add(MultiplexTargetDefinition::createDef("", "Group", multiplex)); - - managerFactory = &factory; - - triggerPreview = addTrigger("Trigger", "Trigger all the consequences. Triggers at the previewed index if multiplexed"); - triggerPreview->hideInEditor = true; - - delay = addFloatParameter("Delay", "Delay the triggering of the commands", 0, 0); - delay->defaultUI = FloatParameter::TIME; - delay->hideInEditor = true; - stagger = addFloatParameter("Stagger", "If multiple consequences are there, delay between each consequence trigger", 0, 0); - stagger->defaultUI = FloatParameter::TIME; - stagger->hideInEditor = true; - - killDelaysOnTrigger = addBoolParameter("Cancel delays on Trigger", "If checked, this will ensure that when triggering, all previous delayed consequences are cancelled", false, false); - - staggerProgression = addFloatParameter("Stagger Progression", "If stagger is used, this animates the progression of the stagger", 0, 0, 1); - staggerProgression->hideInEditor = true; - staggerProgression->setControllableFeedbackOnly(true); -} - -ConsequenceManager::~ConsequenceManager() -{ - -} - - - - -void ConsequenceManager::triggerAll(int multiplexIndex) -{ - if (killDelaysOnTrigger->boolValue()) cancelDelayedConsequences(); - - if (items.size() > 0) - { - if (delay->floatValue() == 0 && stagger->floatValue() == 0) - { - for (auto& bi : items) - { - if (Consequence* c = dynamic_cast(bi)) c->triggerCommand(multiplexIndex); - else if (ConsequenceGroup* g = dynamic_cast(bi)) if (g->enabled->boolValue()) g->csm.triggerAll(multiplexIndex); - } - } - else - { - staggerLaunchers.add(new StaggerLauncher(this, multiplexIndex)); - } - } -} - -void ConsequenceManager::cancelDelayedConsequences() -{ - for (auto& launcher : staggerLaunchers) launcher->stopThread(100); - staggerLaunchers.clear(); -} - -void ConsequenceManager::setForceDisabled(bool value, bool force) -{ - if (forceDisabled == value && !force) return; - forceDisabled = value; - for (auto& i : items) - { - if (Consequence* c = dynamic_cast(i)) c->forceDisabled = value; - else if (ConsequenceGroup* g = dynamic_cast(i)) g->csm.setForceDisabled(value); - } -} - -void ConsequenceManager::updateKillDelayTrigger() -{ - bool showKill = items.size() > 1 && (delay->floatValue() > 0 || stagger->floatValue() > 0); - killDelaysOnTrigger->setEnabled(showKill); - -} - -void ConsequenceManager::onContainerTriggerTriggered(Trigger* t) -{ - if (forceDisabled) return; - - //for manual trigger eventually - if (t == triggerPreview) triggerAll(getPreviewIndex()); - - BaseManager::onContainerTriggerTriggered(t); -} - -void ConsequenceManager::onContainerParameterChanged(Parameter* p) -{ - BaseManager::onContainerParameterChanged(p); - if (p == delay || p == stagger) - { - updateKillDelayTrigger(); - } -} - -void ConsequenceManager::addItemInternal(BaseItem* bi, var data) -{ - if (Consequence* c = dynamic_cast(bi)) c->forceDisabled = forceDisabled; - else if (ConsequenceGroup* g = dynamic_cast(bi)) g->csm.setForceDisabled(forceDisabled); - - //triggerAll->hideInEditor = items.size() == 0; - delay->hideInEditor = items.size() == 0; - stagger->hideInEditor = items.size() < 2; - if (!isClearing) csmNotifier.addMessage(new ConsequenceManagerEvent(ConsequenceManagerEvent::STAGGER_CHANGED, this)); - updateKillDelayTrigger(); -} - -void ConsequenceManager::addItemsInternal(Array items, var data) -{ - for (auto& bi : items) - { - if (Consequence* c = dynamic_cast(bi)) c->forceDisabled = forceDisabled; - else if (ConsequenceGroup* g = dynamic_cast(bi)) g->csm.setForceDisabled(forceDisabled); - } - - //triggerAll->hideInEditor = items.size() == 0; - delay->hideInEditor = items.size() == 0; - stagger->hideInEditor = items.size() < 2; - if (!isClearing) csmNotifier.addMessage(new ConsequenceManagerEvent(ConsequenceManagerEvent::STAGGER_CHANGED, this)); - updateKillDelayTrigger(); -} - -void ConsequenceManager::removeItemInternal(BaseItem*) -{ - //triggerAll->hideInEditor = items.size() == 0; - delay->hideInEditor = items.size() == 0; - stagger->hideInEditor = items.size() < 2; - if (!isClearing) csmNotifier.addMessage(new ConsequenceManagerEvent(ConsequenceManagerEvent::STAGGER_CHANGED, this)); - updateKillDelayTrigger(); -} - -void ConsequenceManager::removeItemsInternal(Array) -{ - delay->hideInEditor = items.size() == 0; - stagger->hideInEditor = items.size() < 2; - if (!isClearing) csmNotifier.addMessage(new ConsequenceManagerEvent(ConsequenceManagerEvent::STAGGER_CHANGED, this)); - updateKillDelayTrigger(); -} - -void ConsequenceManager::launcherTriggered(StaggerLauncher* launcher) -{ - if (staggerLaunchers.size() == 0 || items.size() == 0) return; - if (launcher != staggerLaunchers.getLast()) return; - staggerProgression->setValue((launcher->triggerIndex + 1) * 1.0f / items.size()); -} - -void ConsequenceManager::launcherFinished(StaggerLauncher* launcher) -{ - MessageManager::getInstance()->callAsync([=]() - { - launcher->stopThread(100); - staggerLaunchers.removeObject(launcher); - } - ); -} - -InspectableEditor* ConsequenceManager::getEditorInternal(bool isRoot, Array inspectables) -{ - return new ConsequenceManagerEditor(this, CommandContext::ACTION, isRoot, isMultiplexed()); -} - -ConsequenceManager::StaggerLauncher::StaggerLauncher(ConsequenceManager* csm, int multiplexIndex) : - Thread("Stagger Launcher"), - csm(csm), - multiplexIndex(multiplexIndex) -{ - startThread(); -} - -ConsequenceManager::StaggerLauncher::~StaggerLauncher() -{ - if (Engine::mainEngine->isClearing) stopThread(1000); - else if (isThreadRunning()) - { - MessageManager::callAsync([this] { - stopThread(100); - }); - } -} - -void ConsequenceManager::StaggerLauncher::run() -{ - timeAtRun = Time::getMillisecondCounter(); - triggerIndex = 0; - - uint32 d = (uint32)(csm->delay->floatValue() * 1000); - uint32 s = (uint32)(csm->stagger->floatValue() * 1000); - - uint32 curTime = timeAtRun; - - Array consequencesToLaunch; - for (auto& bi : csm->items) - { - if (!bi->enabled->boolValue()) continue; - consequencesToLaunch.add(bi); - } - - while (!threadShouldExit() && triggerIndex < consequencesToLaunch.size()) - { - uint32 nextTriggerTime = timeAtRun + d + s * triggerIndex; - while (nextTriggerTime > curTime) - { - if (threadShouldExit()) break; - wait(jmin(nextTriggerTime - curTime, 20)); - curTime = Time::getMillisecondCounter(); - nextTriggerTime = timeAtRun + d + s * triggerIndex; - } - - if (triggerIndex >= consequencesToLaunch.size()) break; - BaseItem* bi = consequencesToLaunch[triggerIndex]; - - while (bi != nullptr && !bi->enabled->boolValue()) - { - triggerIndex++; - if (triggerIndex >= consequencesToLaunch.size()) break; - bi = csm->items[triggerIndex]; - } - - - if (threadShouldExit() || bi == nullptr) break; - - if (Consequence* c = dynamic_cast(bi)) c->triggerCommand(multiplexIndex); - else if (ConsequenceGroup* g = dynamic_cast(bi)) if (g->enabled->boolValue()) g->csm.triggerAll(multiplexIndex); - - csm->launcherTriggered(this); - triggerIndex++; - } - - if (!threadShouldExit()) csm->launcherFinished(this); -} - -void ConsequenceManager::multiplexPreviewIndexChanged() -{ - csmNotifier.addMessage(new ConsequenceManagerEvent(ConsequenceManagerEvent::MULTIPLEX_PREVIEW_CHANGED, this)); -} \ No newline at end of file +/* + ============================================================================== + + ConsequenceManager.cpp + Created: 28 Oct 2016 8:07:30pm + Author: bkupe + + ============================================================================== +*/ + +#include "Common/Processor/ProcessorIncludes.h" + +juce_ImplementSingleton(ConsequenceStaggerLauncher) + +ConsequenceManager::ConsequenceManager(const String& name, Multiplex* multiplex) : + BaseManager(name), + MultiplexTarget(multiplex), + killDelaysOnTrigger(nullptr), + forceDisabled(false), + csmNotifier(5) +{ + canBeDisabled = false; + canBeCopiedAndPasted = true; + + selectItemWhenCreated = false; + + factory.defs.add(MultiplexTargetDefinition::createDef("", "Consequence", multiplex)); + factory.defs.add(MultiplexTargetDefinition::createDef("", "Group", multiplex)); + + managerFactory = &factory; + + triggerPreview = addTrigger("Trigger", "Trigger all the consequences. Triggers at the previewed index if multiplexed"); + triggerPreview->hideInEditor = true; + + delay = addFloatParameter("Delay", "Delay the triggering of the commands", 0, 0); + delay->defaultUI = FloatParameter::TIME; + delay->hideInEditor = true; + stagger = addFloatParameter("Stagger", "If multiple consequences are there, delay between each consequence trigger", 0, 0); + stagger->defaultUI = FloatParameter::TIME; + stagger->hideInEditor = true; + + killDelaysOnTrigger = addBoolParameter("Cancel delays on Trigger", "If checked, this will ensure that when triggering, all previous delayed consequences are cancelled", false, false); + + staggerProgression = addFloatParameter("Stagger Progression", "If stagger is used, this animates the progression of the stagger", 0, 0, 1); + staggerProgression->hideInEditor = true; + staggerProgression->setControllableFeedbackOnly(true); +} + +ConsequenceManager::~ConsequenceManager() +{ + cancelDelayedConsequences(-1); +} + +void ConsequenceManager::triggerAll(int multiplexIndex) +{ + if (killDelaysOnTrigger->boolValue()) cancelDelayedConsequences(multiplexIndex); + + if (items.size() > 0) + { + if (delay->floatValue() == 0 && stagger->floatValue() == 0) + { + for (auto& bi : items) + { + if (Consequence* c = dynamic_cast(bi)) c->triggerCommand(multiplexIndex); + else if (ConsequenceGroup* g = dynamic_cast(bi)) if (g->enabled->boolValue()) g->csm.triggerAll(multiplexIndex); + } + } + else + { + ConsequenceStaggerLauncher::getInstance()->addLaunch(this, multiplexIndex); + } + } +} + +void ConsequenceManager::cancelDelayedConsequences(int multiplexIndex) +{ + ConsequenceStaggerLauncher::getInstance()->removeLaunchesFor(this, multiplexIndex); +} + +void ConsequenceManager::setForceDisabled(bool value, bool force) +{ + if (forceDisabled == value && !force) return; + forceDisabled = value; + for (auto& i : items) + { + if (Consequence* c = dynamic_cast(i)) c->forceDisabled = value; + else if (ConsequenceGroup* g = dynamic_cast(i)) g->csm.setForceDisabled(value); + } +} + +void ConsequenceManager::updateKillDelayTrigger() +{ + bool showKill = items.size() > 1 && (delay->floatValue() > 0 || stagger->floatValue() > 0); + killDelaysOnTrigger->setEnabled(showKill); + +} + +void ConsequenceManager::onContainerTriggerTriggered(Trigger* t) +{ + if (forceDisabled) return; + + //for manual trigger eventually + if (t == triggerPreview) triggerAll(getPreviewIndex()); + + BaseManager::onContainerTriggerTriggered(t); +} + +void ConsequenceManager::onContainerParameterChanged(Parameter* p) +{ + BaseManager::onContainerParameterChanged(p); + if (p == delay || p == stagger) + { + updateKillDelayTrigger(); + } +} + +void ConsequenceManager::addItemInternal(BaseItem* bi, var data) +{ + if (Consequence* c = dynamic_cast(bi)) c->forceDisabled = forceDisabled; + else if (ConsequenceGroup* g = dynamic_cast(bi)) g->csm.setForceDisabled(forceDisabled); + + //triggerAll->hideInEditor = items.size() == 0; + delay->hideInEditor = items.size() == 0; + stagger->hideInEditor = items.size() < 2; + if (!isClearing) csmNotifier.addMessage(new ConsequenceManagerEvent(ConsequenceManagerEvent::STAGGER_CHANGED, this)); + updateKillDelayTrigger(); +} + +void ConsequenceManager::addItemsInternal(Array items, var data) +{ + for (auto& bi : items) + { + if (Consequence* c = dynamic_cast(bi)) c->forceDisabled = forceDisabled; + else if (ConsequenceGroup* g = dynamic_cast(bi)) g->csm.setForceDisabled(forceDisabled); + } + + //triggerAll->hideInEditor = items.size() == 0; + delay->hideInEditor = items.size() == 0; + stagger->hideInEditor = items.size() < 2; + if (!isClearing) csmNotifier.addMessage(new ConsequenceManagerEvent(ConsequenceManagerEvent::STAGGER_CHANGED, this)); + updateKillDelayTrigger(); +} + +void ConsequenceManager::removeItemInternal(BaseItem*) +{ + //triggerAll->hideInEditor = items.size() == 0; + delay->hideInEditor = items.size() == 0; + stagger->hideInEditor = items.size() < 2; + if (!isClearing) csmNotifier.addMessage(new ConsequenceManagerEvent(ConsequenceManagerEvent::STAGGER_CHANGED, this)); + updateKillDelayTrigger(); +} + +void ConsequenceManager::removeItemsInternal(Array) +{ + delay->hideInEditor = items.size() == 0; + stagger->hideInEditor = items.size() < 2; + if (!isClearing) csmNotifier.addMessage(new ConsequenceManagerEvent(ConsequenceManagerEvent::STAGGER_CHANGED, this)); + updateKillDelayTrigger(); +} + +void ConsequenceManager::launcherTriggered(int multiplexIndex, int triggerIndex) +{ + staggerProgression->setValue((triggerIndex + 1) * 1.0f / items.size()); +} + + +InspectableEditor* ConsequenceManager::getEditorInternal(bool isRoot, Array inspectables) +{ + return new ConsequenceManagerEditor(this, CommandContext::ACTION, isRoot, isMultiplexed()); +} + +ConsequenceStaggerLauncher::ConsequenceStaggerLauncher() : + Thread("Stagger Launcher") +{ + startThread(); +} + +ConsequenceStaggerLauncher::~ConsequenceStaggerLauncher() +{ + stopThread(1000); +} + +void ConsequenceStaggerLauncher::run() +{ + Array toRemove; + + while (!threadShouldExit()) + { + { + GenericScopedLock lock(launches.getLock()); + for (auto& l : launches) + { + processLaunch(l); + if (l->isFinished()) toRemove.add(l); + } + + for (auto& l : toRemove) launches.removeObject(l); + + if (launches.isEmpty()) break; + } + + wait(10); + } + +} + +void ConsequenceStaggerLauncher::processLaunch(Launch* l) +{ + + ConsequenceManager* csm = l->manager; + uint32 d = (uint32)(csm->delay->floatValue() * 1000); + uint32 s = (uint32)(csm->stagger->floatValue() * 1000); + + //check if last item + if (l->triggerIndex >= csm->items.size()) return; + + + //get relative trigger index, not taking into account disabled items + int relativeIndex = 0; + for (int i = 0; i < l->triggerIndex; i++) if (csm->items[i]->enabled->boolValue()) relativeIndex++; + + //Check if should trigger + uint32 curTime = Time::getMillisecondCounter(); + uint32 triggerTime = l->startTime + d + s * relativeIndex; + + if (curTime < triggerTime) return; + + //Get first enabled item starting at index + { + GenericScopedLock lock(csm->items.getLock()); + BaseItem* bi = csm->items[l->triggerIndex]; + while (bi->enabled->boolValue() == false) + { + l->triggerIndex++; + if (l->triggerIndex >= csm->items.size()) return; + bi = csm->items[l->triggerIndex]; + } + + + if (Consequence* c = dynamic_cast(bi)) c->triggerCommand(l->multiplexIndex); + else if (ConsequenceGroup* g = dynamic_cast(bi)) if (g->enabled->boolValue()) g->csm.triggerAll(l->multiplexIndex); + } + + csm->launcherTriggered(l->multiplexIndex, l->triggerIndex); + l->triggerIndex++; +} + +void ConsequenceStaggerLauncher::addLaunch(ConsequenceManager* csm, int multiplexIndex) +{ + launches.add(new Launch(csm, multiplexIndex)); + if (!isThreadRunning()) startThread(); + else notify(); +} + +void ConsequenceStaggerLauncher::removeLaunchesFor(ConsequenceManager* manager, int multiplexIndex) +{ + GenericScopedLock lock(launches.getLock()); + Array toRemove; + for (auto& l : launches) + { + if (l->manager == manager && (multiplexIndex == -1 || l->multiplexIndex == multiplexIndex)) toRemove.add(l); + } + + for (auto& l : toRemove) launches.removeObject(l); +} + +void ConsequenceManager::multiplexPreviewIndexChanged() +{ + csmNotifier.addMessage(new ConsequenceManagerEvent(ConsequenceManagerEvent::MULTIPLEX_PREVIEW_CHANGED, this)); +} + +bool ConsequenceStaggerLauncher::Launch::isFinished() { + return triggerIndex >= manager->items.size(); +} diff --git a/Source/Common/Processor/Action/Consequence/ConsequenceManager.h b/Source/Common/Processor/Action/Consequence/ConsequenceManager.h index 8959da05e..ffaeb2d3d 100644 --- a/Source/Common/Processor/Action/Consequence/ConsequenceManager.h +++ b/Source/Common/Processor/Action/Consequence/ConsequenceManager.h @@ -1,92 +1,103 @@ -/* - ============================================================================== - - ConsequenceManager.h - Created: 28 Oct 2016 8:07:30pm - Author: bkupe - - ============================================================================== -*/ - -#pragma once - -class ConsequenceManager : - public BaseManager, - public MultiplexTarget, - public Consequence::ConsequenceListener -{ -public: - ConsequenceManager(const String& name = "Consequences", Multiplex* multiplex = nullptr); - ~ConsequenceManager(); - - Trigger* triggerPreview; - - FloatParameter* delay; - FloatParameter* stagger; - BoolParameter* killDelaysOnTrigger; - FloatParameter* staggerProgression; - - Factory factory; - - bool forceDisabled; - - - void triggerAll(int multiplexIndex = 0); - void cancelDelayedConsequences(); - - void setForceDisabled(bool value, bool force = false); - - void updateKillDelayTrigger(); - - void onContainerTriggerTriggered(Trigger*) override; - void onContainerParameterChanged(Parameter* p) override; - - - void addItemInternal(BaseItem*, var data) override; - void addItemsInternal(Array, var data) override; - void removeItemInternal(BaseItem*) override; - void removeItemsInternal(Array) override; - - class StaggerLauncher : - public Thread - { - public: - StaggerLauncher(ConsequenceManager* csm, int multiplexIndex); - ~StaggerLauncher(); - - ConsequenceManager* csm; - int multiplexIndex; - - uint32 timeAtRun; - int triggerIndex; - - void run() override; - }; - OwnedArray staggerLaunchers; - - void launcherTriggered(StaggerLauncher* launcher); - void launcherFinished(StaggerLauncher* launcher); - - void multiplexPreviewIndexChanged() override; - - InspectableEditor* getEditorInternal(bool isRoot, Array inspectables = Array()) override; - - class ConsequenceManagerListener - { - public: - virtual ~ConsequenceManagerListener() {} - virtual void consequenceEnableChanged(Consequence*) {} - virtual void consequenceValidationChanged(Consequence*) {} - virtual void consequenceTriggered(Consequence*) {} - }; - - - ListenerList consequenceManagerListeners; - void addConsequenceManagerListener(ConsequenceManagerListener* newListener) { consequenceManagerListeners.add(newListener); } - void removeConsequenceManagerListener(ConsequenceManagerListener* listener) { consequenceManagerListeners.remove(listener); } - - DECLARE_ASYNC_EVENT(ConsequenceManager, ConsequenceManager, csm, ENUM_LIST(MULTIPLEX_PREVIEW_CHANGED, STAGGER_CHANGED), EVENT_INSPECTABLE_CHECK); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ConsequenceManager) - +/* + ============================================================================== + + ConsequenceManager.h + Created: 28 Oct 2016 8:07:30pm + Author: bkupe + + ============================================================================== +*/ + +#pragma once + +class ConsequenceManager; + +class ConsequenceStaggerLauncher : + public Thread +{ +public: + juce_DeclareSingleton(ConsequenceStaggerLauncher, false) + + ConsequenceStaggerLauncher(); + ~ConsequenceStaggerLauncher(); + + struct Launch + { + Launch(ConsequenceManager* c, int multiplexIndex) : manager(c), startTime(Time::getMillisecondCounter()), multiplexIndex(multiplexIndex), triggerIndex(0) {} + + ConsequenceManager* manager; + uint32 startTime; + int multiplexIndex; + int triggerIndex; + + bool isFinished(); + }; + + OwnedArray launches; + + void run() override; + void processLaunch(Launch* l); + + void addLaunch(ConsequenceManager* c, int multiplexIndex); + void removeLaunchesFor(ConsequenceManager* manager, int multiplexIndex); +}; + +class ConsequenceManager : + public BaseManager, + public MultiplexTarget, + public Consequence::ConsequenceListener +{ +public: + ConsequenceManager(const String& name = "Consequences", Multiplex* multiplex = nullptr); + ~ConsequenceManager(); + + Trigger* triggerPreview; + + FloatParameter* delay; + FloatParameter* stagger; + BoolParameter* killDelaysOnTrigger; + FloatParameter* staggerProgression; + + Factory factory; + + bool forceDisabled; + + + void triggerAll(int multiplexIndex = 0); + void cancelDelayedConsequences(int multiplexIndex = 0); + + void setForceDisabled(bool value, bool force = false); + + void updateKillDelayTrigger(); + + void onContainerTriggerTriggered(Trigger*) override; + void onContainerParameterChanged(Parameter* p) override; + + + void addItemInternal(BaseItem*, var data) override; + void addItemsInternal(Array, var data) override; + void removeItemInternal(BaseItem*) override; + void removeItemsInternal(Array) override; + + void launcherTriggered(int multiplexIndex, int triggerIndex); + + void multiplexPreviewIndexChanged() override; + + InspectableEditor* getEditorInternal(bool isRoot, Array inspectables = Array()) override; + + class ConsequenceManagerListener + { + public: + virtual ~ConsequenceManagerListener() {} + virtual void consequenceEnableChanged(Consequence*) {} + virtual void consequenceValidationChanged(Consequence*) {} + virtual void consequenceTriggered(Consequence*) {} + }; + + + DECLARE_INSPECTACLE_SAFE_LISTENER(ConsequenceManager, consequenceManager); + + DECLARE_ASYNC_EVENT(ConsequenceManager, ConsequenceManager, csm, ENUM_LIST(MULTIPLEX_PREVIEW_CHANGED, STAGGER_CHANGED), EVENT_INSPECTABLE_CHECK); + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ConsequenceManager) }; \ No newline at end of file