mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-04-07 18:32:45 +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 "AssembleLightingStageTask.h"
|
||||
#include "RenderShadowTask.h"
|
||||
#include "RenderDeferredTask.h"
|
||||
#include "RenderForwardTask.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) {
|
||||
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
|
||||
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);
|
||||
|
||||
if (!DISABLE_DEFERRED) {
|
||||
// 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.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);
|
||||
const auto deferredForwardIn = DeferredForwardSwitchJob::Input(items, lightingModel, lightingStageFramesAndZones).asVarying();
|
||||
task.addJob<DeferredForwardSwitchJob>("DeferredForwardSwitch", deferredForwardIn, cullFunctor, tagBits, tagMask);
|
||||
} else {
|
||||
const auto renderInput = RenderForwardTask::Input(items, lightingModel, lightingStageFramesAndZones).asVarying();
|
||||
task.addJob<RenderForwardTask>("RenderForwardTask", renderInput);
|
||||
|
|
|
@ -15,15 +15,38 @@
|
|||
#include <render/Engine.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 {
|
||||
public:
|
||||
using Input = RenderFetchCullSortTask::Output;
|
||||
using JobModel = render::Task::ModelIS<RenderViewTask, Input>;
|
||||
using JobModel = render::Task::ModelI<RenderViewTask, Input>;
|
||||
|
||||
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);
|
||||
|
||||
};
|
||||
|
|
|
@ -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->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) {
|
||||
return;
|
||||
}
|
||||
|
@ -70,13 +70,13 @@ void TaskConfig::transferChildrenConfigs(QConfigPointer source) {
|
|||
}
|
||||
}
|
||||
|
||||
void TaskConfig::refresh() {
|
||||
void JobConfig::refresh() {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
BLOCKING_INVOKE_METHOD(this, "refresh");
|
||||
return;
|
||||
}
|
||||
|
||||
_task->applyConfiguration();
|
||||
_jobConcept->applyConfiguration();
|
||||
}
|
||||
|
||||
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) {
|
||||
if (_switchIndex != index) {
|
||||
_switchIndex = index;
|
||||
void SwitchConfig::setBranch(uint8_t branch) {
|
||||
if (_branch != branch) {
|
||||
_branch = branch;
|
||||
// We can re-use this signal here
|
||||
emit dirtyEnabled();
|
||||
}
|
||||
|
|
|
@ -154,6 +154,11 @@ public:
|
|||
*/
|
||||
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:
|
||||
|
||||
/**jsdoc
|
||||
|
@ -162,6 +167,11 @@ public slots:
|
|||
*/
|
||||
void load(const QJsonObject& val) { qObjectFromJsonValue(val, *this); emit loaded(); }
|
||||
|
||||
/**jsdoc
|
||||
* @function Render.refresh
|
||||
*/
|
||||
void refresh();
|
||||
|
||||
signals:
|
||||
|
||||
/**jsdoc
|
||||
|
@ -248,30 +258,18 @@ public:
|
|||
auto subs = getSubConfigs();
|
||||
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_PROPERTY(bool switchIndex READ getSwitchIndex WRITE setSwitchIndex NOTIFY dirtyEnabled)
|
||||
Q_PROPERTY(bool branch READ getBranch WRITE setBranch NOTIFY dirtyEnabled)
|
||||
|
||||
public:
|
||||
uint8_t getSwitchIndex() const { return _switchIndex; }
|
||||
void setSwitchIndex(uint8_t index);
|
||||
uint8_t getBranch() const { return _branch; }
|
||||
void setBranch(uint8_t index);
|
||||
|
||||
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 I, class O, class C = Config> using ModelIO = Model<T, C, I, O>;
|
||||
|
||||
Job() {}
|
||||
Job(const ConceptPointer& concept) : _concept(concept) {}
|
||||
virtual ~Job() = default;
|
||||
|
||||
|
@ -304,7 +305,7 @@ public:
|
|||
// swap
|
||||
Concept::_config = config;
|
||||
// Capture this
|
||||
std::static_pointer_cast<C>(Concept::_config)->_task = this;
|
||||
Concept::_config->_jobConcept = this;
|
||||
}
|
||||
|
||||
QConfigPointer& getConfiguration() override {
|
||||
|
@ -314,7 +315,7 @@ public:
|
|||
return Concept::_config;
|
||||
}
|
||||
|
||||
virtual void applyConfiguration() override {
|
||||
void applyConfiguration() override {
|
||||
TimeProfiler probe("configure::" + JobConcept::getName());
|
||||
jobConfigure(_data, *std::static_pointer_cast<C>(Concept::_config));
|
||||
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);
|
||||
if (config->isEnabled()) {
|
||||
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 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:
|
||||
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 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>
|
||||
static std::shared_ptr<SwitchTaskModel> create(const std::string& name, const Varying& input, A&&... args) {
|
||||
auto model = std::make_shared<SwitchTaskModel>(name, input, std::make_shared<C>());
|
||||
static std::shared_ptr<SwitchModel> create(const std::string& name, const Varying& input, A&&... args) {
|
||||
auto model = std::make_shared<SwitchModel>(name, input, std::make_shared<C>());
|
||||
|
||||
{
|
||||
TimeProfiler probe("build::" + model->getName());
|
||||
|
@ -364,78 +434,69 @@ public:
|
|||
}
|
||||
|
||||
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());
|
||||
return create(name, input, std::forward<A>(args)...);
|
||||
}
|
||||
|
||||
void applyConfiguration() override {
|
||||
TaskModel<T, C, I, O>::applyConfiguration();
|
||||
void createConfiguration() {
|
||||
// A brand new config
|
||||
auto config = std::make_shared<C>();
|
||||
// Make sure we transfer the former children configs to the new config
|
||||
config->transferChildrenConfigs(Concept::_config);
|
||||
// swap
|
||||
Concept::_config = config;
|
||||
// Capture this
|
||||
Concept::_config->_jobConcept = this;
|
||||
}
|
||||
|
||||
for (auto& jobs : _jobsSwitch) {
|
||||
for (auto& job : jobs.second) {
|
||||
job.applyConfiguration();
|
||||
}
|
||||
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 {
|
||||
auto config = std::static_pointer_cast<C>(Concept::_config);
|
||||
if (config->isEnabled()) {
|
||||
// First we run all the setup jobs
|
||||
TaskModel<T, C, I, O>::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()) {
|
||||
jobContext->taskFlow.reset();
|
||||
return;
|
||||
}
|
||||
auto jobsIt = _branches.find(config->getBranch());
|
||||
if (jobsIt != _branches.end()) {
|
||||
jobsIt->second.run(jobContext);
|
||||
if (jobContext->taskFlow.doAbortTask()) {
|
||||
jobContext->taskFlow.reset();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
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)...);
|
||||
// Create a new job in the Switches' branches; returns the job's output
|
||||
template <class T, class... A> const Varying addBranch(std::string name, uint8_t index, const Varying& input, 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());
|
||||
return std::static_pointer_cast<TaskConcept>(JobType::_concept)->template addJob<T>(name, 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)...);
|
||||
return std::static_pointer_cast<SwitchConcept>(JobType::_concept)->template addBranch<T>(name, index, input, std::forward<A>(args)...);
|
||||
}
|
||||
|
||||
std::shared_ptr<Config> getConfiguration() {
|
||||
return std::static_pointer_cast<Config>(JobType::_concept->getConfiguration());
|
||||
}
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
template <class JC, class TP>
|
||||
|
@ -475,6 +536,7 @@ protected:
|
|||
using SwitchConfig = task::SwitchConfig; \
|
||||
template <class T> using PersistentConfig = task::PersistentConfig<T>; \
|
||||
using Job = task::Job<ContextType, TimeProfiler>; \
|
||||
using Switch = task::Switch<ContextType, TimeProfiler>; \
|
||||
using Task = task::Task<ContextType, TimeProfiler>; \
|
||||
using Engine = task::Engine<ContextType, TimeProfiler>; \
|
||||
using Varying = task::Varying; \
|
||||
|
|
Loading…
Reference in a new issue