diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 8d96a68046..27d1ed9bc2 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -584,7 +584,6 @@ Menu::Menu() { // Developer > Physics >>> MenuWrapper* physicsOptionsMenu = developerMenu->addMenu("Physics"); - addCheckableActionToQMenuAndActionHash(physicsOptionsMenu, MenuOption::PhysicsShowOwned); addCheckableActionToQMenuAndActionHash(physicsOptionsMenu, MenuOption::PhysicsShowHulls); // Developer > Display Crash Options diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 21454b7d66..f07ce641d8 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -244,7 +244,6 @@ namespace MenuOption { const QString OutputMenu = "Display"; const QString PackageModel = "Package Model..."; const QString Pair = "Pair"; - const QString PhysicsShowOwned = "Highlight Simulation Ownership"; const QString PhysicsShowHulls = "Draw Collision Hulls"; const QString PipelineWarnings = "Log Render Pipeline Warnings"; const QString Preferences = "General..."; diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.cpp b/libraries/render-utils/src/AmbientOcclusionEffect.cpp index 6bcb4bbdcb..50b6c06254 100644 --- a/libraries/render-utils/src/AmbientOcclusionEffect.cpp +++ b/libraries/render-utils/src/AmbientOcclusionEffect.cpp @@ -101,13 +101,13 @@ AmbientOcclusionEffect::AmbientOcclusionEffect() { _parametersBuffer = gpu::BufferView(std::make_shared(sizeof(Parameters), (const gpu::Byte*) ¶meters)); } -void AmbientOcclusionEffect::configure(const Config& configuration) { - DependencyManager::get()->setAmbientOcclusionEnabled(configuration.enabled); +void AmbientOcclusionEffect::configure(const Config& config) { + DependencyManager::get()->setAmbientOcclusionEnabled(config.enabled); bool shouldUpdateGaussion = false; const double RADIUS_POWER = 6.0; - const auto& radius = configuration.radius; + const auto& radius = config.radius; if (radius != getRadius()) { auto& current = _parametersBuffer.edit().radiusInfo; current.x = radius; @@ -115,39 +115,39 @@ void AmbientOcclusionEffect::configure(const Config& configuration) { current.z = (float)(1.0 / pow((double)radius, RADIUS_POWER)); } - if (configuration.obscuranceLevel != getObscuranceLevel()) { + if (config.obscuranceLevel != getObscuranceLevel()) { auto& current = _parametersBuffer.edit().radiusInfo; - current.w = configuration.obscuranceLevel; + current.w = config.obscuranceLevel; } - if (configuration.falloffBias != getFalloffBias()) { + if (config.falloffBias != getFalloffBias()) { auto& current = _parametersBuffer.edit().ditheringInfo; - current.z = configuration.falloffBias; + current.z = config.falloffBias; } - if (configuration.edgeSharpness != getEdgeSharpness()) { + if (config.edgeSharpness != getEdgeSharpness()) { auto& current = _parametersBuffer.edit().blurInfo; - current.x = configuration.edgeSharpness; + current.x = config.edgeSharpness; } - if (configuration.blurDeviation != getBlurDeviation()) { + if (config.blurDeviation != getBlurDeviation()) { auto& current = _parametersBuffer.edit().blurInfo; - current.z = configuration.blurDeviation; + current.z = config.blurDeviation; shouldUpdateGaussion = true; } - if (configuration.numSpiralTurns != getNumSpiralTurns()) { + if (config.numSpiralTurns != getNumSpiralTurns()) { auto& current = _parametersBuffer.edit().sampleInfo; - current.z = configuration.numSpiralTurns; + current.z = config.numSpiralTurns; } - if (configuration.numSamples != getNumSamples()) { + if (config.numSamples != getNumSamples()) { auto& current = _parametersBuffer.edit().sampleInfo; - current.x = configuration.numSamples; - current.y = 1.0f / configuration.numSamples; + current.x = config.numSamples; + current.y = 1.0f / config.numSamples; } - const auto& resolutionLevel = configuration.resolutionLevel; + const auto& resolutionLevel = config.resolutionLevel; if (resolutionLevel != getResolutionLevel()) { auto& current = _parametersBuffer.edit().resolutionInfo; current.x = (float)resolutionLevel; @@ -156,20 +156,20 @@ void AmbientOcclusionEffect::configure(const Config& configuration) { DependencyManager::get()->setAmbientOcclusionResolutionLevel(resolutionLevel); } - if (configuration.blurRadius != getBlurRadius()) { + if (config.blurRadius != getBlurRadius()) { auto& current = _parametersBuffer.edit().blurInfo; - current.y = (float)configuration.blurRadius; + current.y = (float)config.blurRadius; shouldUpdateGaussion = true; } - if (configuration.ditheringEnabled != isDitheringEnabled()) { + if (config.ditheringEnabled != isDitheringEnabled()) { auto& current = _parametersBuffer.edit().ditheringInfo; - current.x = (float)configuration.ditheringEnabled; + current.x = (float)config.ditheringEnabled; } - if (configuration.borderingEnabled != isBorderingEnabled()) { + if (config.borderingEnabled != isBorderingEnabled()) { auto& current = _parametersBuffer.edit().ditheringInfo; - current.w = (float)configuration.borderingEnabled; + current.w = (float)config.borderingEnabled; } if (shouldUpdateGaussion) { diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.h b/libraries/render-utils/src/AmbientOcclusionEffect.h index 2c2c9cfff2..c040e31188 100644 --- a/libraries/render-utils/src/AmbientOcclusionEffect.h +++ b/libraries/render-utils/src/AmbientOcclusionEffect.h @@ -18,9 +18,6 @@ class AmbientOcclusionEffectConfig : public render::Job::Config { Q_OBJECT -public: - AmbientOcclusionEffectConfig() : render::Job::Config(false) {} - Q_PROPERTY(bool enabled MEMBER enabled NOTIFY dirty) Q_PROPERTY(bool ditheringEnabled MEMBER ditheringEnabled NOTIFY dirty) Q_PROPERTY(bool borderingEnabled MEMBER borderingEnabled NOTIFY dirty) @@ -34,6 +31,8 @@ public: Q_PROPERTY(int resolutionLevel MEMBER resolutionLevel WRITE setResolutionLevel) Q_PROPERTY(int blurRadius MEMBER blurRadius WRITE setBlurRadius) Q_PROPERTY(double gpuTime READ getGpuTime) +public: + AmbientOcclusionEffectConfig() : render::Job::Config(false) {} const int MAX_RESOLUTION_LEVEL = 4; const int MAX_BLUR_RADIUS = 6; @@ -73,7 +72,7 @@ public: AmbientOcclusionEffect(); - void configure(const Config& configuration); + void configure(const Config& config); void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); float getRadius() const { return _parametersBuffer.get().radiusInfo.x; } diff --git a/libraries/render-utils/src/AntialiasingEffect.h b/libraries/render-utils/src/AntialiasingEffect.h index 1dd3a9ddcc..f0a32c68ff 100644 --- a/libraries/render-utils/src/AntialiasingEffect.h +++ b/libraries/render-utils/src/AntialiasingEffect.h @@ -18,10 +18,9 @@ class AntiAliasingConfig : public render::Job::Config { Q_OBJECT + Q_PROPERTY(bool enabled MEMBER enabled) public: AntiAliasingConfig() : render::Job::Config(false) {} - - Q_PROPERTY(bool enabled MEMBER enabled) }; class Antialiasing { @@ -30,7 +29,7 @@ public: using JobModel = render::Job::Model; Antialiasing(); - void configure(const Config& configuration) {} + void configure(const Config& config) {} void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); const gpu::PipelinePointer& getAntialiasingPipeline(); diff --git a/libraries/render-utils/src/DebugDeferredBuffer.cpp b/libraries/render-utils/src/DebugDeferredBuffer.cpp index f8a35ad0df..2dcfa35522 100644 --- a/libraries/render-utils/src/DebugDeferredBuffer.cpp +++ b/libraries/render-utils/src/DebugDeferredBuffer.cpp @@ -232,6 +232,10 @@ const gpu::PipelinePointer& DebugDeferredBuffer::getPipeline(Mode mode, std::str } } +void DebugDeferredBuffer::configure(const Config& config) { + _mode = (Mode)config.mode; + _size = config.size; +} void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { assert(renderContext->args); diff --git a/libraries/render-utils/src/DebugDeferredBuffer.h b/libraries/render-utils/src/DebugDeferredBuffer.h index 27aa8d30b2..1cd199c67b 100644 --- a/libraries/render-utils/src/DebugDeferredBuffer.h +++ b/libraries/render-utils/src/DebugDeferredBuffer.h @@ -18,16 +18,16 @@ class DebugDeferredBufferConfig : public render::Job::Config { Q_OBJECT -public: - DebugDeferredBufferConfig() : render::Job::Config(false) {} - Q_PROPERTY(bool enabled MEMBER enabled) Q_PROPERTY(int mode MEMBER mode WRITE setMode) Q_PROPERTY(glm::vec4 size MEMBER size NOTIFY dirty) +public: + DebugDeferredBufferConfig() : render::Job::Config(false) {} + void setMode(int newMode); int mode{ 0 }; - glm::vec4 size{ 0, 0, 0, 0 }; + glm::vec4 size{ 0.0f, 0.0f, 0.0f, 0.0f }; signals: void dirty(); }; @@ -39,10 +39,7 @@ public: DebugDeferredBuffer(); - void configure(const Config& config) { - _mode = (Mode)config.mode; - _size = config.size; - } + void configure(const Config& config); void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); protected: diff --git a/libraries/render-utils/src/HitEffect.h b/libraries/render-utils/src/HitEffect.h index 7d683534d0..5252e63726 100644 --- a/libraries/render-utils/src/HitEffect.h +++ b/libraries/render-utils/src/HitEffect.h @@ -13,10 +13,9 @@ class HitEffectConfig : public render::Job::Config { Q_OBJECT + Q_PROPERTY(bool enabled MEMBER enabled) public: HitEffectConfig() : render::Job::Config(false) {} - - Q_PROPERTY(bool enabled MEMBER enabled) }; class HitEffect { @@ -25,7 +24,7 @@ public: using JobModel = render::Job::Model; HitEffect(); - void configure(const Config&) {} + void configure(const Config& config) {} void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); const gpu::PipelinePointer& getHitEffectPipeline(); diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 47a9c66111..06fadb69b3 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -67,13 +67,13 @@ void RenderDeferred::run(const SceneContextPointer& sceneContext, const RenderCo DependencyManager::get()->render(renderContext); } -void ToneMappingDeferred::configure(const Config& configuration) { - if (configuration.exposure >= 0) { - _toneMappingEffect.setExposure(configuration.exposure); +void ToneMappingDeferred::configure(const Config& config) { + if (config.exposure >= 0.0f) { + _toneMappingEffect.setExposure(config.exposure); } - if (configuration.curve >= 0) { - _toneMappingEffect.setToneCurve((ToneMappingEffect::ToneCurve)configuration.curve); + if (config.curve >= 0) { + _toneMappingEffect.setToneCurve((ToneMappingEffect::ToneCurve)config.curve); } } @@ -169,7 +169,7 @@ void DrawDeferred::run(const SceneContextPointer& sceneContext, const RenderCont assert(renderContext->args); assert(renderContext->args->_viewFrustum); - auto& config = std::static_pointer_cast(renderContext->jobConfig); + auto config = std::static_pointer_cast(renderContext->jobConfig); RenderArgs* args = renderContext->args; gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { @@ -218,7 +218,7 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon auto& scene = sceneContext->_scene; auto& items = scene->getMasterBucket().at(ItemFilter::Builder::opaqueShape().withLayered()); - auto& config = std::static_pointer_cast(renderContext->jobConfig); + auto config = std::static_pointer_cast(renderContext->jobConfig); ItemIDsBounds inItems; inItems.reserve(items.size()); diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index 2aa6199b90..414b019b31 100755 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -43,13 +43,13 @@ public: class ToneMappingConfig : public render::Job::Config { Q_OBJECT -public: - ToneMappingConfig() : render::Job::Config(true) {} - Q_PROPERTY(bool enabled MEMBER enabled) Q_PROPERTY(float exposure MEMBER exposure NOTIFY dirty); Q_PROPERTY(int curve MEMBER curve NOTIFY dirty); - float exposure{ 0.0 }; +public: + ToneMappingConfig() : render::Job::Config(true) {} + + float exposure{ 0.0f }; int curve{ 3 }; signals: void dirty(); @@ -60,7 +60,7 @@ public: using Config = ToneMappingConfig; using JobModel = render::Job::Model; - void configure(const Config&); + void configure(const Config& config); void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); ToneMappingEffect _toneMappingEffect; @@ -68,9 +68,9 @@ public: class DrawConfig : public render::Job::Config { Q_OBJECT -public: Q_PROPERTY(int numDrawn READ getNumDrawn) Q_PROPERTY(int maxDrawn MEMBER maxDrawn NOTIFY dirty) +public: int getNumDrawn() { return numDrawn; } int numDrawn{ 0 }; @@ -91,7 +91,7 @@ public: protected: render::ShapePlumberPointer _shapePlumber; - int _maxDrawn{ -1 }; + int _maxDrawn; // initialized by Config }; class DrawStencilDeferred { @@ -115,10 +115,10 @@ public: class DrawOverlay3DConfig : public render::Job::Config { Q_OBJECT -public: Q_PROPERTY(int numItems READ getNumItems) Q_PROPERTY(int numDrawn READ getNumDrawn) Q_PROPERTY(int maxDrawn MEMBER maxDrawn NOTIFY dirty) +public: int getNumItems() { return numItems; } int getNumDrawn() { return numDrawn; } @@ -144,7 +144,7 @@ public: protected: static gpu::PipelinePointer _opaquePipeline; //lazy evaluation hence mutable render::ShapePlumberPointer _shapePlumber; - int _maxDrawn{ -1 }; + int _maxDrawn; // initialized by Config }; class Blit { diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index 0771fcd9bf..be6cd47f95 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -78,6 +78,7 @@ void RenderShadowMap::run(const render::SceneContextPointer& sceneContext, const }); } +// The shadow task *must* use this base ctor to initialize with its own Config, see Task.h RenderShadowTask::RenderShadowTask(CullFunctor cullFunctor) : Task(std::make_shared()) { cullFunctor = cullFunctor ? cullFunctor : [](const RenderArgs*, const AABox&){ return true; }; @@ -121,6 +122,7 @@ RenderShadowTask::RenderShadowTask(CullFunctor cullFunctor) : Task(std::make_sha void RenderShadowTask::configure(const Config& configuration) { DependencyManager::get()->setShadowMapEnabled(configuration.enabled); + // This is a task, so must still propogate configure() to its Jobs Task::configure(configuration); } diff --git a/libraries/render-utils/src/RenderShadowTask.h b/libraries/render-utils/src/RenderShadowTask.h index 5a5186f6f1..e1bf983b79 100644 --- a/libraries/render-utils/src/RenderShadowTask.h +++ b/libraries/render-utils/src/RenderShadowTask.h @@ -33,11 +33,10 @@ protected: class RenderShadowTaskConfig : public render::Task::Config { Q_OBJECT + Q_PROPERTY(bool enabled MEMBER enabled NOTIFY dirty) public: RenderShadowTaskConfig() : render::Task::Config(false) {} - Q_PROPERTY(bool enabled MEMBER enabled NOTIFY dirty) - signals: void dirty(); }; diff --git a/libraries/render/src/render/Context.h b/libraries/render/src/render/Context.h index 0d8c1c8d04..04cf373146 100644 --- a/libraries/render/src/render/Context.h +++ b/libraries/render/src/render/Context.h @@ -31,7 +31,7 @@ public: RenderArgs* args; std::shared_ptr jobConfig{ nullptr }; }; -typedef std::shared_ptr RenderContextPointer; +using RenderContextPointer = std::shared_ptr; } diff --git a/libraries/render/src/render/DrawStatus.cpp b/libraries/render/src/render/DrawStatus.cpp index eb7155c513..c043867c88 100644 --- a/libraries/render/src/render/DrawStatus.cpp +++ b/libraries/render/src/render/DrawStatus.cpp @@ -94,9 +94,9 @@ const gpu::TexturePointer DrawStatus::getStatusIconMap() const { return _statusIconMap; } -void DrawStatus::configure(const Config& configuration) { - _showDisplay = configuration.showDisplay; - _showNetwork = configuration.showNetwork; +void DrawStatus::configure(const Config& config) { + _showDisplay = config.showDisplay; + _showNetwork = config.showNetwork; } void DrawStatus::run(const SceneContextPointer& sceneContext, diff --git a/libraries/render/src/render/DrawStatus.h b/libraries/render/src/render/DrawStatus.h index 982eba4990..d1caeca673 100644 --- a/libraries/render/src/render/DrawStatus.h +++ b/libraries/render/src/render/DrawStatus.h @@ -18,14 +18,15 @@ namespace render { class DrawStatusConfig : public Job::Config { Q_OBJECT - public: - DrawStatusConfig() : Job::Config(false) {} - Q_PROPERTY(bool enabled MEMBER enabled) Q_PROPERTY(bool showDisplay MEMBER showDisplay NOTIFY dirty) Q_PROPERTY(bool showNetwork MEMBER showDisplay NOTIFY dirty) + public: + DrawStatusConfig() : Job::Config(false) {} + bool showDisplay{ false }; bool showNetwork{ false }; + signals: void dirty(); }; @@ -38,7 +39,7 @@ namespace render { DrawStatus() {} DrawStatus(const gpu::TexturePointer statusIconMap) { setStatusIconMap(statusIconMap); } - void configure(const Config& configuration); + void configure(const Config& config); void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems); const gpu::PipelinePointer getDrawItemBoundsPipeline(); @@ -48,8 +49,8 @@ namespace render { const gpu::TexturePointer getStatusIconMap() const; protected: - bool _showDisplay{ false }; - bool _showNetwork{ false }; + bool _showDisplay; // initialized by Config + bool _showNetwork; // initialized by Config int _drawItemBoundPosLoc = -1; int _drawItemBoundDimLoc = -1; diff --git a/libraries/render/src/render/DrawTask.h b/libraries/render/src/render/DrawTask.h index 3ce1ed67fe..d2d9b0a80b 100755 --- a/libraries/render/src/render/DrawTask.h +++ b/libraries/render/src/render/DrawTask.h @@ -29,9 +29,10 @@ void renderShapes(const SceneContextPointer& sceneContext, const RenderContextPo class FetchItemsConfig : public Job::Config { Q_OBJECT -public: Q_PROPERTY(int numItems READ getNumItems) +public: int getNumItems() { return numItems; } + int numItems{ 0 }; }; @@ -45,7 +46,7 @@ public: ItemFilter _filter{ ItemFilter::Builder::opaqueShape().withoutLayered() }; - void configure(const Config&) {} + void configure(const Config& config) {} void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, ItemIDsBounds& outItems); }; diff --git a/libraries/render/src/render/Task.cpp b/libraries/render/src/render/Task.cpp index 1ceea6befe..0bf20c6042 100644 --- a/libraries/render/src/render/Task.cpp +++ b/libraries/render/src/render/Task.cpp @@ -10,12 +10,6 @@ // #include -#include // QObject - -#include "Context.h" - -#include "gpu/Batch.h" -#include #include "Task.h" diff --git a/libraries/render/src/render/Task.h b/libraries/render/src/render/Task.h index cfe37c257e..ac05fbe68a 100644 --- a/libraries/render/src/render/Task.h +++ b/libraries/render/src/render/Task.h @@ -19,9 +19,6 @@ #include "gpu/Batch.h" #include -// Prepare Qt for auto configurations -Q_DECLARE_METATYPE(std::shared_ptr) - namespace render { // A varying piece of data, to be used as Job/Task I/O @@ -53,25 +50,26 @@ protected: std::shared_ptr _concept; }; +class Job; +class Task; + // A default Config is always on; to create an enableable Config, use the ctor JobConfig(bool enabled) class JobConfig : public QObject { Q_OBJECT public: - JobConfig() : alwaysEnabled{ true }, enabled{ true } {} + JobConfig() = default; JobConfig(bool enabled) : alwaysEnabled{ false }, enabled{ enabled } {} bool isEnabled() { return alwaysEnabled || enabled; } bool alwaysEnabled{ true }; - bool enabled; + bool enabled{ true }; }; -class Task; - class TaskConfig : public JobConfig { Q_OBJECT public: - TaskConfig() : JobConfig() {} + TaskConfig() = default ; TaskConfig(bool enabled) : JobConfig(enabled) {} void init(Task* task) { _task = task; } @@ -82,6 +80,7 @@ public: } template void setJobEnabled(bool enable = true, std::string job = "") { + assert(getConfig(job)->alwaysEnabled != true); getConfig(job)->enabled = enable; refresh(); // trigger a Job->configure } @@ -96,24 +95,23 @@ private: Task* _task; }; -template void jobConfigure(T& model, const C& configuration) { - model.configure(configuration); +template void jobConfigure(T& data, const C& configuration) { + data.configure(configuration); } template void jobConfigure(T&, const JobConfig&) { + // nop, as the default JobConfig was used, so the data does not need a configure method } - -// FIXME: In c++17, use default classes of nullptr_t to combine these -template void jobRun(T& model, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { - model.run(sceneContext, renderContext); +template void jobRun(T& data, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + data.run(sceneContext, renderContext); } -template void jobRunI(T& model, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input) { - model.run(sceneContext, renderContext, input); +template void jobRunI(T& data, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input) { + data.run(sceneContext, renderContext, input); } -template void jobRunO(T& model, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, O& output) { - model.run(sceneContext, renderContext, output); +template void jobRunO(T& data, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, O& output) { + data.run(sceneContext, renderContext, output); } -template void jobRunIO(T& model, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input, O& output) { - model.run(sceneContext, renderContext, input, output); +template void jobRunIO(T& data, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input, O& output) { + data.run(sceneContext, renderContext, input, output); } class Job { @@ -285,12 +283,10 @@ public: public: using Data = T; - // TODO: Make Data a shared_ptr, and give Config a weak_ptr Data _data; - // The _config is unused; the model delegates to its data's _config - Model(Data data = Data()) : _data(data), Concept(std::make_shared()) { - _config = _data._config; + Model(Data data = Data()) : Concept(std::make_shared()), _data(data) { + _config = _data._config; // use the data's config std::static_pointer_cast(_config)->init(&_data); applyConfiguration(); @@ -341,7 +337,7 @@ public: protected: template friend class Model; - QConfigPointer _config { nullptr }; + QConfigPointer _config; Jobs _jobs; };