mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-23 12:24:29 +02:00
move switch logic around
This commit is contained in:
parent
8c032ea83f
commit
4a02ab4fe2
5 changed files with 187 additions and 94 deletions
|
@ -10,16 +10,34 @@
|
||||||
//
|
//
|
||||||
#include "RenderViewTask.h"
|
#include "RenderViewTask.h"
|
||||||
|
|
||||||
#include "AssembleLightingStageTask.h"
|
|
||||||
#include "RenderShadowTask.h"
|
#include "RenderShadowTask.h"
|
||||||
#include "RenderDeferredTask.h"
|
#include "RenderDeferredTask.h"
|
||||||
#include "RenderForwardTask.h"
|
#include "RenderForwardTask.h"
|
||||||
|
|
||||||
#include <DisableDeferred.h>
|
#include <DisableDeferred.h>
|
||||||
|
|
||||||
|
void RenderShadowsAndDeferredTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cullFunctor, uint8_t tagBits, uint8_t tagMask) {
|
||||||
|
const auto items = input.getN<DeferredForwardSwitchJob::Input>(0);
|
||||||
|
const auto lightingModel = input.getN<DeferredForwardSwitchJob::Input>(1);
|
||||||
|
const auto lightingStageFramesAndZones = input.getN<DeferredForwardSwitchJob::Input>(2);
|
||||||
|
|
||||||
|
// Warning : the cull functor passed to the shadow pass should only be testing for LOD culling. If frustum culling
|
||||||
|
// is performed, then casters not in the view frustum will be removed, which is not what we wish.
|
||||||
|
const auto shadowTaskIn = RenderShadowTask::Input(lightingStageFramesAndZones.get<AssembleLightingStageTask::Output>().get0()[0], lightingModel).asVarying();
|
||||||
|
const auto shadowTaskOut = task.addJob<RenderShadowTask>("RenderShadowTask", shadowTaskIn, cullFunctor, tagBits, tagMask);
|
||||||
|
|
||||||
|
const auto renderDeferredInput = RenderDeferredTask::Input(items, lightingModel, lightingStageFramesAndZones, shadowTaskOut).asVarying();
|
||||||
|
task.addJob<RenderDeferredTask>("RenderDeferredTask", renderDeferredInput);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeferredForwardSwitchJob::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cullFunctor, uint8_t tagBits, uint8_t tagMask) {
|
||||||
|
task.addBranch<RenderShadowsAndDeferredTask>("RenderShadowsAndDeferredTask", 0, input, cullFunctor, tagBits, tagMask);
|
||||||
|
|
||||||
|
task.addBranch<RenderForwardTask>("RenderForwardTask", 1, input);
|
||||||
|
}
|
||||||
|
|
||||||
void RenderViewTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cullFunctor, uint8_t tagBits, uint8_t tagMask) {
|
void RenderViewTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cullFunctor, uint8_t tagBits, uint8_t tagMask) {
|
||||||
const auto items = task.addJob<RenderFetchCullSortTask>("FetchCullSort", cullFunctor, tagBits, tagMask);
|
const auto items = task.addJob<RenderFetchCullSortTask>("FetchCullSort", cullFunctor, tagBits, tagMask);
|
||||||
assert(items.canCast<RenderFetchCullSortTask::Output>());
|
|
||||||
|
|
||||||
// Issue the lighting model, aka the big global settings for the view
|
// Issue the lighting model, aka the big global settings for the view
|
||||||
const auto lightingModel = task.addJob<MakeLightingModel>("LightingModel");
|
const auto lightingModel = task.addJob<MakeLightingModel>("LightingModel");
|
||||||
|
@ -28,16 +46,8 @@ void RenderViewTask::build(JobModel& task, const render::Varying& input, render:
|
||||||
const auto lightingStageFramesAndZones = task.addJob<AssembleLightingStageTask>("AssembleStages", items);
|
const auto lightingStageFramesAndZones = task.addJob<AssembleLightingStageTask>("AssembleStages", items);
|
||||||
|
|
||||||
if (!DISABLE_DEFERRED) {
|
if (!DISABLE_DEFERRED) {
|
||||||
// Warning : the cull functor passed to the shadow pass should only be testing for LOD culling. If frustum culling
|
const auto deferredForwardIn = DeferredForwardSwitchJob::Input(items, lightingModel, lightingStageFramesAndZones).asVarying();
|
||||||
// is performed, then casters not in the view frustum will be removed, which is not what we wish.
|
task.addJob<DeferredForwardSwitchJob>("DeferredForwardSwitch", deferredForwardIn, cullFunctor, tagBits, tagMask);
|
||||||
const auto shadowTaskIn = RenderShadowTask::Input(lightingStageFramesAndZones.get<AssembleLightingStageTask::Output>().get0()[0], lightingModel).asVarying();
|
|
||||||
const auto shadowTaskOut = task.addSwitchJob<RenderShadowTask>("RenderShadowTask", 0, shadowTaskIn, cullFunctor, tagBits, tagMask);
|
|
||||||
|
|
||||||
const auto renderDeferredInput = RenderDeferredTask::Input(items, lightingModel, lightingStageFramesAndZones, shadowTaskOut).asVarying();
|
|
||||||
task.addSwitchJob<RenderDeferredTask>("RenderDeferredTask", 0, renderDeferredInput);
|
|
||||||
|
|
||||||
const auto renderForwardInput = RenderForwardTask::Input(items, lightingModel, lightingStageFramesAndZones).asVarying();
|
|
||||||
task.addSwitchJob<RenderForwardTask>("RenderForwardTask", 1, renderForwardInput);
|
|
||||||
} else {
|
} else {
|
||||||
const auto renderInput = RenderForwardTask::Input(items, lightingModel, lightingStageFramesAndZones).asVarying();
|
const auto renderInput = RenderForwardTask::Input(items, lightingModel, lightingStageFramesAndZones).asVarying();
|
||||||
task.addJob<RenderForwardTask>("RenderForwardTask", renderInput);
|
task.addJob<RenderForwardTask>("RenderForwardTask", renderInput);
|
||||||
|
|
|
@ -15,15 +15,38 @@
|
||||||
#include <render/Engine.h>
|
#include <render/Engine.h>
|
||||||
#include <render/RenderFetchCullSortTask.h>
|
#include <render/RenderFetchCullSortTask.h>
|
||||||
|
|
||||||
|
#include "AssembleLightingStageTask.h"
|
||||||
|
|
||||||
|
class RenderShadowsAndDeferredTask {
|
||||||
|
public:
|
||||||
|
using Input = render::VaryingSet3<RenderFetchCullSortTask::Output, LightingModelPointer, AssembleLightingStageTask::Output>;
|
||||||
|
using JobModel = render::Task::ModelI<RenderShadowsAndDeferredTask, Input>;
|
||||||
|
|
||||||
|
RenderShadowsAndDeferredTask() {}
|
||||||
|
|
||||||
|
void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs, render::CullFunctor cullFunctor, uint8_t tagBits, uint8_t tagMask);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class DeferredForwardSwitchJob {
|
||||||
|
public:
|
||||||
|
using Input = render::VaryingSet3<RenderFetchCullSortTask::Output, LightingModelPointer, AssembleLightingStageTask::Output>;
|
||||||
|
using JobModel = render::Switch::ModelI<DeferredForwardSwitchJob, Input>;
|
||||||
|
|
||||||
|
DeferredForwardSwitchJob() {}
|
||||||
|
|
||||||
|
void configure(const render::SwitchConfig& config) {}
|
||||||
|
void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs, render::CullFunctor cullFunctor, uint8_t tagBits, uint8_t tagMask);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class RenderViewTask {
|
class RenderViewTask {
|
||||||
public:
|
public:
|
||||||
using Input = RenderFetchCullSortTask::Output;
|
using Input = RenderFetchCullSortTask::Output;
|
||||||
using JobModel = render::Task::ModelIS<RenderViewTask, Input>;
|
using JobModel = render::Task::ModelI<RenderViewTask, Input>;
|
||||||
|
|
||||||
RenderViewTask() {}
|
RenderViewTask() {}
|
||||||
|
|
||||||
void configure(const render::SwitchConfig& configuration) {}
|
|
||||||
void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs, render::CullFunctor cullFunctor, uint8_t tagBits = 0x00, uint8_t tagMask = 0x00);
|
void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs, render::CullFunctor cullFunctor, uint8_t tagBits = 0x00, uint8_t tagMask = 0x00);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,7 +38,7 @@ void JobConfig::setPresetList(const QJsonObject& object) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskConfig::connectChildConfig(QConfigPointer childConfig, const std::string& name) {
|
void JobConfig::connectChildConfig(std::shared_ptr<JobConfig> childConfig, const std::string& name) {
|
||||||
childConfig->setParent(this);
|
childConfig->setParent(this);
|
||||||
childConfig->setObjectName(name.c_str());
|
childConfig->setObjectName(name.c_str());
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ void TaskConfig::connectChildConfig(QConfigPointer childConfig, const std::strin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskConfig::transferChildrenConfigs(QConfigPointer source) {
|
void JobConfig::transferChildrenConfigs(std::shared_ptr<JobConfig> source) {
|
||||||
if (!source) {
|
if (!source) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -70,13 +70,13 @@ void TaskConfig::transferChildrenConfigs(QConfigPointer source) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskConfig::refresh() {
|
void JobConfig::refresh() {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
BLOCKING_INVOKE_METHOD(this, "refresh");
|
BLOCKING_INVOKE_METHOD(this, "refresh");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_task->applyConfiguration();
|
_jobConcept->applyConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskConfig* TaskConfig::getRootConfig(const std::string& jobPath, std::string& jobName) const {
|
TaskConfig* TaskConfig::getRootConfig(const std::string& jobPath, std::string& jobName) const {
|
||||||
|
@ -134,9 +134,9 @@ JobConfig* TaskConfig::getJobConfig(const std::string& jobPath) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwitchConfig::setSwitchIndex(uint8_t index) {
|
void SwitchConfig::setBranch(uint8_t branch) {
|
||||||
if (_switchIndex != index) {
|
if (_branch != branch) {
|
||||||
_switchIndex = index;
|
_branch = branch;
|
||||||
// We can re-use this signal here
|
// We can re-use this signal here
|
||||||
emit dirtyEnabled();
|
emit dirtyEnabled();
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,6 +154,11 @@ public:
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE virtual QObject* getSubConfig(int i) const { return nullptr; }
|
Q_INVOKABLE virtual QObject* getSubConfig(int i) const { return nullptr; }
|
||||||
|
|
||||||
|
void connectChildConfig(std::shared_ptr<JobConfig> childConfig, const std::string& name);
|
||||||
|
void transferChildrenConfigs(std::shared_ptr<JobConfig> source);
|
||||||
|
|
||||||
|
JobConcept* _jobConcept;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
@ -162,6 +167,11 @@ public slots:
|
||||||
*/
|
*/
|
||||||
void load(const QJsonObject& val) { qObjectFromJsonValue(val, *this); emit loaded(); }
|
void load(const QJsonObject& val) { qObjectFromJsonValue(val, *this); emit loaded(); }
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* @function Render.refresh
|
||||||
|
*/
|
||||||
|
void refresh();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
@ -248,30 +258,18 @@ public:
|
||||||
auto subs = getSubConfigs();
|
auto subs = getSubConfigs();
|
||||||
return ((i < 0 || i >= subs.size()) ? nullptr : subs[i]);
|
return ((i < 0 || i >= subs.size()) ? nullptr : subs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void connectChildConfig(QConfigPointer childConfig, const std::string& name);
|
|
||||||
void transferChildrenConfigs(QConfigPointer source);
|
|
||||||
|
|
||||||
JobConcept* _task;
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
|
|
||||||
/**jsdoc
|
|
||||||
* @function Render.refresh
|
|
||||||
*/
|
|
||||||
void refresh();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SwitchConfig : public TaskConfig {
|
class SwitchConfig : public JobConfig {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(bool switchIndex READ getSwitchIndex WRITE setSwitchIndex NOTIFY dirtyEnabled)
|
Q_PROPERTY(bool branch READ getBranch WRITE setBranch NOTIFY dirtyEnabled)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
uint8_t getSwitchIndex() const { return _switchIndex; }
|
uint8_t getBranch() const { return _branch; }
|
||||||
void setSwitchIndex(uint8_t index);
|
void setBranch(uint8_t index);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint8_t _switchIndex { 0 };
|
uint8_t _branch { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,6 +177,7 @@ public:
|
||||||
template <class T, class O, class C = Config> using ModelO = Model<T, C, None, O>;
|
template <class T, class O, class C = Config> using ModelO = Model<T, C, None, O>;
|
||||||
template <class T, class I, class O, class C = Config> using ModelIO = Model<T, C, I, O>;
|
template <class T, class I, class O, class C = Config> using ModelIO = Model<T, C, I, O>;
|
||||||
|
|
||||||
|
Job() {}
|
||||||
Job(const ConceptPointer& concept) : _concept(concept) {}
|
Job(const ConceptPointer& concept) : _concept(concept) {}
|
||||||
virtual ~Job() = default;
|
virtual ~Job() = default;
|
||||||
|
|
||||||
|
@ -304,7 +305,7 @@ public:
|
||||||
// swap
|
// swap
|
||||||
Concept::_config = config;
|
Concept::_config = config;
|
||||||
// Capture this
|
// Capture this
|
||||||
std::static_pointer_cast<C>(Concept::_config)->_task = this;
|
Concept::_config->_jobConcept = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
QConfigPointer& getConfiguration() override {
|
QConfigPointer& getConfiguration() override {
|
||||||
|
@ -314,7 +315,7 @@ public:
|
||||||
return Concept::_config;
|
return Concept::_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void applyConfiguration() override {
|
void applyConfiguration() override {
|
||||||
TimeProfiler probe("configure::" + JobConcept::getName());
|
TimeProfiler probe("configure::" + JobConcept::getName());
|
||||||
jobConfigure(_data, *std::static_pointer_cast<C>(Concept::_config));
|
jobConfigure(_data, *std::static_pointer_cast<C>(Concept::_config));
|
||||||
for (auto& job : TaskConcept::_jobs) {
|
for (auto& job : TaskConcept::_jobs) {
|
||||||
|
@ -322,7 +323,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void run(const ContextPointer& jobContext) override {
|
void run(const ContextPointer& jobContext) override {
|
||||||
auto config = std::static_pointer_cast<C>(Concept::_config);
|
auto config = std::static_pointer_cast<C>(Concept::_config);
|
||||||
if (config->isEnabled()) {
|
if (config->isEnabled()) {
|
||||||
for (auto job : TaskConcept::_jobs) {
|
for (auto job : TaskConcept::_jobs) {
|
||||||
|
@ -340,17 +341,86 @@ public:
|
||||||
template <class T, class O, class C = Config> using ModelO = TaskModel<T, C, None, O>;
|
template <class T, class O, class C = Config> using ModelO = TaskModel<T, C, None, O>;
|
||||||
template <class T, class I, class O, class C = Config> using ModelIO = TaskModel<T, C, I, O>;
|
template <class T, class I, class O, class C = Config> using ModelIO = TaskModel<T, C, I, O>;
|
||||||
|
|
||||||
template <class T, class C = SwitchConfig, class I = None, class O = None> class SwitchTaskModel : public TaskModel<T, C, I, O> {
|
// Create a new job in the Task's queue; returns the job's output
|
||||||
|
template <class T, class... A> const Varying addJob(std::string name, const Varying& input, A&&... args) {
|
||||||
|
return std::static_pointer_cast<TaskConcept>(JobType::_concept)->template addJob<T>(name, input, std::forward<A>(args)...);
|
||||||
|
}
|
||||||
|
template <class T, class... A> const Varying addJob(std::string name, A&&... args) {
|
||||||
|
const auto input = Varying(typename T::JobModel::Input());
|
||||||
|
return std::static_pointer_cast<TaskConcept>(JobType::_concept)->template addJob<T>(name, input, std::forward<A>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Config> getConfiguration() {
|
||||||
|
return std::static_pointer_cast<Config>(JobType::_concept->getConfiguration());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// A Switch is a specialized job to run a collection of other jobs and switch between different branches at run time
|
||||||
|
// It can be created on any type T by aliasing the type JobModel in the class T
|
||||||
|
// using JobModel = Switch::Model<T>
|
||||||
|
// The class T is expected to have a "build" method acting as a constructor.
|
||||||
|
// The build method is where child Jobs can be added internally to the branches of the switch
|
||||||
|
// where the input of the switch can be setup to feed the child jobs
|
||||||
|
// and where the output of the switch is defined
|
||||||
|
template <class JC, class TP>
|
||||||
|
class Switch : public Job<JC, TP> {
|
||||||
|
public:
|
||||||
|
using Context = JC;
|
||||||
|
using TimeProfiler = TP;
|
||||||
|
using ContextPointer = std::shared_ptr<Context>;
|
||||||
|
using Config = SwitchConfig;
|
||||||
|
using JobType = Job<JC, TP>;
|
||||||
|
using None = typename JobType::None;
|
||||||
|
using Concept = typename JobType::Concept;
|
||||||
|
using ConceptPointer = typename JobType::ConceptPointer;
|
||||||
|
using Branches = std::unordered_map<uint8_t, JobType>;
|
||||||
|
|
||||||
|
Switch(ConceptPointer concept) : JobType(concept) {}
|
||||||
|
|
||||||
|
class SwitchConcept : public Concept {
|
||||||
public:
|
public:
|
||||||
|
Varying _input;
|
||||||
|
Varying _output;
|
||||||
|
Branches _branches;
|
||||||
|
|
||||||
|
const Varying getInput() const override { return _input; }
|
||||||
|
const Varying getOutput() const override { return _output; }
|
||||||
|
Varying& editInput() override { return _input; }
|
||||||
|
|
||||||
|
SwitchConcept(const std::string& name, const Varying& input, QConfigPointer config) : Concept(name, config), _input(input) {}
|
||||||
|
|
||||||
|
template <class NT, class... NA> const Varying addBranch(std::string name, uint8_t index, const Varying& input, NA&&... args) {
|
||||||
|
auto& branch = _branches[index];
|
||||||
|
branch = JobType(NT::JobModel::create(name, input, std::forward<NA>(args)...));
|
||||||
|
|
||||||
|
// Conect the child config to this task's config
|
||||||
|
std::static_pointer_cast<SwitchConfig>(Concept::getConfiguration())->connectChildConfig(branch.getConfiguration(), name);
|
||||||
|
|
||||||
|
return branch.getOutput();
|
||||||
|
}
|
||||||
|
template <class NT, class... NA> const Varying addBranch(std::string name, uint8_t index, NA&&... args) {
|
||||||
|
const auto input = Varying(typename NT::JobModel::Input());
|
||||||
|
return addBranch<NT>(name, index, input, std::forward<NA>(args)...);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class C = SwitchConfig, class I = None, class O = None> class SwitchModel : public SwitchConcept {
|
||||||
|
public:
|
||||||
|
using Data = T;
|
||||||
using Input = I;
|
using Input = I;
|
||||||
|
using Output = O;
|
||||||
|
|
||||||
std::unordered_map<uint8_t, Jobs> _jobsSwitch;
|
Data _data;
|
||||||
|
|
||||||
SwitchTaskModel(const std::string& name, const Varying& input, QConfigPointer config) : TaskModel<T, C, I, O>(name, input, config) {}
|
SwitchModel(const std::string& name, const Varying& input, QConfigPointer config) :
|
||||||
|
SwitchConcept(name, input, config),
|
||||||
|
_data(Data()) {
|
||||||
|
}
|
||||||
|
|
||||||
template <class... A>
|
template <class... A>
|
||||||
static std::shared_ptr<SwitchTaskModel> create(const std::string& name, const Varying& input, A&&... args) {
|
static std::shared_ptr<SwitchModel> create(const std::string& name, const Varying& input, A&&... args) {
|
||||||
auto model = std::make_shared<SwitchTaskModel>(name, input, std::make_shared<C>());
|
auto model = std::make_shared<SwitchModel>(name, input, std::make_shared<C>());
|
||||||
|
|
||||||
{
|
{
|
||||||
TimeProfiler probe("build::" + model->getName());
|
TimeProfiler probe("build::" + model->getName());
|
||||||
|
@ -364,32 +434,43 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... A>
|
template <class... A>
|
||||||
static std::shared_ptr<SwitchTaskModel> create(const std::string& name, A&&... args) {
|
static std::shared_ptr<SwitchModel> create(const std::string& name, A&&... args) {
|
||||||
const auto input = Varying(Input());
|
const auto input = Varying(Input());
|
||||||
return create(name, input, std::forward<A>(args)...);
|
return create(name, input, std::forward<A>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
void applyConfiguration() override {
|
void createConfiguration() {
|
||||||
TaskModel<T, C, I, O>::applyConfiguration();
|
// A brand new config
|
||||||
|
auto config = std::make_shared<C>();
|
||||||
for (auto& jobs : _jobsSwitch) {
|
// Make sure we transfer the former children configs to the new config
|
||||||
for (auto& job : jobs.second) {
|
config->transferChildrenConfigs(Concept::_config);
|
||||||
job.applyConfiguration();
|
// swap
|
||||||
|
Concept::_config = config;
|
||||||
|
// Capture this
|
||||||
|
Concept::_config->_jobConcept = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QConfigPointer& getConfiguration() override {
|
||||||
|
if (!Concept::_config) {
|
||||||
|
createConfiguration();
|
||||||
|
}
|
||||||
|
return Concept::_config;
|
||||||
|
}
|
||||||
|
|
||||||
|
void applyConfiguration() override {
|
||||||
|
TimeProfiler probe("configure::" + JobConcept::getName());
|
||||||
|
jobConfigure(_data, *std::static_pointer_cast<C>(Concept::_config));
|
||||||
|
for (auto& branch : _branches) {
|
||||||
|
branch.second.applyConfiguration();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void run(const ContextPointer& jobContext) override {
|
void run(const ContextPointer& jobContext) override {
|
||||||
auto config = std::static_pointer_cast<C>(Concept::_config);
|
auto config = std::static_pointer_cast<C>(Concept::_config);
|
||||||
if (config->isEnabled()) {
|
if (config->isEnabled()) {
|
||||||
// First we run all the setup jobs
|
auto jobsIt = _branches.find(config->getBranch());
|
||||||
TaskModel<T, C, I, O>::run(jobContext);
|
if (jobsIt != _branches.end()) {
|
||||||
|
jobsIt->second.run(jobContext);
|
||||||
// Then we run the branching jobs
|
|
||||||
auto jobsIt = _jobsSwitch.find(config->getSwitchIndex());
|
|
||||||
if (jobsIt != _jobsSwitch.end()) {
|
|
||||||
for (auto job : jobsIt->second) {
|
|
||||||
job.run(jobContext);
|
|
||||||
if (jobContext->taskFlow.doAbortTask()) {
|
if (jobContext->taskFlow.doAbortTask()) {
|
||||||
jobContext->taskFlow.reset();
|
jobContext->taskFlow.reset();
|
||||||
return;
|
return;
|
||||||
|
@ -397,45 +478,25 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
template <class NT, class... NA> const Varying addSwitchJob(std::string name, uint8_t index, const Varying& input, NA&&... args) {
|
|
||||||
auto& jobs = _jobsSwitch[index];
|
|
||||||
jobs.emplace_back((NT::JobModel::create(name, input, std::forward<NA>(args)...)));
|
|
||||||
|
|
||||||
// Conect the child config to this task's config
|
|
||||||
std::static_pointer_cast<TaskConfig>(Concept::getConfiguration())->connectChildConfig(jobs.back().getConfiguration(), name);
|
|
||||||
|
|
||||||
return jobs.back().getOutput();
|
|
||||||
}
|
|
||||||
template <class NT, class... NA> const Varying addSwitchJob(std::string name, uint8_t index, NA&&... args) {
|
|
||||||
const auto input = Varying(typename NT::JobModel::Input());
|
|
||||||
return addJob<NT>(name, index, input, std::forward<NA>(args)...);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
template <class T, class I, class C = SwitchConfig> using ModelIS = SwitchTaskModel<T, C, I, None>;
|
template <class T, class C = SwitchConfig> using Model = SwitchModel<T, C, None, None>;
|
||||||
|
template <class T, class I, class C = SwitchConfig> using ModelI = SwitchModel<T, C, I, None>;
|
||||||
|
// TODO: Switches don't support Outputs yet
|
||||||
|
//template <class T, class O, class C = SwitchConfig> using ModelO = SwitchModel<T, C, None, O>;
|
||||||
|
//template <class T, class I, class O, class C = SwitchConfig> using ModelIO = SwitchModel<T, C, I, O>;
|
||||||
|
|
||||||
// Create a new job in the Task's queue; returns the job's output
|
// Create a new job in the Switches' branches; returns the job's output
|
||||||
template <class T, class... A> const Varying addJob(std::string name, const Varying& input, A&&... args) {
|
template <class T, class... A> const Varying addBranch(std::string name, uint8_t index, const Varying& input, A&&... args) {
|
||||||
return std::static_pointer_cast<TaskConcept>(JobType::_concept)->template addJob<T>(name, input, std::forward<A>(args)...);
|
return std::static_pointer_cast<SwitchConcept>(JobType::_concept)->template addBranch<T>(name, index, input, std::forward<A>(args)...);
|
||||||
}
|
}
|
||||||
template <class T, class... A> const Varying addJob(std::string name, A&&... args) {
|
template <class T, class... A> const Varying addBranch(std::string name, uint8_t index, A&&... args) {
|
||||||
const auto input = Varying(typename T::JobModel::Input());
|
const auto input = Varying(typename T::JobModel::Input());
|
||||||
return std::static_pointer_cast<TaskConcept>(JobType::_concept)->template addJob<T>(name, input, std::forward<A>(args)...);
|
return std::static_pointer_cast<SwitchConcept>(JobType::_concept)->template addBranch<T>(name, index, input, std::forward<A>(args)...);
|
||||||
}
|
|
||||||
template <class T, class... A> const Varying addSwitchJob(std::string name, uint8_t index, const Varying& input, A&&... args) {
|
|
||||||
return std::static_pointer_cast<SwitchTaskModel>(JobType::_concept)->template addSwitchJob<T>(name, index, input, std::forward<A>(args)...);
|
|
||||||
}
|
|
||||||
template <class T, class... A> const Varying addSwitchJob(std::string name, uint8_t index, A&&... args) {
|
|
||||||
const auto input = Varying(typename T::JobModel::Input());
|
|
||||||
return std::static_pointer_cast<SwitchTaskModel>(JobType::_concept)->template addSwitchJob<T>(name, index, input, std::forward<A>(args)...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Config> getConfiguration() {
|
std::shared_ptr<Config> getConfiguration() {
|
||||||
return std::static_pointer_cast<Config>(JobType::_concept->getConfiguration());
|
return std::static_pointer_cast<Config>(JobType::_concept->getConfiguration());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class JC, class TP>
|
template <class JC, class TP>
|
||||||
|
@ -475,6 +536,7 @@ protected:
|
||||||
using SwitchConfig = task::SwitchConfig; \
|
using SwitchConfig = task::SwitchConfig; \
|
||||||
template <class T> using PersistentConfig = task::PersistentConfig<T>; \
|
template <class T> using PersistentConfig = task::PersistentConfig<T>; \
|
||||||
using Job = task::Job<ContextType, TimeProfiler>; \
|
using Job = task::Job<ContextType, TimeProfiler>; \
|
||||||
|
using Switch = task::Switch<ContextType, TimeProfiler>; \
|
||||||
using Task = task::Task<ContextType, TimeProfiler>; \
|
using Task = task::Task<ContextType, TimeProfiler>; \
|
||||||
using Engine = task::Engine<ContextType, TimeProfiler>; \
|
using Engine = task::Engine<ContextType, TimeProfiler>; \
|
||||||
using Varying = task::Varying; \
|
using Varying = task::Varying; \
|
||||||
|
|
Loading…
Reference in a new issue