Added some convenience to set and watch scenery nodes

This commit is contained in:
Michaël Lemaire 2015-12-13 19:56:00 +01:00
parent 8ff83d48e7
commit d6444028f9
13 changed files with 141 additions and 11 deletions

View file

@ -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) {

View file

@ -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:
/**

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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);

View file

@ -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);
}
}

View file

@ -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;

View file

@ -1,5 +1,6 @@
#include "OpenGLTerrain.h"
#include <algorithm>
#include <vector>
#include "OpenGLFunctions.h"
#include "OpenGLRenderer.h"

View file

@ -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);

View file

@ -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

View file

@ -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");
}