From d6444028f99cdcd7021b5dd3849047312b296ff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Sun, 13 Dec 2015 19:56:00 +0100 Subject: [PATCH] Added some convenience to set and watch scenery nodes --- src/definition/DefinitionWatcher.cpp | 20 +++++++++++++++ src/definition/DefinitionWatcher.h | 12 ++++++++- src/definition/FloatNode.cpp | 4 +-- src/definition/IntNode.cpp | 4 +-- src/definition/NoiseNode.cpp | 2 +- src/definition/Scenery.cpp | 38 ++++++++++++++++++++++++++++ src/definition/Scenery.h | 12 +++++++++ src/render/opengl/OpenGLSkybox.cpp | 19 ++++++++++---- src/render/opengl/OpenGLSkybox.h | 1 + src/render/opengl/OpenGLTerrain.cpp | 1 + src/render/opengl/OpenGLVariable.h | 7 +++++ src/tests/BaseTestCase.h | 5 ++++ src/tests/OpenGLSkybox_Test.cpp | 27 ++++++++++++++++++++ 13 files changed, 141 insertions(+), 11 deletions(-) create mode 100644 src/tests/OpenGLSkybox_Test.cpp diff --git a/src/definition/DefinitionWatcher.cpp b/src/definition/DefinitionWatcher.cpp index 6c46820..628397f 100644 --- a/src/definition/DefinitionWatcher.cpp +++ b/src/definition/DefinitionWatcher.cpp @@ -1,11 +1,31 @@ #include "DefinitionWatcher.h" +#include "IntDiff.h" +#include "FloatDiff.h" #include "DefinitionNode.h" #include "Logs.h" DefinitionWatcher::DefinitionWatcher() { } +void DefinitionWatcher::nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) { + string type_name = node->getTypeName(); + + if (type_name == "int") { + IntDiff *int_diff = (IntDiff *)diff; + intNodeChanged(node->getPath(), int_diff->getNewValue(), int_diff->getOldValue()); + } else if (type_name == "float") { + FloatDiff *float_diff = (FloatDiff *)diff; + floatNodeChanged(node->getPath(), float_diff->getNewValue(), float_diff->getOldValue()); + } +} + +void DefinitionWatcher::intNodeChanged(const string &, int, int) { +} + +void DefinitionWatcher::floatNodeChanged(const string &, double, double) { +} + void DefinitionWatcher::startWatching(const DefinitionNode *root, const string &path, bool init_diff) { DefinitionNode *node = root->findByPath(path); if (node) { diff --git a/src/definition/DefinitionWatcher.h b/src/definition/DefinitionWatcher.h index 19db71f..e634ae4 100644 --- a/src/definition/DefinitionWatcher.h +++ b/src/definition/DefinitionWatcher.h @@ -18,7 +18,17 @@ class DEFINITIONSHARED_EXPORT DefinitionWatcher { /** * Abstract method called when a node changed. */ - virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) = 0; + virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff); + + /** + * Abstract convenience to receive integer node changes. + */ + virtual void intNodeChanged(const string &path, int new_value, int old_value); + + /** + * Abstract convenience to receive float node changes. + */ + virtual void floatNodeChanged(const string &path, double new_value, double old_value); protected: /** diff --git a/src/definition/FloatNode.cpp b/src/definition/FloatNode.cpp index eda3dbb..b7a1d72 100644 --- a/src/definition/FloatNode.cpp +++ b/src/definition/FloatNode.cpp @@ -30,7 +30,7 @@ void FloatNode::copy(DefinitionNode *destination) const { if (destination->getTypeName() == getTypeName()) { ((FloatNode *)destination)->value = value; } else { - Logs::error() << "Can't copy from " << getTypeName() << " to " << destination->getTypeName() << endl; + Logs::error() << "[Definition] Can't copy from " << getTypeName() << " to " << destination->getTypeName() << endl; } } @@ -61,7 +61,7 @@ bool FloatNode::applyDiff(const DefinitionDiff *diff, bool backward) { value = next; return true; } else { - Logs::error() << "Can't apply float diff " << previous << " => " << next << " to " << getName() << endl; + Logs::error() << "[Definition] Can't apply float diff " << previous << " => " << next << " to " << getName() << endl; return false; } } diff --git a/src/definition/IntNode.cpp b/src/definition/IntNode.cpp index b54023c..dfd2771 100644 --- a/src/definition/IntNode.cpp +++ b/src/definition/IntNode.cpp @@ -30,7 +30,7 @@ void IntNode::copy(DefinitionNode *destination) const { if (destination->getTypeName() == getTypeName()) { ((IntNode *)destination)->value = value; } else { - Logs::error() << "Can't copy from " << getTypeName() << " to " << destination->getTypeName() << endl; + Logs::error() << "[Definition] Can't copy from " << getTypeName() << " to " << destination->getTypeName() << endl; } } @@ -61,7 +61,7 @@ bool IntNode::applyDiff(const DefinitionDiff *diff, bool backward) { value = next; return true; } else { - Logs::error() << "Can't apply int diff " << previous << " => " << next << " to " << getName() << endl; + Logs::error() << "[Definition] Can't apply int diff " << previous << " => " << next << " to " << getName() << endl; return false; } } diff --git a/src/definition/NoiseNode.cpp b/src/definition/NoiseNode.cpp index 9d9543a..78c9506 100644 --- a/src/definition/NoiseNode.cpp +++ b/src/definition/NoiseNode.cpp @@ -31,7 +31,7 @@ void NoiseNode::copy(DefinitionNode *destination) const { if (destination->getTypeName() == getTypeName()) { noise->copy(((NoiseNode *)destination)->noise); } else { - Logs::error() << "Can't copy from " << getTypeName() << " to " << destination->getTypeName() << endl; + Logs::error() << "[Definition] Can't copy from " << getTypeName() << " to " << destination->getTypeName() << endl; } } diff --git a/src/definition/Scenery.cpp b/src/definition/Scenery.cpp index 658ebee..e639b45 100644 --- a/src/definition/Scenery.cpp +++ b/src/definition/Scenery.cpp @@ -10,8 +10,11 @@ #include "TexturesDefinition.h" #include "VegetationDefinition.h" #include "WaterDefinition.h" +#include "DiffManager.h" #include "Logs.h" #include "RandomGenerator.h" +#include "IntNode.h" +#include "FloatNode.h" static const double APP_HEADER = 19866544632.125; static const int DATA_VERSION = 1; @@ -91,6 +94,41 @@ Scenery::FileOperationResult Scenery::loadGlobal(const string &filepath) { return FILE_OPERATION_OK; } +void Scenery::undo() { + DiffManager *diffs = getDiffManager(); + if (diffs) { + diffs->undo(); + } +} + +void Scenery::redo() { + DiffManager *diffs = getDiffManager(); + if (diffs) { + diffs->redo(); + } +} + +#define NODE_SETTER(_path_, _nodetype_, _nodeclass_, _value_) \ + DefinitionNode *node = findByPath(_path_); \ + if (node) { \ + if (node->getTypeName() == _nodetype_) { \ + _nodeclass_ *tnode = (_nodeclass_ *)node; \ + tnode->setValue(_value_); \ + } else { \ + Logs::warning() << "[Definition] Node " << path << " of wrong type for value " << value << endl; \ + } \ + } else { \ + Logs::warning() << "[Definition] Can't find node " << path << " to set to " << value << endl; \ + } + +void Scenery::set(const string &path, const int &value) { + NODE_SETTER(path, "int", IntNode, value) +} + +void Scenery::set(const string &path, const double &value) { + NODE_SETTER(path, "float", FloatNode, value) +} + const Scenery *Scenery::getScenery() const { return this; } diff --git a/src/definition/Scenery.h b/src/definition/Scenery.h index 46a25f6..3a34281 100644 --- a/src/definition/Scenery.h +++ b/src/definition/Scenery.h @@ -32,6 +32,18 @@ class DEFINITIONSHARED_EXPORT Scenery : public DefinitionNode { FileOperationResult saveGlobal(const string &filepath) const; FileOperationResult loadGlobal(const string &filepath); + /** + * Undo the last scenery change. + */ + void undo(); + /** + * Redo the last scenery change. + */ + void redo(); + + void set(const string &path, const int &value); + void set(const string &path, const double &value); + virtual const Scenery *getScenery() const override; void autoPreset(RandomGenerator &random = RandomGeneratorDefault); diff --git a/src/render/opengl/OpenGLSkybox.cpp b/src/render/opengl/OpenGLSkybox.cpp index 8b44365..d0e4a47 100644 --- a/src/render/opengl/OpenGLSkybox.cpp +++ b/src/render/opengl/OpenGLSkybox.cpp @@ -74,7 +74,7 @@ void OpenGLSkybox::render() { program->draw(vertices); } -void OpenGLSkybox::nodeChanged(const DefinitionNode *node, const DefinitionDiff *) { +void OpenGLSkybox::nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) { OpenGLSharedState *state = renderer->getSharedState(); AtmosphereDefinition *newdef = renderer->getScenery()->getAtmosphere(); @@ -86,9 +86,18 @@ void OpenGLSkybox::nodeChanged(const DefinitionNode *node, const DefinitionDiff state->set("sunColor", sun_color); state->set("dayTime", newdef->propDayTime()->getValue()); - } else if (node->getPath() == path_humidity) { - state->set("atmosphereHumidity", newdef->propHumidity()->getValue()); - } else if (node->getPath() == path_sun_radius) { - state->set("sunRadius", newdef->propSunRadius()->getValue()); + } + + DefinitionWatcher::nodeChanged(node, diff); +} + +void OpenGLSkybox::floatNodeChanged(const string &path, double new_value, double) +{ + OpenGLSharedState *state = renderer->getSharedState(); + + if (path == path_humidity) { + state->set("atmosphereHumidity", new_value); + } else if (path == path_sun_radius) { + state->set("sunRadius", new_value); } } diff --git a/src/render/opengl/OpenGLSkybox.h b/src/render/opengl/OpenGLSkybox.h index ab76cd6..8e7afe0 100644 --- a/src/render/opengl/OpenGLSkybox.h +++ b/src/render/opengl/OpenGLSkybox.h @@ -19,6 +19,7 @@ class OPENGLSHARED_EXPORT OpenGLSkybox : public OpenGLPart, public DefinitionWat virtual void render() override; virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) override; + virtual void floatNodeChanged(const string &path, double new_value, double old_value) override; private: OpenGLShaderProgram *program; diff --git a/src/render/opengl/OpenGLTerrain.cpp b/src/render/opengl/OpenGLTerrain.cpp index 1fa7c41..da99fca 100644 --- a/src/render/opengl/OpenGLTerrain.cpp +++ b/src/render/opengl/OpenGLTerrain.cpp @@ -1,5 +1,6 @@ #include "OpenGLTerrain.h" +#include #include #include "OpenGLFunctions.h" #include "OpenGLRenderer.h" diff --git a/src/render/opengl/OpenGLVariable.h b/src/render/opengl/OpenGLVariable.h index 07aef32..135b0ef 100644 --- a/src/render/opengl/OpenGLVariable.h +++ b/src/render/opengl/OpenGLVariable.h @@ -53,6 +53,13 @@ class OpenGLVariable { void set(const QMatrix4x4 &matrix); void set(const Color &color); + inline int getIntValue() const { + return value_int; + } + inline float getFloatValue() const { + return value_float; + } + protected: void uploadTexture(OpenGLRenderer *renderer); diff --git a/src/tests/BaseTestCase.h b/src/tests/BaseTestCase.h index 4011c18..c58ed66 100644 --- a/src/tests/BaseTestCase.h +++ b/src/tests/BaseTestCase.h @@ -35,6 +35,11 @@ ASSERT_DOUBLE_EQ(_vec_.y, _y_); \ ASSERT_DOUBLE_EQ(_vec_.z, _z_) +#define EXPECT_GLVARIABLE_FLOAT(_expected_, _state_, _name_) \ + EXPECT_NEAR(_expected_, (_state_)->get(_name_)->getFloatValue(), 0.000001) +#define ASSERT_GLVARIABLE_FLOAT(_expected_, _state_, _name_) \ + ASSERT_NEAR(_expected_, (_state_)->get(_name_)->getFloatValue(), 0.000001) + class BaseTestCase : public ::testing::Test {}; #endif // BASETESTCASE_H diff --git a/src/tests/OpenGLSkybox_Test.cpp b/src/tests/OpenGLSkybox_Test.cpp new file mode 100644 index 0000000..3d6b91f --- /dev/null +++ b/src/tests/OpenGLSkybox_Test.cpp @@ -0,0 +1,27 @@ +#include "BaseTestCase.h" +#include "OpenGLSkybox.h" + +#include "Scenery.h" +#include "OpenGLSharedState.h" +#include "OpenGLRenderer.h" + +TEST(OpenGLSkybox, glvariable_atmosphereHumidity) { + Scenery scenery; + OpenGLRenderer renderer(&scenery); + + OpenGLSkybox glvegetation(&renderer); + glvegetation.initialize(); + EXPECT_GLVARIABLE_FLOAT(0.0, renderer.getSharedState(), "atmosphereHumidity"); + + scenery.set("/atmosphere/humidity", 0.8); + EXPECT_GLVARIABLE_FLOAT(0.8, renderer.getSharedState(), "atmosphereHumidity"); + + scenery.set("/atmosphere/humidity", 0.6); + EXPECT_GLVARIABLE_FLOAT(0.6, renderer.getSharedState(), "atmosphereHumidity"); + + scenery.undo(); + EXPECT_GLVARIABLE_FLOAT(0.8, renderer.getSharedState(), "atmosphereHumidity"); + + scenery.redo(); + EXPECT_GLVARIABLE_FLOAT(0.6, renderer.getSharedState(), "atmosphereHumidity"); +}