diff --git a/interface/src/avatar/CauterizedModel.cpp b/interface/src/avatar/CauterizedModel.cpp index c7d25d3151..d7b7e0fedf 100644 --- a/interface/src/avatar/CauterizedModel.cpp +++ b/interface/src/avatar/CauterizedModel.cpp @@ -16,6 +16,7 @@ #include #include "CauterizedMeshPartPayload.h" +#include "RenderUtilsLogging.h" CauterizedModel::CauterizedModel(RigPointer rig, QObject* parent) : @@ -51,7 +52,7 @@ void CauterizedModel::createVisibleRenderItemSet() { // all of our mesh vectors must match in size if ((int)meshes.size() != _meshStates.size()) { - qCDebug(renderlogging) << "WARNING!!!! Mesh Sizes don't match! We will not segregate mesh groups yet."; + qCDebug(renderutils) << "WARNING!!!! Mesh Sizes don't match! We will not segregate mesh groups yet."; return; } diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index bf4be7fd17..e2e22fe366 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -111,7 +111,7 @@ void setupPreferences() { static const QString SNAPSHOTS { "Snapshots" }; { auto getter = []()->QString { return Snapshot::snapshotsLocation.get(); }; - auto setter = [](const QString& value) { Snapshot::snapshotsLocation.set(value); }; + auto setter = [](const QString& value) { Snapshot::snapshotsLocation.set(value); emit DependencyManager::get()->snapshotLocationSet(value); }; auto preference = new BrowsePreference(SNAPSHOTS, "Put my snapshots here", getter, setter); preferences->addPreference(preference); } diff --git a/interface/src/ui/Snapshot.h b/interface/src/ui/Snapshot.h index 93ffbbc7bb..1246e1d004 100644 --- a/interface/src/ui/Snapshot.h +++ b/interface/src/ui/Snapshot.h @@ -44,6 +44,9 @@ public: static Setting::Handle snapshotsLocation; static void uploadSnapshot(const QString& filename, const QUrl& href = QUrl("")); +signals: + void snapshotLocationSet(const QString& value); + public slots: Q_INVOKABLE QString getSnapshotsLocation(); Q_INVOKABLE void setSnapshotsLocation(const QString& location); diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.h b/libraries/render-utils/src/AmbientOcclusionEffect.h index 92d0f1d375..3643e608ed 100644 --- a/libraries/render-utils/src/AmbientOcclusionEffect.h +++ b/libraries/render-utils/src/AmbientOcclusionEffect.h @@ -71,7 +71,7 @@ class AmbientOcclusionEffectConfig : public render::GPUJobConfig::Persistent { Q_PROPERTY(int blurRadius MEMBER blurRadius WRITE setBlurRadius) public: - AmbientOcclusionEffectConfig() : render::GPUJobConfig::Persistent("Ambient Occlusion", false) {} + AmbientOcclusionEffectConfig() : render::GPUJobConfig::Persistent(QStringList() << "Render" << "Engine" << "Ambient Occlusion", false) {} const int MAX_RESOLUTION_LEVEL = 4; const int MAX_BLUR_RADIUS = 6; diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index c5e694cb18..dcf0c84622 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -20,7 +20,6 @@ #include "model/Light.h" #include "model/Geometry.h" -#include "render/Context.h" #include #include "DeferredFrameTransform.h" diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 309182b25e..eddda41d5e 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1194,7 +1194,7 @@ void Model::createVisibleRenderItemSet() { // all of our mesh vectors must match in size if ((int)meshes.size() != _meshStates.size()) { - qCDebug(renderlogging) << "WARNING!!!! Mesh Sizes don't match! We will not segregate mesh groups yet."; + qCDebug(renderutils) << "WARNING!!!! Mesh Sizes don't match! We will not segregate mesh groups yet."; return; } diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index 0a4371cccd..d7ec087174 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -15,7 +15,6 @@ #include -#include #include #include #include diff --git a/libraries/render-utils/src/RenderShadowTask.h b/libraries/render-utils/src/RenderShadowTask.h index a044028e4d..031f44a42d 100644 --- a/libraries/render-utils/src/RenderShadowTask.h +++ b/libraries/render-utils/src/RenderShadowTask.h @@ -35,7 +35,7 @@ class RenderShadowTaskConfig : public render::Task::Config::Persistent { Q_OBJECT Q_PROPERTY(bool enabled MEMBER enabled NOTIFY dirty) public: - RenderShadowTaskConfig() : render::Task::Config::Persistent("Shadows", false) {} + RenderShadowTaskConfig() : render::Task::Config::Persistent(QStringList() << "Render" << "Engine" << "Shadows", false) {} signals: void dirty(); diff --git a/libraries/render/src/render/Context.h b/libraries/render/src/render/Context.h deleted file mode 100644 index cb0fc65d40..0000000000 --- a/libraries/render/src/render/Context.h +++ /dev/null @@ -1,32 +0,0 @@ -// -// Context.h -// render/src/render -// -// Created by Zach Pomerantz on 1/6/2015. -// Copyright 2015 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_render_Context_h -#define hifi_render_Context_h - -#include "Scene.h" - -namespace render { - - class JobConfig; - -class RenderContext { -public: - RenderArgs* args; - std::shared_ptr jobConfig{ nullptr }; - ScenePointer _scene; -}; -using RenderContextPointer = std::shared_ptr; - -} - -#endif // hifi_render_Context_h - diff --git a/libraries/render/src/render/Engine.h b/libraries/render/src/render/Engine.h index 68d86e6c16..240693b422 100644 --- a/libraries/render/src/render/Engine.h +++ b/libraries/render/src/render/Engine.h @@ -14,10 +14,67 @@ #include -#include "Context.h" -#include "Task.h" +#include "Scene.h" +#include "../task/Task.h" +#include "gpu/Batch.h" + namespace render { + + + class RenderContext : public task::JobContext { + public: + virtual ~RenderContext() {} + + RenderArgs* args; + ScenePointer _scene; + }; + using RenderContextPointer = std::shared_ptr; + + Task_DeclareTypeAliases(RenderContext) + + // Versions of the COnfig integrating a gpu & batch timer + class GPUJobConfig : public JobConfig { + Q_OBJECT + Q_PROPERTY(double gpuRunTime READ getGPURunTime) + Q_PROPERTY(double batchRunTime READ getBatchRunTime) + + double _msGPURunTime { 0.0 }; + double _msBatchRunTime { 0.0 }; + public: + using Persistent = PersistentConfig; + + GPUJobConfig() = default; + GPUJobConfig(bool enabled) : JobConfig(enabled) {} + + // Running Time measurement on GPU and for Batch execution + void setGPUBatchRunTime(double msGpuTime, double msBatchTime) { _msGPURunTime = msGpuTime; _msBatchRunTime = msBatchTime; } + double getGPURunTime() const { return _msGPURunTime; } + double getBatchRunTime() const { return _msBatchRunTime; } + }; + + class GPUTaskConfig : public TaskConfig { + Q_OBJECT + Q_PROPERTY(double gpuRunTime READ getGPURunTime) + Q_PROPERTY(double batchRunTime READ getBatchRunTime) + + double _msGPURunTime { 0.0 }; + double _msBatchRunTime { 0.0 }; + public: + + using Persistent = PersistentConfig; + + + GPUTaskConfig() = default; + GPUTaskConfig(bool enabled) : TaskConfig(enabled) {} + + // Running Time measurement on GPU and for Batch execution + void setGPUBatchRunTime(double msGpuTime, double msBatchTime) { _msGPURunTime = msGpuTime; _msBatchRunTime = msBatchTime; } + double getGPURunTime() const { return _msGPURunTime; } + double getBatchRunTime() const { return _msBatchRunTime; } + }; + + // The render engine holds all render tasks, and is itself a render task. // State flows through tasks to jobs via the render and scene contexts - // the engine should not be known from its jobs. @@ -43,6 +100,8 @@ namespace render { protected: RenderContextPointer _renderContext; + + void run(const RenderContextPointer& context) override { assert(_renderContext); Task::run(_renderContext); } }; using EnginePointer = std::shared_ptr; diff --git a/libraries/render/src/render/RenderFetchCullSortTask.h b/libraries/render/src/render/RenderFetchCullSortTask.h index 12bcb9786d..f32293f001 100644 --- a/libraries/render/src/render/RenderFetchCullSortTask.h +++ b/libraries/render/src/render/RenderFetchCullSortTask.h @@ -13,8 +13,6 @@ #define hifi_RenderFetchCullSortTask_h #include - -#include "Task.h" #include "CullTask.h" class RenderFetchCullSortTask { diff --git a/libraries/render/src/render/Task.h b/libraries/render/src/render/Task.h deleted file mode 100644 index 1035b74340..0000000000 --- a/libraries/render/src/render/Task.h +++ /dev/null @@ -1,745 +0,0 @@ -// -// Task.h -// render/src/render -// -// Created by Zach Pomerantz on 1/6/2016. -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_render_Task_h -#define hifi_render_Task_h -#include - -#include - -#include -#include -#include -#include - -#include "SettingHandle.h" - -#include "Context.h" -#include "Logging.h" - -#include "gpu/Batch.h" -#include - -namespace render { - -class Varying; - - -// A varying piece of data, to be used as Job/Task I/O -// TODO: Task IO -class Varying { -public: - Varying() {} - Varying(const Varying& var) : _concept(var._concept) {} - Varying& operator=(const Varying& var) { - _concept = var._concept; - return (*this); - } - template Varying(const T& data) : _concept(std::make_shared>(data)) {} - - template bool canCast() const { return !!std::dynamic_pointer_cast>(_concept); } - template const T& get() const { return std::static_pointer_cast>(_concept)->_data; } - template T& edit() { return std::static_pointer_cast>(_concept)->_data; } - - - // access potential sub varyings contained in this one. - Varying operator[] (uint8_t index) const { return (*_concept)[index]; } - uint8_t length() const { return (*_concept).length(); } - - template Varying getN (uint8_t index) const { return get()[index]; } - template Varying editN (uint8_t index) { return edit()[index]; } - -protected: - class Concept { - public: - virtual ~Concept() = default; - - virtual Varying operator[] (uint8_t index) const = 0; - virtual uint8_t length() const = 0; - }; - template class Model : public Concept { - public: - using Data = T; - - Model(const Data& data) : _data(data) {} - virtual ~Model() = default; - - virtual Varying operator[] (uint8_t index) const override { - Varying var; - return var; - } - virtual uint8_t length() const override { return 0; } - - Data _data; - }; - - std::shared_ptr _concept; -}; - -using VaryingPairBase = std::pair; -template < typename T0, typename T1 > -class VaryingSet2 : public VaryingPairBase { -public: - using Parent = VaryingPairBase; - typedef void is_proxy_tag; - - VaryingSet2() : Parent(Varying(T0()), Varying(T1())) {} - VaryingSet2(const VaryingSet2& pair) : Parent(pair.first, pair.second) {} - VaryingSet2(const Varying& first, const Varying& second) : Parent(first, second) {} - - const T0& get0() const { return first.get(); } - T0& edit0() { return first.edit(); } - - const T1& get1() const { return second.get(); } - T1& edit1() { return second.edit(); } - - virtual Varying operator[] (uint8_t index) const { - if (index == 1) { - return std::get<1>((*this)); - } else { - return std::get<0>((*this)); - } - } - virtual uint8_t length() const { return 2; } - - Varying hasVarying() const { return Varying((*this)); } -}; - - -template -class VaryingSet3 : public std::tuple{ -public: - using Parent = std::tuple; - - VaryingSet3() : Parent(Varying(T0()), Varying(T1()), Varying(T2())) {} - VaryingSet3(const VaryingSet3& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src)) {} - VaryingSet3(const Varying& first, const Varying& second, const Varying& third) : Parent(first, second, third) {} - - const T0& get0() const { return std::get<0>((*this)).template get(); } - T0& edit0() { return std::get<0>((*this)).template edit(); } - - const T1& get1() const { return std::get<1>((*this)).template get(); } - T1& edit1() { return std::get<1>((*this)).template edit(); } - - const T2& get2() const { return std::get<2>((*this)).template get(); } - T2& edit2() { return std::get<2>((*this)).template edit(); } - - virtual Varying operator[] (uint8_t index) const { - if (index == 2) { - return std::get<2>((*this)); - } else if (index == 1) { - return std::get<1>((*this)); - } else { - return std::get<0>((*this)); - } - } - virtual uint8_t length() const { return 3; } - - Varying hasVarying() const { return Varying((*this)); } -}; - -template -class VaryingSet4 : public std::tuple{ -public: - using Parent = std::tuple; - - VaryingSet4() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3())) {} - VaryingSet4(const VaryingSet4& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src)) {} - VaryingSet4(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth) : Parent(first, second, third, fourth) {} - - const T0& get0() const { return std::get<0>((*this)).template get(); } - T0& edit0() { return std::get<0>((*this)).template edit(); } - - const T1& get1() const { return std::get<1>((*this)).template get(); } - T1& edit1() { return std::get<1>((*this)).template edit(); } - - const T2& get2() const { return std::get<2>((*this)).template get(); } - T2& edit2() { return std::get<2>((*this)).template edit(); } - - const T3& get3() const { return std::get<3>((*this)).template get(); } - T3& edit3() { return std::get<3>((*this)).template edit(); } - - virtual Varying operator[] (uint8_t index) const { - if (index == 3) { - return std::get<3>((*this)); - } else if (index == 2) { - return std::get<2>((*this)); - } else if (index == 1) { - return std::get<1>((*this)); - } else { - return std::get<0>((*this)); - } - } - virtual uint8_t length() const { return 4; } - - Varying hasVarying() const { return Varying((*this)); } -}; - - -template -class VaryingSet5 : public std::tuple{ -public: - using Parent = std::tuple; - - VaryingSet5() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3()), Varying(T4())) {} - VaryingSet5(const VaryingSet5& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src), std::get<4>(src)) {} - VaryingSet5(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth, const Varying& fifth) : Parent(first, second, third, fourth, fifth) {} - - const T0& get0() const { return std::get<0>((*this)).template get(); } - T0& edit0() { return std::get<0>((*this)).template edit(); } - - const T1& get1() const { return std::get<1>((*this)).template get(); } - T1& edit1() { return std::get<1>((*this)).template edit(); } - - const T2& get2() const { return std::get<2>((*this)).template get(); } - T2& edit2() { return std::get<2>((*this)).template edit(); } - - const T3& get3() const { return std::get<3>((*this)).template get(); } - T3& edit3() { return std::get<3>((*this)).template edit(); } - - const T4& get4() const { return std::get<4>((*this)).template get(); } - T4& edit4() { return std::get<4>((*this)).template edit(); } - - virtual Varying operator[] (uint8_t index) const { - if (index == 4) { - return std::get<4>((*this)); - } else if (index == 3) { - return std::get<3>((*this)); - } else if (index == 2) { - return std::get<2>((*this)); - } else if (index == 1) { - return std::get<1>((*this)); - } else { - return std::get<0>((*this)); - } - } - virtual uint8_t length() const { return 5; } - - Varying hasVarying() const { return Varying((*this)); } -}; - -template -class VaryingSet6 : public std::tuple{ -public: - using Parent = std::tuple; - - VaryingSet6() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3()), Varying(T4()), Varying(T5())) {} - VaryingSet6(const VaryingSet6& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src), std::get<4>(src), std::get<5>(src)) {} - VaryingSet6(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth, const Varying& fifth, const Varying& sixth) : Parent(first, second, third, fourth, fifth, sixth) {} - - const T0& get0() const { return std::get<0>((*this)).template get(); } - T0& edit0() { return std::get<0>((*this)).template edit(); } - - const T1& get1() const { return std::get<1>((*this)).template get(); } - T1& edit1() { return std::get<1>((*this)).template edit(); } - - const T2& get2() const { return std::get<2>((*this)).template get(); } - T2& edit2() { return std::get<2>((*this)).template edit(); } - - const T3& get3() const { return std::get<3>((*this)).template get(); } - T3& edit3() { return std::get<3>((*this)).template edit(); } - - const T4& get4() const { return std::get<4>((*this)).template get(); } - T4& edit4() { return std::get<4>((*this)).template edit(); } - - const T5& get5() const { return std::get<5>((*this)).template get(); } - T5& edit5() { return std::get<5>((*this)).template edit(); } - - Varying hasVarying() const { return Varying((*this)); } -}; - -template -class VaryingSet7 : public std::tuple{ -public: - using Parent = std::tuple; - - VaryingSet7() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3()), Varying(T4()), Varying(T5()), Varying(T6())) {} - VaryingSet7(const VaryingSet7& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src), std::get<4>(src), std::get<5>(src), std::get<6>(src)) {} - VaryingSet7(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth, const Varying& fifth, const Varying& sixth, const Varying& seventh) : Parent(first, second, third, fourth, fifth, sixth, seventh) {} - - const T0& get0() const { return std::get<0>((*this)).template get(); } - T0& edit0() { return std::get<0>((*this)).template edit(); } - - const T1& get1() const { return std::get<1>((*this)).template get(); } - T1& edit1() { return std::get<1>((*this)).template edit(); } - - const T2& get2() const { return std::get<2>((*this)).template get(); } - T2& edit2() { return std::get<2>((*this)).template edit(); } - - const T3& get3() const { return std::get<3>((*this)).template get(); } - T3& edit3() { return std::get<3>((*this)).template edit(); } - - const T4& get4() const { return std::get<4>((*this)).template get(); } - T4& edit4() { return std::get<4>((*this)).template edit(); } - - const T5& get5() const { return std::get<5>((*this)).template get(); } - T5& edit5() { return std::get<5>((*this)).template edit(); } - - const T6& get6() const { return std::get<6>((*this)).template get(); } - T6& edit6() { return std::get<6>((*this)).template edit(); } - - Varying hasVarying() const { return Varying((*this)); } -}; - - -template < class T, int NUM > -class VaryingArray : public std::array { -public: - VaryingArray() { - for (size_t i = 0; i < NUM; i++) { - (*this)[i] = Varying(T()); - } - } -}; - -class Job; -class JobConcept; -class Task; -class JobNoIO {}; - -template class PersistentConfig : public C { -public: - const QString DEFAULT = "Default"; - const QString NONE = "None"; - - PersistentConfig() = delete; - PersistentConfig(const QString& path) : - _preset(QStringList() << "Render" << "Engine" << path, DEFAULT) { } - PersistentConfig(const QStringList& path) : - _preset(QStringList() << "Render" << "Engine" << path, DEFAULT) { } - PersistentConfig(const QString& path, bool enabled) : C(enabled), - _preset(QStringList() << "Render" << "Engine" << path, enabled ? DEFAULT : NONE) { } - PersistentConfig(const QStringList& path, bool enabled) : C(enabled), - _preset(QStringList() << "Render" << "Engine" << path, enabled ? DEFAULT : NONE) { } - - QStringList getPresetList() { - if (_presets.empty()) { - setPresetList(QJsonObject()); - } - return _presets.keys(); - } - - virtual void setPresetList(const QJsonObject& list) override { - assert(_presets.empty()); - - _default = toJsonValue(*this).toObject().toVariantMap(); - - _presets.unite(list.toVariantMap()); - if (C::alwaysEnabled || C::enabled) { - _presets.insert(DEFAULT, _default); - } - if (!C::alwaysEnabled) { - _presets.insert(NONE, QVariantMap{{ "enabled", false }}); - } - - auto preset = _preset.get(); - if (preset != _preset.getDefault() && _presets.contains(preset)) { - // Load the persisted configuration - C::load(_presets[preset].toMap()); - } - } - - QString getPreset() { return _preset.get(); } - - void setPreset(const QString& preset) { - _preset.set(preset); - if (_presets.contains(preset)) { - // Always start back at default to remain deterministic - QVariantMap config = _default; - QVariantMap presetConfig = _presets[preset].toMap(); - for (auto it = presetConfig.cbegin(); it != presetConfig.cend(); it++) { - config.insert(it.key(), it.value()); - } - C::load(config); - } - } - -protected: - QVariantMap _default; - QVariantMap _presets; - Setting::Handle _preset; -}; - -// A default Config is always on; to create an enableable Config, use the ctor JobConfig(bool enabled) -class JobConfig : public QObject { - Q_OBJECT - Q_PROPERTY(double cpuRunTime READ getCPURunTime NOTIFY newStats()) //ms - Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) - - double _msCPURunTime{ 0.0 }; -public: - using Persistent = PersistentConfig; - - JobConfig() = default; - JobConfig(bool enabled) : alwaysEnabled{ false }, enabled{ enabled } {} - - bool isEnabled() { return alwaysEnabled || enabled; } - void setEnabled(bool enable) { enabled = alwaysEnabled || enable; } - - bool alwaysEnabled{ true }; - bool enabled{ true }; - - virtual void setPresetList(const QJsonObject& object) { - for (auto it = object.begin(); it != object.end(); it++) { - JobConfig* child = findChild(it.key(), Qt::FindDirectChildrenOnly); - if (child) { - child->setPresetList(it.value().toObject()); - } - } - } - - // This must be named toJSON to integrate with the global scripting JSON object - Q_INVOKABLE QString toJSON() { return QJsonDocument(toJsonValue(*this).toObject()).toJson(QJsonDocument::Compact); } - Q_INVOKABLE void load(const QVariantMap& map) { qObjectFromJsonValue(QJsonObject::fromVariantMap(map), *this); emit loaded(); } - - // Running Time measurement - // The new stats signal is emitted once per run time of a job when stats (cpu runtime) are updated - void setCPURunTime(double mstime) { _msCPURunTime = mstime; emit newStats(); } - double getCPURunTime() const { return _msCPURunTime; } - -public slots: - void load(const QJsonObject& val) { qObjectFromJsonValue(val, *this); emit loaded(); } - -signals: - void loaded(); - void newStats(); -}; - -class TaskConfig : public JobConfig { - Q_OBJECT -public: - using QConfigPointer = std::shared_ptr; - - using Persistent = PersistentConfig; - - TaskConfig() = default ; - TaskConfig(bool enabled) : JobConfig(enabled) {} - - // getter for qml integration, prefer the templated getter - Q_INVOKABLE QObject* getConfig(const QString& name) { return QObject::findChild(name); } - // getter for cpp (strictly typed), prefer this getter - template typename T::Config* getConfig(std::string job = "") const { - QString name = job.empty() ? QString() : QString(job.c_str()); // an empty string is not a null string - return findChild(name); - } - - void connectChildConfig(QConfigPointer childConfig, const std::string& name); - void transferChildrenConfigs(QConfigPointer source); - -public slots: - void refresh(); - -private: - friend Task; - JobConcept* _task; -}; - -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 -} -template void jobConfigure(T&, const TaskConfig&) { - // nop, as the default TaskConfig was used, so the data does not need a configure method -} -template void jobRun(T& data, const RenderContextPointer& renderContext, const JobNoIO& input, JobNoIO& output) { - data.run(renderContext); -} -template void jobRun(T& data, const RenderContextPointer& renderContext, const I& input, JobNoIO& output) { - data.run(renderContext, input); -} -template void jobRun(T& data, const RenderContextPointer& renderContext, const JobNoIO& input, O& output) { - data.run(renderContext, output); -} -template void jobRun(T& data, const RenderContextPointer& renderContext, const I& input, O& output) { - data.run(renderContext, input, output); -} - -// The guts of a job -class JobConcept { -public: - using Config = JobConfig; - using QConfigPointer = std::shared_ptr; - - JobConcept(QConfigPointer config) : _config(config) {} - virtual ~JobConcept() = default; - - virtual const Varying getInput() const { return Varying(); } - virtual const Varying getOutput() const { return Varying(); } - - virtual QConfigPointer& getConfiguration() { return _config; } - virtual void applyConfiguration() = 0; - - virtual void run(const RenderContextPointer& renderContext) = 0; - -protected: - void setCPURunTime(double mstime) { std::static_pointer_cast(_config)->setCPURunTime(mstime); } - - QConfigPointer _config; - - friend class Job; -}; - -class Job { -public: - using Concept = JobConcept; - using Config = JobConfig; - using QConfigPointer = std::shared_ptr; - using None = JobNoIO; - using ConceptPointer = std::shared_ptr; - - template class Model : public Concept { - public: - using Data = T; - using Input = I; - using Output = O; - - Data _data; - Varying _input; - Varying _output; - - const Varying getInput() const override { return _input; } - const Varying getOutput() const override { return _output; } - - template - Model(const Varying& input, QConfigPointer config, A&&... args) : - Concept(config), - _data(Data(std::forward(args)...)), - _input(input), - _output(Output()) { - applyConfiguration(); - } - - template - static std::shared_ptr create(const Varying& input, A&&... args) { - return std::make_shared(input, std::make_shared(), std::forward(args)...); - } - - - void applyConfiguration() override { - jobConfigure(_data, *std::static_pointer_cast(_config)); - } - - void run(const RenderContextPointer& renderContext) override { - renderContext->jobConfig = std::static_pointer_cast(_config); - if (renderContext->jobConfig->alwaysEnabled || renderContext->jobConfig->isEnabled()) { - jobRun(_data, renderContext, _input.get(), _output.edit()); - } - renderContext->jobConfig.reset(); - } - }; - template using ModelI = Model; - template using ModelO = Model; - template using ModelIO = Model; - - Job(std::string name, ConceptPointer concept) : _concept(concept), _name(name) {} - - const Varying getInput() const { return _concept->getInput(); } - const Varying getOutput() const { return _concept->getOutput(); } - QConfigPointer& getConfiguration() const { return _concept->getConfiguration(); } - void applyConfiguration() { return _concept->applyConfiguration(); } - - template T& edit() { - auto concept = std::static_pointer_cast(_concept); - assert(concept); - return concept->_data; - } - - void run(const RenderContextPointer& renderContext) { - PerformanceTimer perfTimer(_name.c_str()); - PROFILE_RANGE(render, _name.c_str()); - auto start = usecTimestampNow(); - - _concept->run(renderContext); - - _concept->setCPURunTime((double)(usecTimestampNow() - start) / 1000.0); - } - -protected: - ConceptPointer _concept; - std::string _name = ""; -}; - -// A task is a specialized job to run a collection of other jobs -// It can be created on any type T by aliasing the type JobModel in the class T -// using JobModel = Task::Model -// 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 task -// where the input of the task can be setup to feed the child jobs -// and where the output of the task is defined -class Task : public Job { -public: - using Config = TaskConfig; - using QConfigPointer = Job::QConfigPointer; - using None = Job::None; - using Concept = Job::Concept; - using Jobs = std::vector; - - Task(std::string name, ConceptPointer concept) : Job(name, concept) {} - - class TaskConcept : public Concept { - public: - Varying _input; - Varying _output; - Jobs _jobs; - - const Varying getInput() const override { return _input; } - const Varying getOutput() const override { return _output; } - - TaskConcept(const Varying& input, QConfigPointer config) : Concept(config), _input(input) {} - - // Create a new job in the container's queue; returns the job's output - template const Varying addJob(std::string name, const Varying& input, NA&&... args) { - _jobs.emplace_back(name, (NT::JobModel::create(input, std::forward(args)...))); - - // Conect the child config to this task's config - std::static_pointer_cast(getConfiguration())->connectChildConfig(_jobs.back().getConfiguration(), name); - - return _jobs.back().getOutput(); - } - template const Varying addJob(std::string name, NA&&... args) { - const auto input = Varying(typename NT::JobModel::Input()); - return addJob(name, input, std::forward(args)...); - } - }; - - template class TaskModel : public TaskConcept { - public: - using Data = T; - using Input = I; - using Output = O; - - Data _data; - - TaskModel(const Varying& input, QConfigPointer config) : - TaskConcept(input, config), - _data(Data()) {} - - template - static std::shared_ptr create(const Varying& input, A&&... args) { - auto model = std::make_shared(input, std::make_shared()); - // std::static_pointer_cast(model->_config)->_task = model.get(); - - model->_data.build(*(model), model->_input, model->_output, std::forward(args)...); - - // Recreate the Config to use the templated type - model->createConfiguration(); - model->applyConfiguration(); - - return model; - } - - template - static std::shared_ptr create(A&&... args) { - const auto input = Varying(Input()); - return create(input, std::forward(args)...); - } - - void createConfiguration() { - // A brand new config - auto config = std::make_shared(); - // Make sure we transfer the former children configs to the new config - config->transferChildrenConfigs(_config); - // swap - _config = config; - // Capture this - std::static_pointer_cast(_config)->_task = this; - } - - QConfigPointer& getConfiguration() override { - if (!_config) { - createConfiguration(); - } - return _config; - } - - void applyConfiguration() override { - jobConfigure(_data, *std::static_pointer_cast(_config)); - for (auto& job : _jobs) { - job.applyConfiguration(); - } - } - - void run(const RenderContextPointer& renderContext) override { - auto config = std::static_pointer_cast(_config); - if (config->alwaysEnabled || config->enabled) { - for (auto job : _jobs) { - job.run(renderContext); - } - } - } - }; - template using Model = TaskModel; - template using ModelI = TaskModel; - template using ModelO = TaskModel; - template using ModelIO = TaskModel; - - // Create a new job in the Task's queue; returns the job's output - template const Varying addJob(std::string name, const Varying& input, A&&... args) { - return std::static_pointer_cast( _concept)->addJob(name, input, std::forward(args)...); - } - template const Varying addJob(std::string name, A&&... args) { - const auto input = Varying(typename T::JobModel::Input()); - return std::static_pointer_cast( _concept)->addJob(name, input, std::forward(args)...); - } - - std::shared_ptr getConfiguration() { - return std::static_pointer_cast(_concept->getConfiguration()); - } - -protected: -}; - -// Versions of the COnfig integrating a gpu & batch timer -class GPUJobConfig : public JobConfig { - Q_OBJECT - Q_PROPERTY(double gpuRunTime READ getGPURunTime) - Q_PROPERTY(double batchRunTime READ getBatchRunTime) - - double _msGPURunTime { 0.0 }; - double _msBatchRunTime { 0.0 }; -public: - using Persistent = PersistentConfig; - - GPUJobConfig() = default; - GPUJobConfig(bool enabled) : JobConfig(enabled) {} - - // Running Time measurement on GPU and for Batch execution - void setGPUBatchRunTime(double msGpuTime, double msBatchTime) { _msGPURunTime = msGpuTime; _msBatchRunTime = msBatchTime; } - double getGPURunTime() const { return _msGPURunTime; } - double getBatchRunTime() const { return _msBatchRunTime; } -}; - -class GPUTaskConfig : public TaskConfig { - Q_OBJECT - Q_PROPERTY(double gpuRunTime READ getGPURunTime) - Q_PROPERTY(double batchRunTime READ getBatchRunTime) - - double _msGPURunTime { 0.0 }; - double _msBatchRunTime { 0.0 }; -public: - - using Persistent = PersistentConfig; - - - GPUTaskConfig() = default; - GPUTaskConfig(bool enabled) : TaskConfig(enabled) {} - - // Running Time measurement on GPU and for Batch execution - void setGPUBatchRunTime(double msGpuTime, double msBatchTime) { _msGPURunTime = msGpuTime; _msBatchRunTime = msBatchTime; } - double getGPURunTime() const { return _msGPURunTime; } - double getBatchRunTime() const { return _msBatchRunTime; } -}; - -} - -#endif // hifi_render_Task_h diff --git a/libraries/render/src/render/Task.cpp b/libraries/render/src/task/Config.cpp similarity index 81% rename from libraries/render/src/render/Task.cpp rename to libraries/render/src/task/Config.cpp index 13476f102e..cb2c4f1e3c 100644 --- a/libraries/render/src/render/Task.cpp +++ b/libraries/render/src/task/Config.cpp @@ -1,6 +1,6 @@ // -// Task.cpp -// render/src/render +// Config.cpp +// render/src/task // // Created by Zach Pomerantz on 1/21/2016. // Copyright 2016 High Fidelity, Inc. @@ -8,12 +8,21 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // - -#include +#include "Config.h" #include "Task.h" +#include -using namespace render; +using namespace task; + +void JobConfig::setPresetList(const QJsonObject& object) { + for (auto it = object.begin(); it != object.end(); it++) { + JobConfig* child = findChild(it.key(), Qt::FindDirectChildrenOnly); + if (child) { + child->setPresetList(it.value().toObject()); + } + } +} void TaskConfig::connectChildConfig(QConfigPointer childConfig, const std::string& name) { childConfig->setParent(this); diff --git a/libraries/render/src/task/Config.h b/libraries/render/src/task/Config.h new file mode 100644 index 0000000000..c78a3f3bfe --- /dev/null +++ b/libraries/render/src/task/Config.h @@ -0,0 +1,157 @@ +// +// Config.h +// render/src/render +// +// Created by Zach Pomerantz on 1/6/2016. +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_task_Config_h +#define hifi_task_Config_h + +#include +#include +#include +#include +#include + +#include "SettingHandle.h" + +#include "Logging.h" + +namespace task { + +class JobConcept; + +template class PersistentConfig : public C { +public: + const QString DEFAULT = "Default"; + const QString NONE = "None"; + + PersistentConfig() = delete; + PersistentConfig(const QStringList& path) : + _preset(path, DEFAULT) { } + PersistentConfig(const QStringList& path, bool enabled) : C(enabled), + _preset(path, enabled ? DEFAULT : NONE) { } + + QStringList getPresetList() { + if (_presets.empty()) { + setPresetList(QJsonObject()); + } + return _presets.keys(); + } + + virtual void setPresetList(const QJsonObject& list) override { + assert(_presets.empty()); + + _default = toJsonValue(*this).toObject().toVariantMap(); + + _presets.unite(list.toVariantMap()); + if (C::alwaysEnabled || C::enabled) { + _presets.insert(DEFAULT, _default); + } + if (!C::alwaysEnabled) { + _presets.insert(NONE, QVariantMap{{ "enabled", false }}); + } + + auto preset = _preset.get(); + if (preset != _preset.getDefault() && _presets.contains(preset)) { + // Load the persisted configuration + C::load(_presets[preset].toMap()); + } + } + + QString getPreset() { return _preset.get(); } + + void setPreset(const QString& preset) { + _preset.set(preset); + if (_presets.contains(preset)) { + // Always start back at default to remain deterministic + QVariantMap config = _default; + QVariantMap presetConfig = _presets[preset].toMap(); + for (auto it = presetConfig.cbegin(); it != presetConfig.cend(); it++) { + config.insert(it.key(), it.value()); + } + C::load(config); + } + } + +protected: + QVariantMap _default; + QVariantMap _presets; + Setting::Handle _preset; +}; + +// A default Config is always on; to create an enableable Config, use the ctor JobConfig(bool enabled) +class JobConfig : public QObject { + Q_OBJECT + Q_PROPERTY(double cpuRunTime READ getCPURunTime NOTIFY newStats()) //ms + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) + + double _msCPURunTime{ 0.0 }; +public: + using Persistent = PersistentConfig; + + JobConfig() = default; + JobConfig(bool enabled) : alwaysEnabled{ false }, enabled{ enabled } {} + + bool isEnabled() { return alwaysEnabled || enabled; } + void setEnabled(bool enable) { enabled = alwaysEnabled || enable; } + + bool alwaysEnabled{ true }; + bool enabled{ true }; + + virtual void setPresetList(const QJsonObject& object); + + // This must be named toJSON to integrate with the global scripting JSON object + Q_INVOKABLE QString toJSON() { return QJsonDocument(toJsonValue(*this).toObject()).toJson(QJsonDocument::Compact); } + Q_INVOKABLE void load(const QVariantMap& map) { qObjectFromJsonValue(QJsonObject::fromVariantMap(map), *this); emit loaded(); } + + // Running Time measurement + // The new stats signal is emitted once per run time of a job when stats (cpu runtime) are updated + void setCPURunTime(double mstime) { _msCPURunTime = mstime; emit newStats(); } + double getCPURunTime() const { return _msCPURunTime; } + +public slots: + void load(const QJsonObject& val) { qObjectFromJsonValue(val, *this); emit loaded(); } + +signals: + void loaded(); + void newStats(); +}; + +class TaskConfig : public JobConfig { + Q_OBJECT +public: + using QConfigPointer = std::shared_ptr; + + using Persistent = PersistentConfig; + + TaskConfig() = default ; + TaskConfig(bool enabled) : JobConfig(enabled) {} + + // getter for qml integration, prefer the templated getter + Q_INVOKABLE QObject* getConfig(const QString& name) { return QObject::findChild(name); } + // getter for cpp (strictly typed), prefer this getter + template typename T::Config* getConfig(std::string job = "") const { + QString name = job.empty() ? QString() : QString(job.c_str()); // an empty string is not a null string + return findChild(name); + } + + void connectChildConfig(QConfigPointer childConfig, const std::string& name); + void transferChildrenConfigs(QConfigPointer source); + + JobConcept* _task; + +public slots: + void refresh(); +}; + +using QConfigPointer = std::shared_ptr; + +} + +#endif // hifi_task_Config_h diff --git a/libraries/render/src/task/Task.h b/libraries/render/src/task/Task.h new file mode 100644 index 0000000000..ed335150a7 --- /dev/null +++ b/libraries/render/src/task/Task.h @@ -0,0 +1,323 @@ +// +// Task.h +// render/src/task +// +// Created by Zach Pomerantz on 1/6/2016. +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_task_Task_h +#define hifi_task_Task_h + +#include "Config.h" +#include "Varying.h" + +#include "SettingHandle.h" + +#include "Logging.h" + +#include +#include + +namespace task { + +class JobConcept; +template class JobT; +template class TaskT; +class JobNoIO {}; + +class JobContext { +public: + virtual ~JobContext() {} + + std::shared_ptr jobConfig { nullptr }; +}; +using JobContextPointer = std::shared_ptr; + +// The guts of a job +class JobConcept { +public: + using Config = JobConfig; + + JobConcept(QConfigPointer config) : _config(config) {} + virtual ~JobConcept() = default; + + virtual const Varying getInput() const { return Varying(); } + virtual const Varying getOutput() const { return Varying(); } + + virtual QConfigPointer& getConfiguration() { return _config; } + virtual void applyConfiguration() = 0; + + void setCPURunTime(double mstime) { std::static_pointer_cast(_config)->setCPURunTime(mstime); } + + QConfigPointer _config; +protected: +}; + + +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 +} +template void jobConfigure(T&, const TaskConfig&) { + // nop, as the default TaskConfig was used, so the data does not need a configure method +} + +template void jobRun(T& data, const RC& renderContext, const JobNoIO& input, JobNoIO& output) { + data.run(renderContext); +} +template void jobRun(T& data, const RC& renderContext, const I& input, JobNoIO& output) { + data.run(renderContext, input); +} +template void jobRun(T& data, const RC& renderContext, const JobNoIO& input, O& output) { + data.run(renderContext, output); +} +template void jobRun(T& data, const RC& renderContext, const I& input, O& output) { + data.run(renderContext, input, output); +} + +template +class Job { +public: + using Context = RC; + using ContextPointer = std::shared_ptr; + using Config = JobConfig; + using None = JobNoIO; + + class Concept : public JobConcept { + public: + Concept(QConfigPointer config) : JobConcept(config) {} + virtual ~Concept() = default; + + virtual void run(const ContextPointer& renderContext) = 0; + }; + using ConceptPointer = std::shared_ptr; + + template class Model : public Concept { + public: + using Data = T; + using Input = I; + using Output = O; + + Data _data; + Varying _input; + Varying _output; + + const Varying getInput() const override { return _input; } + const Varying getOutput() const override { return _output; } + + template + Model(const Varying& input, QConfigPointer config, A&&... args) : + Concept(config), + _data(Data(std::forward(args)...)), + _input(input), + _output(Output()) { + applyConfiguration(); + } + + template + static std::shared_ptr create(const Varying& input, A&&... args) { + return std::make_shared(input, std::make_shared(), std::forward(args)...); + } + + + void applyConfiguration() override { + jobConfigure(_data, *std::static_pointer_cast(Concept::_config)); + } + + void run(const ContextPointer& renderContext) override { + renderContext->jobConfig = std::static_pointer_cast(Concept::_config); + if (renderContext->jobConfig->alwaysEnabled || renderContext->jobConfig->isEnabled()) { + jobRun(_data, renderContext, _input.get(), _output.edit()); + } + renderContext->jobConfig.reset(); + } + }; + template using ModelI = Model; + template using ModelO = Model; + template using ModelIO = Model; + + Job(std::string name, ConceptPointer concept) : _concept(concept), _name(name) {} + + const Varying getInput() const { return _concept->getInput(); } + const Varying getOutput() const { return _concept->getOutput(); } + QConfigPointer& getConfiguration() const { return _concept->getConfiguration(); } + void applyConfiguration() { return _concept->applyConfiguration(); } + + template T& edit() { + auto concept = std::static_pointer_cast(_concept); + assert(concept); + return concept->_data; + } + + virtual void run(const ContextPointer& renderContext) { + PerformanceTimer perfTimer(_name.c_str()); + PROFILE_RANGE(render, _name.c_str()); + auto start = usecTimestampNow(); + + _concept->run(renderContext); + + _concept->setCPURunTime((double)(usecTimestampNow() - start) / 1000.0); + } + +protected: + ConceptPointer _concept; + std::string _name = ""; +}; + +// A task is a specialized job to run a collection of other jobs +// It can be created on any type T by aliasing the type JobModel in the class T +// using JobModel = Task::Model +// 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 task +// where the input of the task can be setup to feed the child jobs +// and where the output of the task is defined +template +class Task : public Job { +public: + using Context = RC; + using ContextPointer = std::shared_ptr; + using Config = TaskConfig; + using JobType = Job; + using None = typename JobType::None; + using Concept = typename JobType::Concept; + using ConceptPointer = typename JobType::ConceptPointer; + using Jobs = std::vector; + + Task(std::string name, ConceptPointer concept) : JobType(name, concept) {} + + class TaskConcept : public Concept { + public: + Varying _input; + Varying _output; + Jobs _jobs; + + const Varying getInput() const override { return _input; } + const Varying getOutput() const override { return _output; } + + TaskConcept(const Varying& input, QConfigPointer config) : Concept(config), _input(input) {} + + // Create a new job in the container's queue; returns the job's output + template const Varying addJob(std::string name, const Varying& input, NA&&... args) { + _jobs.emplace_back(name, (NT::JobModel::create(input, std::forward(args)...))); + + // Conect the child config to this task's config + std::static_pointer_cast(Concept::getConfiguration())->connectChildConfig(_jobs.back().getConfiguration(), name); + + return _jobs.back().getOutput(); + } + template const Varying addJob(std::string name, NA&&... args) { + const auto input = Varying(typename NT::JobModel::Input()); + return addJob(name, input, std::forward(args)...); + } + }; + + template class TaskModel : public TaskConcept { + public: + using Data = T; + using Input = I; + using Output = O; + + Data _data; + + TaskModel(const Varying& input, QConfigPointer config) : + TaskConcept(input, config), + _data(Data()) {} + + template + static std::shared_ptr create(const Varying& input, A&&... args) { + auto model = std::make_shared(input, std::make_shared()); + + model->_data.build(*(model), model->_input, model->_output, std::forward(args)...); + + // Recreate the Config to use the templated type + model->createConfiguration(); + model->applyConfiguration(); + + return model; + } + + template + static std::shared_ptr create(A&&... args) { + const auto input = Varying(Input()); + return create(input, std::forward(args)...); + } + + void createConfiguration() { + // A brand new config + auto config = std::make_shared(); + // Make sure we transfer the former children configs to the new config + config->transferChildrenConfigs(Concept::_config); + // swap + Concept::_config = config; + // Capture this + std::static_pointer_cast(Concept::_config)->_task = this; + } + + QConfigPointer& getConfiguration() override { + if (!Concept::_config) { + createConfiguration(); + } + return Concept::_config; + } + + void applyConfiguration() override { + jobConfigure(_data, *std::static_pointer_cast(Concept::_config)); + for (auto& job : TaskConcept::_jobs) { + job.applyConfiguration(); + } + } + + void run(const ContextPointer& renderContext) override { + auto config = std::static_pointer_cast(Concept::_config); + if (config->alwaysEnabled || config->enabled) { + for (auto job : TaskConcept::_jobs) { + job.run(renderContext); + } + } + } + }; + template using Model = TaskModel; + template using ModelI = TaskModel; + template using ModelO = TaskModel; + template using ModelIO = TaskModel; + + // Create a new job in the Task's queue; returns the job's output + template const Varying addJob(std::string name, const Varying& input, A&&... args) { + return std::static_pointer_cast(JobType::_concept)->template addJob(name, input, std::forward(args)...); + } + template const Varying addJob(std::string name, A&&... args) { + const auto input = Varying(typename T::JobModel::Input()); + return std::static_pointer_cast(JobType::_concept)->template addJob(name, input, std::forward(args)...); + } + + std::shared_ptr getConfiguration() { + return std::static_pointer_cast(JobType::_concept->getConfiguration()); + } + +protected: +}; +} + + +#define Task_DeclareTypeAliases(ContextType) \ + using JobConfig = task::JobConfig; \ + using TaskConfig = task::TaskConfig; \ + template using PersistentConfig = task::PersistentConfig; \ + using Job = task::Job; \ + using Task = task::Task; \ + using Varying = task::Varying; \ + template < typename T0, typename T1 > using VaryingSet2 = task::VaryingSet2; \ + template < typename T0, typename T1, typename T2 > using VaryingSet3 = task::VaryingSet3; \ + template < typename T0, typename T1, typename T2, typename T3 > using VaryingSet4 = task::VaryingSet4; \ + template < typename T0, typename T1, typename T2, typename T3, typename T4 > using VaryingSet5 = task::VaryingSet5; \ + template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5 > using VaryingSet6 = task::VaryingSet6; \ + template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6 > using VaryingSet7 = task::VaryingSet7; \ + template < class T, int NUM > using VaryingArray = task::VaryingArray; + +#endif // hifi_task_Task_h diff --git a/libraries/render/src/task/Varying.h b/libraries/render/src/task/Varying.h new file mode 100644 index 0000000000..50f4acd414 --- /dev/null +++ b/libraries/render/src/task/Varying.h @@ -0,0 +1,287 @@ +// +// Varying.h +// render/src/task +// +// Created by Zach Pomerantz on 1/6/2016. +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_task_Varying_h +#define hifi_task_Varying_h + +#include +#include + +namespace task { + +// A varying piece of data, to be used as Job/Task I/O +class Varying { +public: + Varying() {} + Varying(const Varying& var) : _concept(var._concept) {} + Varying& operator=(const Varying& var) { + _concept = var._concept; + return (*this); + } + template Varying(const T& data) : _concept(std::make_shared>(data)) {} + + template bool canCast() const { return !!std::dynamic_pointer_cast>(_concept); } + template const T& get() const { return std::static_pointer_cast>(_concept)->_data; } + template T& edit() { return std::static_pointer_cast>(_concept)->_data; } + + + // access potential sub varyings contained in this one. + Varying operator[] (uint8_t index) const { return (*_concept)[index]; } + uint8_t length() const { return (*_concept).length(); } + + template Varying getN (uint8_t index) const { return get()[index]; } + template Varying editN (uint8_t index) { return edit()[index]; } + +protected: + class Concept { + public: + virtual ~Concept() = default; + + virtual Varying operator[] (uint8_t index) const = 0; + virtual uint8_t length() const = 0; + }; + template class Model : public Concept { + public: + using Data = T; + + Model(const Data& data) : _data(data) {} + virtual ~Model() = default; + + virtual Varying operator[] (uint8_t index) const override { + Varying var; + return var; + } + virtual uint8_t length() const override { return 0; } + + Data _data; + }; + + std::shared_ptr _concept; +}; + +using VaryingPairBase = std::pair; +template < typename T0, typename T1 > +class VaryingSet2 : public VaryingPairBase { +public: + using Parent = VaryingPairBase; + typedef void is_proxy_tag; + + VaryingSet2() : Parent(Varying(T0()), Varying(T1())) {} + VaryingSet2(const VaryingSet2& pair) : Parent(pair.first, pair.second) {} + VaryingSet2(const Varying& first, const Varying& second) : Parent(first, second) {} + + const T0& get0() const { return first.get(); } + T0& edit0() { return first.edit(); } + + const T1& get1() const { return second.get(); } + T1& edit1() { return second.edit(); } + + virtual Varying operator[] (uint8_t index) const { + if (index == 1) { + return std::get<1>((*this)); + } else { + return std::get<0>((*this)); + } + } + virtual uint8_t length() const { return 2; } + + Varying hasVarying() const { return Varying((*this)); } +}; + + +template +class VaryingSet3 : public std::tuple{ +public: + using Parent = std::tuple; + + VaryingSet3() : Parent(Varying(T0()), Varying(T1()), Varying(T2())) {} + VaryingSet3(const VaryingSet3& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src)) {} + VaryingSet3(const Varying& first, const Varying& second, const Varying& third) : Parent(first, second, third) {} + + const T0& get0() const { return std::get<0>((*this)).template get(); } + T0& edit0() { return std::get<0>((*this)).template edit(); } + + const T1& get1() const { return std::get<1>((*this)).template get(); } + T1& edit1() { return std::get<1>((*this)).template edit(); } + + const T2& get2() const { return std::get<2>((*this)).template get(); } + T2& edit2() { return std::get<2>((*this)).template edit(); } + + virtual Varying operator[] (uint8_t index) const { + if (index == 2) { + return std::get<2>((*this)); + } else if (index == 1) { + return std::get<1>((*this)); + } else { + return std::get<0>((*this)); + } + } + virtual uint8_t length() const { return 3; } + + Varying hasVarying() const { return Varying((*this)); } +}; + +template +class VaryingSet4 : public std::tuple{ +public: + using Parent = std::tuple; + + VaryingSet4() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3())) {} + VaryingSet4(const VaryingSet4& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src)) {} + VaryingSet4(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth) : Parent(first, second, third, fourth) {} + + const T0& get0() const { return std::get<0>((*this)).template get(); } + T0& edit0() { return std::get<0>((*this)).template edit(); } + + const T1& get1() const { return std::get<1>((*this)).template get(); } + T1& edit1() { return std::get<1>((*this)).template edit(); } + + const T2& get2() const { return std::get<2>((*this)).template get(); } + T2& edit2() { return std::get<2>((*this)).template edit(); } + + const T3& get3() const { return std::get<3>((*this)).template get(); } + T3& edit3() { return std::get<3>((*this)).template edit(); } + + virtual Varying operator[] (uint8_t index) const { + if (index == 3) { + return std::get<3>((*this)); + } else if (index == 2) { + return std::get<2>((*this)); + } else if (index == 1) { + return std::get<1>((*this)); + } else { + return std::get<0>((*this)); + } + } + virtual uint8_t length() const { return 4; } + + Varying hasVarying() const { return Varying((*this)); } +}; + + +template +class VaryingSet5 : public std::tuple{ +public: + using Parent = std::tuple; + + VaryingSet5() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3()), Varying(T4())) {} + VaryingSet5(const VaryingSet5& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src), std::get<4>(src)) {} + VaryingSet5(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth, const Varying& fifth) : Parent(first, second, third, fourth, fifth) {} + + const T0& get0() const { return std::get<0>((*this)).template get(); } + T0& edit0() { return std::get<0>((*this)).template edit(); } + + const T1& get1() const { return std::get<1>((*this)).template get(); } + T1& edit1() { return std::get<1>((*this)).template edit(); } + + const T2& get2() const { return std::get<2>((*this)).template get(); } + T2& edit2() { return std::get<2>((*this)).template edit(); } + + const T3& get3() const { return std::get<3>((*this)).template get(); } + T3& edit3() { return std::get<3>((*this)).template edit(); } + + const T4& get4() const { return std::get<4>((*this)).template get(); } + T4& edit4() { return std::get<4>((*this)).template edit(); } + + virtual Varying operator[] (uint8_t index) const { + if (index == 4) { + return std::get<4>((*this)); + } else if (index == 3) { + return std::get<3>((*this)); + } else if (index == 2) { + return std::get<2>((*this)); + } else if (index == 1) { + return std::get<1>((*this)); + } else { + return std::get<0>((*this)); + } + } + virtual uint8_t length() const { return 5; } + + Varying hasVarying() const { return Varying((*this)); } +}; + +template +class VaryingSet6 : public std::tuple{ +public: + using Parent = std::tuple; + + VaryingSet6() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3()), Varying(T4()), Varying(T5())) {} + VaryingSet6(const VaryingSet6& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src), std::get<4>(src), std::get<5>(src)) {} + VaryingSet6(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth, const Varying& fifth, const Varying& sixth) : Parent(first, second, third, fourth, fifth, sixth) {} + + const T0& get0() const { return std::get<0>((*this)).template get(); } + T0& edit0() { return std::get<0>((*this)).template edit(); } + + const T1& get1() const { return std::get<1>((*this)).template get(); } + T1& edit1() { return std::get<1>((*this)).template edit(); } + + const T2& get2() const { return std::get<2>((*this)).template get(); } + T2& edit2() { return std::get<2>((*this)).template edit(); } + + const T3& get3() const { return std::get<3>((*this)).template get(); } + T3& edit3() { return std::get<3>((*this)).template edit(); } + + const T4& get4() const { return std::get<4>((*this)).template get(); } + T4& edit4() { return std::get<4>((*this)).template edit(); } + + const T5& get5() const { return std::get<5>((*this)).template get(); } + T5& edit5() { return std::get<5>((*this)).template edit(); } + + Varying hasVarying() const { return Varying((*this)); } +}; + +template +class VaryingSet7 : public std::tuple{ +public: + using Parent = std::tuple; + + VaryingSet7() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3()), Varying(T4()), Varying(T5()), Varying(T6())) {} + VaryingSet7(const VaryingSet7& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src), std::get<4>(src), std::get<5>(src), std::get<6>(src)) {} + VaryingSet7(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth, const Varying& fifth, const Varying& sixth, const Varying& seventh) : Parent(first, second, third, fourth, fifth, sixth, seventh) {} + + const T0& get0() const { return std::get<0>((*this)).template get(); } + T0& edit0() { return std::get<0>((*this)).template edit(); } + + const T1& get1() const { return std::get<1>((*this)).template get(); } + T1& edit1() { return std::get<1>((*this)).template edit(); } + + const T2& get2() const { return std::get<2>((*this)).template get(); } + T2& edit2() { return std::get<2>((*this)).template edit(); } + + const T3& get3() const { return std::get<3>((*this)).template get(); } + T3& edit3() { return std::get<3>((*this)).template edit(); } + + const T4& get4() const { return std::get<4>((*this)).template get(); } + T4& edit4() { return std::get<4>((*this)).template edit(); } + + const T5& get5() const { return std::get<5>((*this)).template get(); } + T5& edit5() { return std::get<5>((*this)).template edit(); } + + const T6& get6() const { return std::get<6>((*this)).template get(); } + T6& edit6() { return std::get<6>((*this)).template edit(); } + + Varying hasVarying() const { return Varying((*this)); } +}; + + +template < class T, int NUM > +class VaryingArray : public std::array { +public: + VaryingArray() { + for (size_t i = 0; i < NUM; i++) { + (*this)[i] = Varying(T()); + } + } +}; +} + +#endif // hifi_task_Varying_h diff --git a/scripts/developer/utilities/record/recorder.js b/script-archive/recorder.js similarity index 100% rename from scripts/developer/utilities/record/recorder.js rename to script-archive/recorder.js diff --git a/scripts/system/html/css/SnapshotReview.css b/scripts/system/html/css/SnapshotReview.css index 12b91d372b..ccc9386d13 100644 --- a/scripts/system/html/css/SnapshotReview.css +++ b/scripts/system/html/css/SnapshotReview.css @@ -80,6 +80,9 @@ input[type=button].naked:active { #snapshot-images { width: 100%; + display: flex; + justify-content: center; + flex-direction: column; } #snapshot-images img { @@ -108,7 +111,7 @@ input[type=button].naked:active { justify-content: space-between; flex-direction: row; align-items: center; - height: 50px; + height: 45px; line-height: 60px; width: calc(100% - 8px); position: absolute; @@ -119,13 +122,13 @@ input[type=button].naked:active { .shareButtons { display: flex; align-items: center; - margin-left: 30px; + margin-left: 15px; height: 100%; - width: 80%; + width: 75%; } .blastToConnections { text-align: left; - margin-right: 25px; + margin-right: 20px; height: 29px; } .shareWithEveryone { @@ -158,10 +161,11 @@ input[type=button].naked:active { font-family: Raleway-SemiBold; font-size: 14px; color: white; - text-shadow: 2px 2px 3px #000000; height: 100%; margin-right: 10px; - width: 20%; +} +.showShareButtonsButtonDiv > label { + text-shadow: 2px 2px 3px #000000; } .showShareButton { width: 40px; @@ -193,23 +197,17 @@ input[type=button].naked:active { background-color: white; } .showShareButtonDots { - display: flex; - width: 32px; + display: block; + width: 40px; height: 40px; + font-family: HiFi-Glyphs; + font-size: 60px; position: absolute; - top: 5px; - right: 14px; + right: 20px; + bottom: 12px; + color: #00b4ef; pointer-events: none; } -.showShareButtonDots > span { - width: 10px; - height: 10px; - margin: auto; - background-color: #0093C5; - border-radius: 50%; - border-width: 0; - display: inline; -} /* // END styling of share overlay */ diff --git a/scripts/system/html/css/hifi-style.css b/scripts/system/html/css/hifi-style.css index f1ace02eb0..ac34cee09f 100644 --- a/scripts/system/html/css/hifi-style.css +++ b/scripts/system/html/css/hifi-style.css @@ -101,9 +101,11 @@ input[type=radio] { opacity: 0; } input[type=radio] + label{ - display: inline-block; - margin-left: -2em; - line-height: 2em; + display: inline-block; + margin-left: -2em; + line-height: 2em; + font-family: Raleway-SemiBold; + font-size: 14px; } input[type=radio] + label > span{ display: inline-block; @@ -157,7 +159,6 @@ input[type=radio]:active + label > span > span{ border-width: 0px; background-image: linear-gradient(#00B4EF, #1080B8); min-height: 30px; - } .blueButton:hover { background-image: linear-gradient(#00B4EF, #00B4EF); diff --git a/scripts/system/html/js/SnapshotReview.js b/scripts/system/html/js/SnapshotReview.js index 53f4d17930..ed290e9756 100644 --- a/scripts/system/html/js/SnapshotReview.js +++ b/scripts/system/html/js/SnapshotReview.js @@ -52,7 +52,7 @@ function clearImages() { imageCount = 0; idCounter = 0; } -function addImage(image_data, isGifLoading, isShowingPreviousImages, canSharePreviousImages, hifiShareButtonsDisabled) { +function addImage(image_data, isGifLoading, canShare, isShowingPreviousImages, blastButtonDisabled, hifiButtonDisabled) { if (!image_data.localPath) { return; } @@ -60,8 +60,9 @@ function addImage(image_data, isGifLoading, isShowingPreviousImages, canSharePre // imageContainer setup var imageContainer = document.createElement("DIV"); imageContainer.id = id; - imageContainer.style.width = "100%"; - imageContainer.style.height = "251px"; + imageContainer.style.width = "95%"; + imageContainer.style.height = "240px"; + imageContainer.style.margin = "5px auto"; imageContainer.style.display = "flex"; imageContainer.style.justifyContent = "center"; imageContainer.style.alignItems = "center"; @@ -80,22 +81,22 @@ function addImage(image_data, isGifLoading, isShowingPreviousImages, canSharePre if (isGif) { imageContainer.innerHTML += 'GIF'; } - if (!isGifLoading && !isShowingPreviousImages) { + if (!isGifLoading && !isShowingPreviousImages && canShare) { shareForUrl(id); - } else if (isShowingPreviousImages && canSharePreviousImages) { - appendShareBar(id, image_data.story_id, isGif, hifiShareButtonsDisabled) + } else if (isShowingPreviousImages && canShare && image_data.story_id) { + appendShareBar(id, image_data.story_id, isGif, blastButtonDisabled, hifiButtonDisabled) } } -function appendShareBar(divID, story_id, isGif, hifiShareButtonsDisabled) { +function appendShareBar(divID, story_id, isGif, blastButtonDisabled, hifiButtonDisabled) { var story_url = "https://highfidelity.com/user_stories/" + story_id; var parentDiv = document.getElementById(divID); parentDiv.setAttribute('data-story-id', story_id); - document.getElementById(divID).appendChild(createShareBar(divID, isGif, story_url, hifiShareButtonsDisabled)); + document.getElementById(divID).appendChild(createShareBar(divID, isGif, story_url, blastButtonDisabled, hifiButtonDisabled)); if (divID === "p0") { selectImageToShare(divID, true); } } -function createShareBar(parentID, isGif, shareURL, hifiShareButtonsDisabled) { +function createShareBar(parentID, isGif, shareURL, blastButtonDisabled, hifiButtonDisabled) { var shareBar = document.createElement("div"); shareBar.id = parentID + "shareBar"; shareBar.className = "shareControls"; @@ -109,8 +110,8 @@ function createShareBar(parentID, isGif, shareURL, hifiShareButtonsDisabled) { var twitterButtonID = parentID + "twitterButton"; shareBar.innerHTML += '' + '' + @@ -118,7 +119,7 @@ function createShareBar(parentID, isGif, shareURL, hifiShareButtonsDisabled) { '' + '' + '
' + - '' + + '' + '
' + ''; @@ -149,6 +150,15 @@ function selectImageToShare(selectedID, isSelected) { shareBar.style.backgroundColor = "rgba(0, 0, 0, 0.5)"; shareButtonsDiv.style.visibility = "visible"; + + var containers = document.getElementsByClassName("shareControls"); + var parentID; + for (var i = 0; i < containers.length; ++i) { + parentID = containers[i].id.slice(0, 2); + if (parentID !== selectedID) { + selectImageToShare(parentID, false); + } + } } else { showShareButtonsButton.onclick = function () { selectImageToShare(selectedID, true) }; showShareButtonsButton.classList.remove("active"); @@ -173,7 +183,6 @@ function blastToConnections(selectedID, isGif) { selectedID = selectedID.id; // `selectedID` is passed as an HTML object to these functions; we just want the ID document.getElementById(selectedID + "blastToConnectionsButton").disabled = true; - document.getElementById(selectedID + "shareWithEveryoneButton").disabled = true; EventBridge.emitWebEvent(JSON.stringify({ type: "snapshot", @@ -185,7 +194,6 @@ function blastToConnections(selectedID, isGif) { function shareWithEveryone(selectedID, isGif) { selectedID = selectedID.id; // `selectedID` is passed as an HTML object to these functions; we just want the ID - document.getElementById(selectedID + "blastToConnectionsButton").disabled = true; document.getElementById(selectedID + "shareWithEveryoneButton").disabled = true; EventBridge.emitWebEvent(JSON.stringify({ @@ -233,7 +241,7 @@ function handleCaptureSetting(setting) { window.onload = function () { // Uncomment the line below to test functionality in a browser. // See definition of "testInBrowser()" to modify tests. - //testInBrowser(true); + //testInBrowser(false); openEventBridge(function () { // Set up a handler for receiving the data, and tell the .js we are ready to receive it. EventBridge.scriptEventReceived.connect(function (message) { @@ -260,7 +268,7 @@ window.onload = function () { var messageOptions = message.options; imageCount = message.image_data.length; message.image_data.forEach(function (element, idx, array) { - addImage(element, true, true, message.canShare, message.image_data[idx].buttonDisabled); + addImage(element, true, message.canShare, true, message.image_data[idx].blastButtonDisabled, message.image_data[idx].hifiButtonDisabled); }); break; case 'addImages': @@ -272,22 +280,24 @@ window.onload = function () { if (messageOptions.containsGif) { if (messageOptions.processingGif) { imageCount = message.image_data.length + 1; // "+1" for the GIF that'll finish processing soon - message.image_data.unshift({ localPath: messageOptions.loadingGifPath }); + message.image_data.push({ localPath: messageOptions.loadingGifPath }); message.image_data.forEach(function (element, idx, array) { - addImage(element, idx === 0, false, false); + addImage(element, idx === 1, idx === 0 && messageOptions.canShare, false); }); } else { var gifPath = message.image_data[0].localPath; - var p0img = document.getElementById('p0img'); - p0img.src = gifPath; + var p1img = document.getElementById('p1img'); + p1img.src = gifPath; - paths[0] = gifPath; - shareForUrl("p0"); + paths[1] = gifPath; + if (messageOptions.canShare) { + shareForUrl("p1"); + } } } else { imageCount = message.image_data.length; message.image_data.forEach(function (element, idx, array) { - addImage(element, false, false, false); + addImage(element, false, messageOptions.canShare, false); }); } break; @@ -296,7 +306,7 @@ window.onload = function () { break; case 'snapshotUploadComplete': var isGif = message.image_url.split('.').pop().toLowerCase() === "gif"; - appendShareBar(isGif || imageCount === 1 ? "p0" : "p1", message.story_id, isGif); + appendShareBar(isGif ? "p1" : "p0", message.story_id, isGif); break; default: console.log("Unknown message action received in SnapshotReview.js."); @@ -329,6 +339,7 @@ function testInBrowser(isTestingSetupInstructions) { } else { imageCount = 1; //addImage({ localPath: 'http://lorempixel.com/553/255' }); - addImage({ localPath: 'C:/Users/valef/Desktop/hifi-snap-by-zfox-on-2017-04-26_10-26-53.gif' }, false, true, true, false); + addImage({ localPath: 'C:/Users/valef/Desktop/hifi-snap-by-zfox-on-2017-05-01_15-48-15.gif' }, false, true, true, false, false); + addImage({ localPath: 'C:/Users/valef/Desktop/hifi-snap-by-zfox-on-2017-05-01_15-48-15.jpg' }, false, true, true, false, false); } } diff --git a/scripts/system/makeUserConnection.js b/scripts/system/makeUserConnection.js index 47082e882f..33d6b363ab 100644 --- a/scripts/system/makeUserConnection.js +++ b/scripts/system/makeUserConnection.js @@ -519,11 +519,9 @@ function updateTriggers(value, fromKeyboard, hand) { if (currentHand && hand !== currentHand) { - debug("currentHand", currentHand, "ignoring messages from", hand); + debug("currentHand", currentHand, "ignoring messages from", hand); // this can be a lot of spam on Touch. Should guard that someday. return; } - currentHand = hand; - currentHandJointIndex = getIdealHandJointIndex(MyAvatar, handToString(currentHand)); // Always, in case of changed skeleton. // ok now, we are either initiating or quitting... var isGripping = value > GRIP_MIN; if (isGripping) { @@ -531,6 +529,8 @@ if (state !== STATES.INACTIVE) { return; } + currentHand = hand; + currentHandJointIndex = getIdealHandJointIndex(MyAvatar, handToString(currentHand)); // Always, in case of changed skeleton. startHandshake(fromKeyboard); } else { // TODO: should we end handshake even when inactive? Ponder diff --git a/scripts/system/snapshot.js b/scripts/system/snapshot.js index 1cc24b8265..d0d1bd96f5 100644 --- a/scripts/system/snapshot.js +++ b/scripts/system/snapshot.js @@ -117,13 +117,15 @@ function onMessage(message) { setting: Settings.getValue("alsoTakeAnimatedSnapshot", true) })); if (Snapshot.getSnapshotsLocation() !== "") { - tablet.emitScriptEvent(JSON.stringify({ - type: "snapshot", - action: "showPreviousImages", - options: snapshotOptions, - image_data: imageData, - canShare: !isDomainOpen(Settings.getValue("previousSnapshotDomainID")) - })); + isDomainOpen(Settings.getValue("previousSnapshotDomainID"), function (canShare) { + tablet.emitScriptEvent(JSON.stringify({ + type: "snapshot", + action: "showPreviousImages", + options: snapshotOptions, + image_data: imageData, + canShare: canShare + })); + }); } else { tablet.emitScriptEvent(JSON.stringify({ type: "snapshot", @@ -131,10 +133,12 @@ function onMessage(message) { })); Settings.setValue("previousStillSnapPath", ""); Settings.setValue("previousStillSnapStoryID", ""); - Settings.setValue("previousStillSnapSharingDisabled", false); + Settings.setValue("previousStillSnapBlastingDisabled", false); + Settings.setValue("previousStillSnapHifiSharingDisabled", false); Settings.setValue("previousAnimatedSnapPath", ""); Settings.setValue("previousAnimatedSnapStoryID", ""); - Settings.setValue("previousAnimatedSnapSharingDisabled", false); + Settings.setValue("previousAnimatedSnapBlastingDisabled", false); + Settings.setValue("previousAnimatedSnapHifiSharingDisabled", false); } break; case 'chooseSnapshotLocation': @@ -180,9 +184,9 @@ function onMessage(message) { isLoggedIn = Account.isLoggedIn(); storyIDsToMaybeDelete.splice(storyIDsToMaybeDelete.indexOf(message.story_id), 1); if (message.isGif) { - Settings.setValue("previousAnimatedSnapSharingDisabled", true); + Settings.setValue("previousAnimatedSnapBlastingDisabled", true); } else { - Settings.setValue("previousStillSnapSharingDisabled", true); + Settings.setValue("previousStillSnapBlastingDisabled", true); } if (isLoggedIn) { @@ -220,9 +224,9 @@ function onMessage(message) { if (error || (response.status !== 'success')) { print("ERROR uploading announcement story: ", error || response.status); if (message.isGif) { - Settings.setValue("previousAnimatedSnapSharingDisabled", false); + Settings.setValue("previousAnimatedSnapBlastingDisabled", false); } else { - Settings.setValue("previousStillSnapSharingDisabled", false); + Settings.setValue("previousStillSnapBlastingDisabled", false); } return; } else { @@ -240,9 +244,9 @@ function onMessage(message) { isLoggedIn = Account.isLoggedIn(); storyIDsToMaybeDelete.splice(storyIDsToMaybeDelete.indexOf(message.story_id), 1); if (message.isGif) { - Settings.setValue("previousAnimatedSnapSharingDisabled", true); + Settings.setValue("previousAnimatedSnapHifiSharingDisabled", true); } else { - Settings.setValue("previousStillSnapSharingDisabled", true); + Settings.setValue("previousStillSnapHifiSharingDisabled", true); } if (isLoggedIn) { @@ -264,9 +268,9 @@ function onMessage(message) { if (error || (response.status !== 'success')) { print("ERROR changing audience: ", error || response.status); if (message.isGif) { - Settings.setValue("previousAnimatedSnapSharingDisabled", false); + Settings.setValue("previousAnimatedSnapHifiSharingDisabled", false); } else { - Settings.setValue("previousStillSnapSharingDisabled", false); + Settings.setValue("previousStillSnapHifiSharingDisabled", false); } return; } else { @@ -301,21 +305,33 @@ function onButtonClicked() { shouldActivateButton = true; var previousStillSnapPath = Settings.getValue("previousStillSnapPath"); var previousStillSnapStoryID = Settings.getValue("previousStillSnapStoryID"); - var previousStillSnapSharingDisabled = Settings.getValue("previousStillSnapSharingDisabled"); + var previousStillSnapBlastingDisabled = Settings.getValue("previousStillSnapBlastingDisabled"); + var previousStillSnapHifiSharingDisabled = Settings.getValue("previousStillSnapHifiSharingDisabled"); var previousAnimatedSnapPath = Settings.getValue("previousAnimatedSnapPath"); var previousAnimatedSnapStoryID = Settings.getValue("previousAnimatedSnapStoryID"); - var previousAnimatedSnapSharingDisabled = Settings.getValue("previousAnimatedSnapSharingDisabled"); + var previousAnimatedSnapBlastingDisabled = Settings.getValue("previousAnimatedSnapBlastingDisabled"); + var previousAnimatedSnapHifiSharingDisabled = Settings.getValue("previousAnimatedSnapHifiSharingDisabled"); snapshotOptions = { containsGif: previousAnimatedSnapPath !== "", processingGif: false, shouldUpload: false } imageData = []; - if (previousAnimatedSnapPath !== "") { - imageData.push({ localPath: previousAnimatedSnapPath, story_id: previousAnimatedSnapStoryID, buttonDisabled: previousAnimatedSnapSharingDisabled }); - } if (previousStillSnapPath !== "") { - imageData.push({ localPath: previousStillSnapPath, story_id: previousStillSnapStoryID, buttonDisabled: previousStillSnapSharingDisabled }); + imageData.push({ + localPath: previousStillSnapPath, + story_id: previousStillSnapStoryID, + blastButtonDisabled: previousStillSnapBlastingDisabled, + hifiButtonDisabled: previousStillSnapHifiSharingDisabled + }); + } + if (previousAnimatedSnapPath !== "") { + imageData.push({ + localPath: previousAnimatedSnapPath, + story_id: previousAnimatedSnapStoryID, + blastButtonDisabled: previousAnimatedSnapBlastingDisabled, + hifiButtonDisabled: previousAnimatedSnapHifiSharingDisabled + }); } tablet.gotoWebScreen(SNAPSHOT_REVIEW_URL); tablet.webEventReceived.connect(onMessage); @@ -355,10 +371,12 @@ function takeSnapshot() { })); Settings.setValue("previousStillSnapPath", ""); Settings.setValue("previousStillSnapStoryID", ""); - Settings.setValue("previousStillSnapSharingDisabled", false); + Settings.setValue("previousStillSnapBlastingDisabled", false); + Settings.setValue("previousStillSnapHifiSharingDisabled", false); Settings.setValue("previousAnimatedSnapPath", ""); Settings.setValue("previousAnimatedSnapStoryID", ""); - Settings.setValue("previousAnimatedSnapSharingDisabled", false); + Settings.setValue("previousAnimatedSnapBlastingDisabled", false); + Settings.setValue("previousAnimatedSnapHifiSharingDisabled", false); // Raising the desktop for the share dialog at end will interact badly with clearOverlayWhenMoving. // Turn it off now, before we start futzing with things (and possibly moving). @@ -377,6 +395,7 @@ function takeSnapshot() { resetOverlays = Menu.isOptionChecked("Overlays"); // For completeness. Certainly true if the button is visible to be clicked. reticleVisible = Reticle.visible; Reticle.visible = false; + Reticle.allowMouseCapture = false; var includeAnimated = Settings.getValue("alsoTakeAnimatedSnapshot", true); if (includeAnimated) { @@ -403,37 +422,40 @@ function takeSnapshot() { }, FINISH_SOUND_DELAY); } -function isDomainOpen(id) { +function isDomainOpen(id, callback) { print("Checking open status of domain with ID:", id); - if (!id) { - return false; + var status = false; + if (id) { + var options = [ + 'now=' + new Date().toISOString(), + 'include_actions=concurrency', + 'domain_id=' + id.slice(1, -1), + 'restriction=open,hifi' // If we're sharing, we're logged in + // If we're here, protocol matches, and it is online + ]; + var url = METAVERSE_BASE + "/api/v1/user_stories?" + options.join('&'); + + request({ + uri: url, + method: 'GET' + }, function (error, response) { + if (error || (response.status !== 'success')) { + print("ERROR getting open status of domain: ", error || response.status); + } else { + status = response.total_entries ? true : false; + } + print("Domain open status:", status); + callback(status); + }); + } else { + callback(status); } - - var options = [ - 'now=' + new Date().toISOString(), - 'include_actions=concurrency', - 'domain_id=' + id.slice(1, -1), - 'restriction=open,hifi' // If we're sharing, we're logged in - // If we're here, protocol matches, and it is online - ]; - var url = METAVERSE_BASE + "/api/v1/user_stories?" + options.join('&'); - - return request({ - uri: url, - method: 'GET' - }, function (error, response) { - if (error || (response.status !== 'success')) { - print("ERROR getting open status of domain: ", error || response.status); - return false; - } else { - return response.total_entries; - } - }); } function stillSnapshotTaken(pathStillSnapshot, notify) { // show hud Reticle.visible = reticleVisible; + Reticle.allowMouseCapture = true; // show overlays if they were on if (resetOverlays) { Menu.setIsOptionChecked("Overlays", true); @@ -448,25 +470,27 @@ function stillSnapshotTaken(pathStillSnapshot, notify) { // during which time the user may have moved. So stash that info in the dialog so that // it records the correct href. (We can also stash in .jpegs, but not .gifs.) // last element in data array tells dialog whether we can share or not - snapshotOptions = { - containsGif: false, - processingGif: false, - canShare: !isDomainOpen(domainId) - }; - imageData = [{ localPath: pathStillSnapshot, href: href }]; Settings.setValue("previousStillSnapPath", pathStillSnapshot); - tablet.emitScriptEvent(JSON.stringify({ - type: "snapshot", - action: "addImages", - options: snapshotOptions, - image_data: imageData - })); - if (clearOverlayWhenMoving) { MyAvatar.setClearOverlayWhenMoving(true); // not until after the share dialog } HMD.openTablet(); + + isDomainOpen(domainId, function (canShare) { + snapshotOptions = { + containsGif: false, + processingGif: false, + canShare: canShare + }; + imageData = [{ localPath: pathStillSnapshot, href: href }]; + tablet.emitScriptEvent(JSON.stringify({ + type: "snapshot", + action: "addImages", + options: snapshotOptions, + image_data: imageData + })); + }); } function processingGifStarted(pathStillSnapshot) { @@ -474,31 +498,33 @@ function processingGifStarted(pathStillSnapshot) { Window.processingGifCompleted.connect(processingGifCompleted); // show hud Reticle.visible = reticleVisible; + Reticle.allowMouseCapture = true; // show overlays if they were on if (resetOverlays) { Menu.setIsOptionChecked("Overlays", true); } - - snapshotOptions = { - containsGif: true, - processingGif: true, - loadingGifPath: Script.resolvePath(Script.resourcesPath() + 'icons/loadingDark.gif'), - canShare: !isDomainOpen(domainId) - }; - imageData = [{ localPath: pathStillSnapshot, href: href }]; Settings.setValue("previousStillSnapPath", pathStillSnapshot); - tablet.emitScriptEvent(JSON.stringify({ - type: "snapshot", - action: "addImages", - options: snapshotOptions, - image_data: imageData - })); - if (clearOverlayWhenMoving) { MyAvatar.setClearOverlayWhenMoving(true); // not until after the share dialog } HMD.openTablet(); + + isDomainOpen(domainId, function (canShare) { + snapshotOptions = { + containsGif: true, + processingGif: true, + loadingGifPath: Script.resolvePath(Script.resourcesPath() + 'icons/loadingDark.gif'), + canShare: canShare + }; + imageData = [{ localPath: pathStillSnapshot, href: href }]; + tablet.emitScriptEvent(JSON.stringify({ + type: "snapshot", + action: "addImages", + options: snapshotOptions, + image_data: imageData + })); + }); } function processingGifCompleted(pathAnimatedSnapshot) { @@ -508,20 +534,22 @@ function processingGifCompleted(pathAnimatedSnapshot) { buttonConnected = true; } - snapshotOptions = { - containsGif: true, - processingGif: false, - canShare: !isDomainOpen(domainId) - } - imageData = [{ localPath: pathAnimatedSnapshot, href: href }]; Settings.setValue("previousAnimatedSnapPath", pathAnimatedSnapshot); - tablet.emitScriptEvent(JSON.stringify({ - type: "snapshot", - action: "addImages", - options: snapshotOptions, - image_data: imageData - })); + isDomainOpen(domainId, function (canShare) { + snapshotOptions = { + containsGif: true, + processingGif: false, + canShare: canShare + }; + imageData = [{ localPath: pathAnimatedSnapshot, href: href }]; + tablet.emitScriptEvent(JSON.stringify({ + type: "snapshot", + action: "addImages", + options: snapshotOptions, + image_data: imageData + })); + }); } function maybeDeleteSnapshotStories() { storyIDsToMaybeDelete.forEach(function (element, idx, array) { @@ -554,12 +582,21 @@ function onUsernameChanged() { shareAfterLogin = false; } } +function snapshotLocationSet(location) { + if (location !== "") { + tablet.emitScriptEvent(JSON.stringify({ + type: "snapshot", + action: "snapshotLocationChosen" + })); + } +} button.clicked.connect(onButtonClicked); buttonConnected = true; Window.snapshotShared.connect(snapshotUploaded); tablet.screenChanged.connect(onTabletScreenChanged); Account.usernameChanged.connect(onUsernameChanged); +Snapshot.snapshotLocationSet.connect(snapshotLocationSet); Script.scriptEnding.connect(function () { if (buttonConnected) { button.clicked.disconnect(onButtonClicked); @@ -570,6 +607,7 @@ Script.scriptEnding.connect(function () { } Window.snapshotShared.disconnect(snapshotUploaded); tablet.screenChanged.disconnect(onTabletScreenChanged); + Snapshot.snapshotLocationSet.disconnect(snapshotLocationSet); }); }()); // END LOCAL_SCOPE diff --git a/tests/gpu-test/src/TestWindow.h b/tests/gpu-test/src/TestWindow.h index fd059f3e32..bceb29305e 100644 --- a/tests/gpu-test/src/TestWindow.h +++ b/tests/gpu-test/src/TestWindow.h @@ -17,7 +17,7 @@ #include #include -#include +#include #define DEFERRED_LIGHTING