Refactored layers system to work better as DefinitionNode
It now features undo/redo of layer creation and removal
This commit is contained in:
parent
5f0b3734cf
commit
2b65f1d26a
24 changed files with 444 additions and 207 deletions
|
@ -6,7 +6,8 @@
|
|||
#include "PackStream.h"
|
||||
#include "FloatNode.h"
|
||||
|
||||
CloudLayerDefinition::CloudLayerDefinition(DefinitionNode *parent) : DefinitionNode(parent, "layer", "cloudlayer") {
|
||||
CloudLayerDefinition::CloudLayerDefinition(DefinitionNode *parent, const std::string &name)
|
||||
: DefinitionNode(parent, name, "cloudlayer") {
|
||||
type = CIRRUS;
|
||||
altitude = 0.5;
|
||||
scaling = 0.5;
|
||||
|
@ -20,13 +21,13 @@ CloudLayerDefinition::~CloudLayerDefinition() {
|
|||
}
|
||||
|
||||
CloudLayerDefinition *CloudLayerDefinition::newCopy(const CloudLayerDefinition &other, DefinitionNode *parent) {
|
||||
CloudLayerDefinition *layer = new CloudLayerDefinition(parent);
|
||||
CloudLayerDefinition *layer = new CloudLayerDefinition(parent, other.getName());
|
||||
other.copy(layer);
|
||||
return layer;
|
||||
}
|
||||
|
||||
CloudLayerDefinition *CloudLayerDefinition::newCopy(DefinitionNode *parent) const {
|
||||
CloudLayerDefinition *layer = new CloudLayerDefinition(parent);
|
||||
CloudLayerDefinition *layer = new CloudLayerDefinition(parent, getName());
|
||||
copy(layer);
|
||||
return layer;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace definition {
|
|||
|
||||
class DEFINITIONSHARED_EXPORT CloudLayerDefinition : public DefinitionNode {
|
||||
public:
|
||||
CloudLayerDefinition(DefinitionNode *parent);
|
||||
CloudLayerDefinition(DefinitionNode *parent, const std::string &name);
|
||||
virtual ~CloudLayerDefinition();
|
||||
|
||||
inline const NoiseState &getNoiseState() const {
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
#include "CloudLayerDefinition.h"
|
||||
|
||||
static DefinitionNode *_layerConstructor(Layers *parent) {
|
||||
return new CloudLayerDefinition(parent);
|
||||
static DefinitionNode *_layerConstructor(Layers *parent, const std::string &name) {
|
||||
return new CloudLayerDefinition(parent, name);
|
||||
}
|
||||
|
||||
CloudsDefinition::CloudsDefinition(DefinitionNode *parent) : Layers(parent, "clouds", _layerConstructor) {
|
||||
|
@ -13,9 +13,8 @@ void CloudsDefinition::applyPreset(CloudsPreset preset) {
|
|||
clear();
|
||||
|
||||
if (preset == CLOUDS_PRESET_PARTLY_CLOUDY) {
|
||||
CloudLayerDefinition *layer = new CloudLayerDefinition(this);
|
||||
layer->type = CloudLayerDefinition::STRATOCUMULUS;
|
||||
layer->setName("Strato-cumulus");
|
||||
CloudLayerDefinition layer(NULL, "Strato-cumulus");
|
||||
layer.type = CloudLayerDefinition::STRATOCUMULUS;
|
||||
addLayer(layer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,3 +4,6 @@
|
|||
|
||||
DefinitionDiff::DefinitionDiff(const DefinitionNode *node) : type_name(node->getTypeName()), path(node->getPath()) {
|
||||
}
|
||||
|
||||
DefinitionDiff::~DefinitionDiff() {
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ namespace definition {
|
|||
class DEFINITIONSHARED_EXPORT DefinitionDiff {
|
||||
public:
|
||||
DefinitionDiff(const DefinitionNode *node);
|
||||
virtual ~DefinitionDiff();
|
||||
|
||||
inline const std::string &getTypeName() const {
|
||||
return type_name;
|
||||
|
|
|
@ -248,5 +248,7 @@ void DefinitionNode::addDiff(const DefinitionDiff *diff) {
|
|||
|
||||
if (root && root->diffs) {
|
||||
root->diffs->addDiff(this, diff);
|
||||
} else {
|
||||
delete diff;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "DefinitionNode.h"
|
||||
#include "DefinitionDiff.h"
|
||||
#include "DefinitionWatcher.h"
|
||||
#include "Logs.h"
|
||||
|
||||
DiffManager::DiffManager(DefinitionNode *tree) : tree(tree) {
|
||||
undone = 0;
|
||||
|
@ -46,31 +47,41 @@ void DiffManager::addDiff(DefinitionNode *node, const DefinitionDiff *diff) {
|
|||
|
||||
void DiffManager::undo() {
|
||||
if (undone < (int)diffs.size()) {
|
||||
undone++;
|
||||
const DefinitionDiff *diff = diffs[diffs.size() - undone];
|
||||
const DefinitionDiff *diff = diffs[diffs.size() - undone - 1];
|
||||
|
||||
// Obtain the node by path and reverse apply diff on it
|
||||
DefinitionNode *node = tree->findByPath(diff->getPath());
|
||||
if (node) {
|
||||
undone++;
|
||||
|
||||
node->applyDiff(diff, true);
|
||||
|
||||
for (auto watcher : watchers[node]) {
|
||||
// FIXME Reverse diff
|
||||
watcher->nodeChanged(node, diff);
|
||||
}
|
||||
} else {
|
||||
Logs::error() << "Can't find node to undo diff : " << diff->getPath() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DiffManager::redo() {
|
||||
if (undone > 0) {
|
||||
const DefinitionDiff *diff = diffs[diffs.size() - undone];
|
||||
undone--;
|
||||
|
||||
// Obtain the node by path and re-apply diff on it
|
||||
DefinitionNode *node = tree->findByPath(diff->getPath());
|
||||
if (node) {
|
||||
undone--;
|
||||
|
||||
node->applyDiff(diff);
|
||||
|
||||
for (auto watcher : watchers[node]) {
|
||||
watcher->nodeChanged(node, diff);
|
||||
}
|
||||
} else {
|
||||
Logs::error() << "Can't find node to redo diff : " << diff->getPath() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,13 @@ class DEFINITIONSHARED_EXPORT DiffManager {
|
|||
DiffManager(DefinitionNode *tree);
|
||||
~DiffManager();
|
||||
|
||||
/**
|
||||
* Get the total number of diff stored.
|
||||
*/
|
||||
inline int getDiffCount(int include_undone = true) {
|
||||
return include_undone ? diffs.size() : diffs.size() - undone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a watcher for a specific node.
|
||||
*
|
||||
|
|
|
@ -2,15 +2,15 @@
|
|||
|
||||
#include "PackStream.h"
|
||||
#include "Logs.h"
|
||||
#include "LayersDiff.h"
|
||||
|
||||
Layers::Layers(DefinitionNode *parent, const std::string &name, LayerConstructor layer_constructor)
|
||||
: DefinitionNode(parent, name, "layers" + name), layer_constructor(layer_constructor) {
|
||||
max_layer_count = 100;
|
||||
null_layer = layer_constructor(this);
|
||||
null_layer = layer_constructor(this, "#NULL#");
|
||||
}
|
||||
|
||||
Layers::~Layers() {
|
||||
clear();
|
||||
delete null_layer;
|
||||
}
|
||||
|
||||
|
@ -28,16 +28,12 @@ void Layers::load(PackStream *stream) {
|
|||
int layer_count;
|
||||
stream->read(&layer_count);
|
||||
|
||||
if (layer_count > max_layer_count) {
|
||||
layer_count = max_layer_count;
|
||||
}
|
||||
clear();
|
||||
for (int i = 0; i < layer_count; i++) {
|
||||
int position = addLayer();
|
||||
if (position >= 0) {
|
||||
layers[position]->setName(stream->readString());
|
||||
layers[position]->load(stream);
|
||||
}
|
||||
DefinitionNode *layer = layer_constructor(this, stream->readString());
|
||||
layer->load(stream);
|
||||
addLayer(*layer);
|
||||
delete layer;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,24 +49,18 @@ void Layers::copy(DefinitionNode *destination_) const {
|
|||
null_layer->copy(destination->null_layer);
|
||||
|
||||
for (auto layer : layers) {
|
||||
int position = destination->addLayer();
|
||||
DefinitionNode *new_layer = destination->getLayer(position);
|
||||
layer->copy(new_layer);
|
||||
destination->addLayer(*layer);
|
||||
}
|
||||
}
|
||||
|
||||
Layers *Layers::newCopy() const {
|
||||
Layers *result = new Layers(NULL, getName(), layer_constructor);
|
||||
copy(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Layers::setMaxLayerCount(int max_layer_count) {
|
||||
this->max_layer_count = max_layer_count;
|
||||
// TODO Delete overlimit layers ?
|
||||
for (int i = getLayerCount(); i > max_layer_count; i--) {
|
||||
removeLayer(i - 1);
|
||||
}
|
||||
}
|
||||
|
||||
int Layers::count() const {
|
||||
int Layers::getLayerCount() const {
|
||||
return layers.size();
|
||||
}
|
||||
|
||||
|
@ -84,82 +74,79 @@ DefinitionNode *Layers::getLayer(int position) const {
|
|||
}
|
||||
}
|
||||
|
||||
int Layers::findLayer(DefinitionNode *layer) const {
|
||||
int i = 0;
|
||||
for (auto it : layers) {
|
||||
if (it == layer) {
|
||||
return i;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
Logs::warning() << "Layer " << layer << " (" << layer->getName() << " not found, on a total of "
|
||||
<< (int)layers.size() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
bool Layers::applyDiff(const DefinitionDiff *diff, bool backward) {
|
||||
auto layer_diff = (LayersDiff *)diff;
|
||||
LayersDiff::LayersDiffOp op = layer_diff->getOp();
|
||||
int layer_count = getLayerCount();
|
||||
|
||||
int Layers::addLayer(DefinitionNode *layer) {
|
||||
if ((int)layers.size() < max_layer_count) {
|
||||
layers.push_back(layer);
|
||||
addChild(layer);
|
||||
return layers.size() - 1;
|
||||
} else {
|
||||
if ((not backward and op == LayersDiff::LAYER_ADDED) or (backward and op == LayersDiff::LAYER_REMOVED)) {
|
||||
if (layer_count >= max_layer_count) {
|
||||
Logs::warning() << "Add layer ignored because limit of " << max_layer_count << " reached" << std::endl;
|
||||
delete layer;
|
||||
return -1;
|
||||
return false;
|
||||
} else {
|
||||
int position = layer_diff->getLayer1();
|
||||
if (position < 0 or position > layer_count) {
|
||||
Logs::error() << "Add layer ignored because requested position was incorrect" << std::endl;
|
||||
return false;
|
||||
} else {
|
||||
DefinitionNode *layer = layer_constructor(this, "temp");
|
||||
layer_diff->restoreSavedLayer(layer);
|
||||
if (position == layer_count) {
|
||||
layers.push_back(layer);
|
||||
} else {
|
||||
layers.insert(layers.begin() + position, layer);
|
||||
}
|
||||
addChild(layer);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
int Layers::addLayer() {
|
||||
return addLayer(layer_constructor(this));
|
||||
}
|
||||
|
||||
void Layers::removeLayer(int position) {
|
||||
if (position >= 0 and position < (int)layers.size()) {
|
||||
} else if ((not backward and op == LayersDiff::LAYER_REMOVED) or (backward and op == LayersDiff::LAYER_ADDED)) {
|
||||
int position = layer_diff->getLayer1();
|
||||
if (position < 0 or position >= layer_count) {
|
||||
Logs::warning() << "Removing unknown layer " << position << " on " << layer_count << " from '" << getName()
|
||||
<< "'" << std::endl;
|
||||
return false;
|
||||
} else {
|
||||
DefinitionNode *removed = layers[position];
|
||||
removeChild(removed);
|
||||
layers.erase(layers.begin() + position);
|
||||
delete removed;
|
||||
} else {
|
||||
Logs::warning() << "Removing unknown layer " << position << " on " << (int)layers.size() << " from '"
|
||||
<< getName() << "'" << std::endl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Layers::generateInitDiffs(std::vector<const DefinitionDiff *> *diffs) const {
|
||||
int i = 0;
|
||||
for (auto layer: layers) {
|
||||
auto diff = new LayersDiff(this, LayersDiff::LAYER_ADDED, i++);
|
||||
diff->saveLayer(*layer);
|
||||
diffs->push_back(diff);
|
||||
}
|
||||
}
|
||||
|
||||
void Layers::removeLayer(DefinitionNode *layer) {
|
||||
removeLayer(findLayer(layer));
|
||||
void Layers::addLayer(const DefinitionNode &tocopy) {
|
||||
auto diff = new LayersDiff(this, LayersDiff::LAYER_ADDED, getLayerCount());
|
||||
diff->saveLayer(tocopy);
|
||||
addDiff(diff);
|
||||
}
|
||||
|
||||
void Layers::moveLayer(int old_position, int new_position) {
|
||||
if (old_position >= 0 and old_position < (int)layers.size() and new_position >= 0 and
|
||||
new_position < (int)layers.size()) {
|
||||
DefinitionNode *layer = layers[old_position];
|
||||
layers.erase(layers.begin() + old_position);
|
||||
layers.insert(layers.begin() + new_position, layer);
|
||||
}
|
||||
void Layers::addLayer(const std::string &name) {
|
||||
auto layer = layer_constructor(this, name);
|
||||
addLayer(*layer);
|
||||
delete layer;
|
||||
}
|
||||
|
||||
void Layers::moveLayer(DefinitionNode *layer, int new_position) {
|
||||
moveLayer(findLayer(layer), new_position);
|
||||
void Layers::removeLayer(int position) {
|
||||
auto diff = new LayersDiff(this, LayersDiff::LAYER_REMOVED, position);
|
||||
diff->saveLayer(*getLayer(position));
|
||||
addDiff(diff);
|
||||
}
|
||||
|
||||
void Layers::clear() {
|
||||
while (layers.size() > 0) {
|
||||
removeLayer(0);
|
||||
}
|
||||
}
|
||||
|
||||
DefinitionNode *Layers::findChildByName(const std::string name) {
|
||||
DefinitionNode *result = DefinitionNode::findChildByName(name);
|
||||
if (result) {
|
||||
return result;
|
||||
} else {
|
||||
int position = addLayer();
|
||||
if (position >= 0) {
|
||||
result = getLayer(position);
|
||||
result->setName(name);
|
||||
return result;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
int n = getLayerCount();
|
||||
for (int i = n - 1; i >= 0; i--) {
|
||||
removeLayer(i);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
namespace paysages {
|
||||
namespace definition {
|
||||
|
||||
typedef DefinitionNode *(*LayerConstructor)(Layers *parent);
|
||||
typedef DefinitionNode *(*LayerConstructor)(Layers *parent, const std::string &name);
|
||||
|
||||
/**
|
||||
* @brief Layers of definitions, ideally all of the same type.
|
||||
|
@ -21,31 +21,49 @@ class DEFINITIONSHARED_EXPORT Layers : public DefinitionNode {
|
|||
virtual void save(PackStream *stream) const override;
|
||||
virtual void load(PackStream *stream) override;
|
||||
virtual void copy(DefinitionNode *destination) const override;
|
||||
Layers *newCopy() const;
|
||||
|
||||
void setMaxLayerCount(int max_layer_count);
|
||||
|
||||
int count() const;
|
||||
DefinitionNode *getLayer(int position) const;
|
||||
int findLayer(DefinitionNode *layer) const;
|
||||
virtual bool applyDiff(const DefinitionDiff *diff, bool backward = false) override;
|
||||
virtual void generateInitDiffs(std::vector<const DefinitionDiff *> *diffs) const override;
|
||||
|
||||
/**
|
||||
* @brief Add a new layer
|
||||
*
|
||||
* This method takes ownership of the layer definition. In any case, it will be deleted by
|
||||
* this object (even if the layer could not be added).
|
||||
* @return The position of the new layer, -1 if it couldn't be added.
|
||||
* Set the maximal layer count allowed.
|
||||
*/
|
||||
int addLayer(DefinitionNode *layer);
|
||||
int addLayer();
|
||||
void removeLayer(int position);
|
||||
void removeLayer(DefinitionNode *layer);
|
||||
void moveLayer(int old_position, int new_position);
|
||||
void moveLayer(DefinitionNode *layer, int new_position);
|
||||
void clear();
|
||||
void setMaxLayerCount(int max_layer_count);
|
||||
|
||||
protected:
|
||||
virtual DefinitionNode *findChildByName(const std::string name) override;
|
||||
/**
|
||||
* Get the current layer count.
|
||||
*/
|
||||
int getLayerCount() const;
|
||||
|
||||
/**
|
||||
* Retrieve a layer by its position.
|
||||
*/
|
||||
DefinitionNode *getLayer(int position) const;
|
||||
|
||||
/**
|
||||
* Retrieve a layer by its name.
|
||||
*/
|
||||
DefinitionNode *getLayer(const std::string &name) const;
|
||||
|
||||
/**
|
||||
* Add a new empty layer.
|
||||
*/
|
||||
void addLayer(const std::string &name);
|
||||
|
||||
/**
|
||||
* Add a new layer, copying another node into it.
|
||||
*/
|
||||
void addLayer(const DefinitionNode &tocopy);
|
||||
|
||||
/**
|
||||
* Remove a layer by its position.
|
||||
*/
|
||||
void removeLayer(int position);
|
||||
|
||||
/**
|
||||
* Clear this node of all layers.
|
||||
*/
|
||||
void clear();
|
||||
|
||||
public:
|
||||
LayerConstructor layer_constructor;
|
||||
|
|
32
src/definition/LayersDiff.cpp
Normal file
32
src/definition/LayersDiff.cpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
#include "LayersDiff.h"
|
||||
|
||||
#include "PackStream.h"
|
||||
#include "Layers.h"
|
||||
#include "Logs.h"
|
||||
|
||||
LayersDiff::LayersDiff(const Layers *layers, LayersDiffOp op, int layer1)
|
||||
: DefinitionDiff(layers), op(op), layer1(layer1), saved(NULL) {
|
||||
}
|
||||
|
||||
LayersDiff::~LayersDiff() {
|
||||
if (saved) {
|
||||
delete saved;
|
||||
}
|
||||
}
|
||||
|
||||
void LayersDiff::saveLayer(const DefinitionNode &src) {
|
||||
if (saved) {
|
||||
delete saved;
|
||||
}
|
||||
saved = new PackStream();
|
||||
saved->write(src.getName());
|
||||
src.save(saved);
|
||||
}
|
||||
|
||||
void LayersDiff::restoreSavedLayer(DefinitionNode *dest) const {
|
||||
if (saved) {
|
||||
PackStream reader(saved);
|
||||
dest->setName(reader.readString());
|
||||
dest->load(&reader);
|
||||
}
|
||||
}
|
47
src/definition/LayersDiff.h
Normal file
47
src/definition/LayersDiff.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
#ifndef LAYERSDIFF_H
|
||||
#define LAYERSDIFF_H
|
||||
|
||||
#include "definition_global.h"
|
||||
|
||||
#include "DefinitionDiff.h"
|
||||
|
||||
namespace paysages {
|
||||
namespace definition {
|
||||
|
||||
class DEFINITIONSHARED_EXPORT LayersDiff : public DefinitionDiff {
|
||||
public:
|
||||
typedef enum { LAYER_ADDED, LAYER_REMOVED } LayersDiffOp;
|
||||
|
||||
public:
|
||||
LayersDiff(const Layers *layers, LayersDiffOp op, int layer1);
|
||||
virtual ~LayersDiff();
|
||||
|
||||
inline LayersDiffOp getOp() const {
|
||||
return op;
|
||||
}
|
||||
inline int getLayer1() const {
|
||||
return layer1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a layer state into the diff.
|
||||
*/
|
||||
void saveLayer(const DefinitionNode &src);
|
||||
|
||||
/**
|
||||
* Restore the saved layer into a node.
|
||||
*/
|
||||
void restoreSavedLayer(DefinitionNode *dest) const;
|
||||
|
||||
private:
|
||||
// Operation to apply
|
||||
LayersDiffOp op;
|
||||
// Position of first layer changed
|
||||
int layer1;
|
||||
// Serialized layer data
|
||||
PackStream *saved;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // LAYERSDIFF_H
|
|
@ -8,8 +8,8 @@
|
|||
#include "TerrainDefinition.h"
|
||||
#include "Color.h"
|
||||
|
||||
TextureLayerDefinition::TextureLayerDefinition(DefinitionNode *parent)
|
||||
: DefinitionNode(parent, "texture", "texturelayer") {
|
||||
TextureLayerDefinition::TextureLayerDefinition(DefinitionNode *parent, const std::string &name)
|
||||
: DefinitionNode(parent, name, "texturelayer") {
|
||||
terrain_zone = new Zone;
|
||||
_displacement_noise = new NoiseGenerator;
|
||||
_detail_noise = new NoiseGenerator;
|
||||
|
|
|
@ -20,7 +20,7 @@ class DEFINITIONSHARED_EXPORT TextureLayerDefinition : public DefinitionNode {
|
|||
} TextureLayerPreset;
|
||||
|
||||
public:
|
||||
TextureLayerDefinition(DefinitionNode *parent);
|
||||
TextureLayerDefinition(DefinitionNode *parent, const std::string &name);
|
||||
virtual ~TextureLayerDefinition();
|
||||
|
||||
virtual void save(PackStream *stream) const override;
|
||||
|
|
|
@ -2,53 +2,53 @@
|
|||
|
||||
#include "TextureLayerDefinition.h"
|
||||
|
||||
static DefinitionNode *_layer_constructor(Layers *parent) {
|
||||
return new TextureLayerDefinition(parent);
|
||||
static DefinitionNode *_layer_constructor(Layers *parent, const std::string &name) {
|
||||
return new TextureLayerDefinition(parent, name);
|
||||
}
|
||||
|
||||
TexturesDefinition::TexturesDefinition(DefinitionNode *parent) : Layers(parent, "textures", _layer_constructor) {
|
||||
}
|
||||
|
||||
void TexturesDefinition::applyPreset(TexturesPreset preset) {
|
||||
TextureLayerDefinition *layer;
|
||||
TextureLayerDefinition layer(NULL, "temp");
|
||||
clear();
|
||||
|
||||
layer = getTextureLayer(addLayer());
|
||||
layer->applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_MUD);
|
||||
layer->setName("Mud");
|
||||
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_MUD);
|
||||
layer.setName("Mud");
|
||||
addLayer(layer);
|
||||
|
||||
if (preset == TEXTURES_PRESET_FULL) {
|
||||
layer = getTextureLayer(addLayer());
|
||||
layer->applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_ROCK);
|
||||
layer->setName("Ground");
|
||||
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_ROCK);
|
||||
layer.setName("Ground");
|
||||
addLayer(layer);
|
||||
|
||||
layer = getTextureLayer(addLayer());
|
||||
layer->applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_GRASS);
|
||||
layer->setName("Grass");
|
||||
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_GRASS);
|
||||
layer.setName("Grass");
|
||||
addLayer(layer);
|
||||
|
||||
layer = getTextureLayer(addLayer());
|
||||
layer->applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_SAND);
|
||||
layer->setName("Sand");
|
||||
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_SAND);
|
||||
layer.setName("Sand");
|
||||
addLayer(layer);
|
||||
|
||||
layer = getTextureLayer(addLayer());
|
||||
layer->applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_SNOW);
|
||||
layer->setName("Snow");
|
||||
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_SNOW);
|
||||
layer.setName("Snow");
|
||||
addLayer(layer);
|
||||
} else if (preset == TEXTURES_PRESET_IRELAND) {
|
||||
layer = getTextureLayer(addLayer());
|
||||
layer->applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_ROCK);
|
||||
layer->setName("Ground");
|
||||
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_ROCK);
|
||||
layer.setName("Ground");
|
||||
addLayer(layer);
|
||||
|
||||
layer = getTextureLayer(addLayer());
|
||||
layer->applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_GRASS);
|
||||
layer->setName("Grass");
|
||||
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_GRASS);
|
||||
layer.setName("Grass");
|
||||
addLayer(layer);
|
||||
} else if (preset == TEXTURES_PRESET_ALPS) {
|
||||
layer = getTextureLayer(addLayer());
|
||||
layer->applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_ROCK);
|
||||
layer->setName("Ground");
|
||||
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_ROCK);
|
||||
layer.setName("Ground");
|
||||
addLayer(layer);
|
||||
|
||||
layer = getTextureLayer(addLayer());
|
||||
layer->applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_SNOW);
|
||||
layer->setName("Snow");
|
||||
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_SNOW);
|
||||
layer.setName("Snow");
|
||||
addLayer(layer);
|
||||
} else if (preset == TEXTURES_PRESET_CANYON) {
|
||||
/* TODO */
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ void TexturesDefinition::applyPreset(TexturesPreset preset) {
|
|||
|
||||
double TexturesDefinition::getMaximalDisplacement() {
|
||||
double result = 0.0;
|
||||
int n = count();
|
||||
int n = getLayerCount();
|
||||
for (int i = 0; i < n; i++) {
|
||||
result += getTextureLayer(i)->displacement_height;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ void TimeManager::moveForward(Scenery *scenery, double amount) {
|
|||
scenery->getAtmosphere()->setDayTime(scenery->getAtmosphere()->propDayTime()->getValue() + amount);
|
||||
|
||||
// Move the clouds
|
||||
int n = scenery->getClouds()->count();
|
||||
int n = scenery->getClouds()->getLayerCount();
|
||||
for (int i = 0; i < n; i++) {
|
||||
CloudLayerDefinition *cloud = scenery->getClouds()->getCloudLayer(i);
|
||||
cloud->propXOffset()->addValue(-wind_x * amount * 100.0);
|
||||
|
|
|
@ -26,6 +26,7 @@ class SurfaceMaterial;
|
|||
class Zone;
|
||||
class WaterDefinition;
|
||||
class Layers;
|
||||
class LayersDiff;
|
||||
class CloudsDefinition;
|
||||
class CloudLayerDefinition;
|
||||
class AtmosphereDefinition;
|
||||
|
|
|
@ -52,14 +52,15 @@ static void testGroundShadowQuality() {
|
|||
scenery.getAtmosphere()->applyPreset(AtmosphereDefinition::ATMOSPHERE_PRESET_CLEAR_SUNSET);
|
||||
scenery.getAtmosphere()->setDayTime(16, 45);
|
||||
scenery.getTextures()->clear();
|
||||
TextureLayerDefinition *texture = scenery.getTextures()->getTextureLayer(scenery.getTextures()->addLayer());
|
||||
texture->displacement_height = 0.3;
|
||||
texture->displacement_scaling = 2.0;
|
||||
texture->displacement_offset = 0.0;
|
||||
texture->material->setColor(0.6, 0.55, 0.57, 1.0);
|
||||
texture->material->reflection = 0.006;
|
||||
texture->material->shininess = 6.0;
|
||||
texture->validate();
|
||||
TextureLayerDefinition texture(NULL, "test");
|
||||
texture.displacement_height = 0.3;
|
||||
texture.displacement_scaling = 2.0;
|
||||
texture.displacement_offset = 0.0;
|
||||
texture.material->setColor(0.6, 0.55, 0.57, 1.0);
|
||||
texture.material->reflection = 0.006;
|
||||
texture.material->shininess = 6.0;
|
||||
texture.validate();
|
||||
scenery.getTextures()->addLayer(texture);
|
||||
scenery.getCamera()->setLocation(Vector3(10.0, 10.0, -10.0));
|
||||
scenery.getCamera()->setTarget(VECTOR_ZERO);
|
||||
scenery.validate();
|
||||
|
|
|
@ -20,7 +20,7 @@ CloudsRenderer::CloudsRenderer(SoftwareRenderer *parent) : parent(parent) {
|
|||
enabled = true;
|
||||
fake_renderer = new BaseCloudLayerRenderer(parent);
|
||||
|
||||
CloudLayerDefinition *fake_layer = new CloudLayerDefinition(NULL);
|
||||
CloudLayerDefinition *fake_layer = new CloudLayerDefinition(NULL, "#fake#");
|
||||
fake_model = new BaseCloudsModel(fake_layer);
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ void CloudsRenderer::update() {
|
|||
layer_models.clear();
|
||||
|
||||
CloudsDefinition *clouds = parent->getScenery()->getClouds();
|
||||
int n = clouds->count();
|
||||
int n = clouds->getLayerCount();
|
||||
for (int i = 0; i < n; i++) {
|
||||
layer_renderers.push_back(new CloudBasicLayerRenderer(parent));
|
||||
|
||||
|
@ -129,7 +129,7 @@ void CloudsRenderer::setLayerModel(unsigned int layer, BaseCloudsModel *model, b
|
|||
Color CloudsRenderer::getColor(const Vector3 &eye, const Vector3 &location, const Color &base) {
|
||||
CloudsDefinition *definition = parent->getScenery()->getClouds();
|
||||
|
||||
int n = definition->count();
|
||||
int n = definition->getLayerCount();
|
||||
if (not enabled or n < 1) {
|
||||
return base;
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ Color CloudsRenderer::getColor(const Vector3 &eye, const Vector3 &location, cons
|
|||
bool CloudsRenderer::applyLightFilter(LightComponent &light, const Vector3 &at) {
|
||||
CloudsDefinition *definition = parent->getScenery()->getClouds();
|
||||
|
||||
int n = definition->count();
|
||||
int n = definition->getLayerCount();
|
||||
if (not enabled or n < 1) {
|
||||
return true;
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ double CloudsRenderer::getHighestAltitude() {
|
|||
CloudsDefinition *definition = parent->getScenery()->getClouds();
|
||||
double highest = 0.0;
|
||||
|
||||
int n = definition->count();
|
||||
int n = definition->getLayerCount();
|
||||
double low, high;
|
||||
for (int i = 0; i < n; i++) {
|
||||
BaseCloudsModel *layer_model = getLayerModel(i);
|
||||
|
|
|
@ -46,7 +46,7 @@ double TexturesRenderer::getTriplanarNoise(NoiseGenerator *noise, const Vector3
|
|||
double TexturesRenderer::getMaximalDisplacement(TexturesDefinition *textures) {
|
||||
int i, n;
|
||||
double disp = 0.0;
|
||||
n = textures->count();
|
||||
n = textures->getLayerCount();
|
||||
for (i = 0; i < n; i++) {
|
||||
TextureLayerDefinition *layer = textures->getTextureLayer(i);
|
||||
|
||||
|
@ -129,7 +129,7 @@ Vector3 TexturesRenderer::displaceTerrain(const TerrainRenderer::TerrainResult &
|
|||
double offset = 0.0;
|
||||
int i, n;
|
||||
|
||||
n = textures->count();
|
||||
n = textures->getLayerCount();
|
||||
for (i = 0; i < n; i++) {
|
||||
TextureLayerDefinition *layer = textures->getTextureLayer(i);
|
||||
|
||||
|
@ -161,7 +161,7 @@ TexturesRenderer::TexturesResult TexturesRenderer::applyToTerrain(double x, doub
|
|||
// TODO Displaced textures had their presence already computed before, store that result and use it
|
||||
|
||||
// Find presence of each layer
|
||||
int n = textures->count();
|
||||
int n = textures->getLayerCount();
|
||||
int start = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
TexturesLayerResult &layer = result.layers[i];
|
||||
|
|
|
@ -15,5 +15,8 @@ bool FileSystem::isFile(const std::string &filepath) {
|
|||
bool FileSystem::removeFile(const std::string &filepath) {
|
||||
if (FileSystem::isFile(filepath)) {
|
||||
remove(filepath.c_str());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,13 @@ PackStream::PackStream(const PackStream *other) {
|
|||
stream->setVersion(QDataStream::Qt_5_2);
|
||||
}
|
||||
|
||||
PackStream::PackStream(const std::string &buffer_content) {
|
||||
file = NULL;
|
||||
buffer = new QByteArray(buffer_content.c_str(), buffer_content.size());
|
||||
stream = new QDataStream(buffer, QIODevice::ReadOnly);
|
||||
stream->setVersion(QDataStream::Qt_5_2);
|
||||
}
|
||||
|
||||
bool PackStream::bindToFile(const std::string &filepath, bool write) {
|
||||
if (not file) {
|
||||
file = new QFile(QString::fromStdString(filepath));
|
||||
|
@ -90,6 +97,16 @@ void PackStream::writeFromBuffer(const PackStream &other, bool prepend_size) {
|
|||
}
|
||||
}
|
||||
|
||||
std::string PackStream::getBuffer() {
|
||||
if (file) {
|
||||
Logs::error() << "Try to get buffer on a stream bound to a file: " << file->fileName().toStdString()
|
||||
<< std::endl;
|
||||
return "";
|
||||
} else {
|
||||
return buffer->toStdString();
|
||||
}
|
||||
}
|
||||
|
||||
void PackStream::read(int *value) {
|
||||
if (value and not stream->atEnd()) {
|
||||
int output;
|
||||
|
|
|
@ -25,6 +25,11 @@ class SYSTEMSHARED_EXPORT PackStream {
|
|||
*/
|
||||
PackStream(const PackStream *other);
|
||||
|
||||
/**
|
||||
* Open a reading stream on a buffer content.
|
||||
*/
|
||||
PackStream(const std::string &buffer_content);
|
||||
|
||||
bool bindToFile(const std::string &filepath, bool write = false);
|
||||
|
||||
void write(const int *value);
|
||||
|
@ -41,6 +46,11 @@ class SYSTEMSHARED_EXPORT PackStream {
|
|||
*/
|
||||
void writeFromBuffer(const PackStream &other, bool prepend_size = false);
|
||||
|
||||
/**
|
||||
* Get the contents of the memory buffer, if this stream is not bound to a file.
|
||||
*/
|
||||
std::string getBuffer();
|
||||
|
||||
void read(int *value);
|
||||
void read(double *value);
|
||||
void read(char *value, int max_length);
|
||||
|
|
|
@ -2,19 +2,21 @@
|
|||
|
||||
#include "Layers.h"
|
||||
#include "PackStream.h"
|
||||
#include "DiffManager.h"
|
||||
#include "IntNode.h"
|
||||
|
||||
DefinitionNode *_construc1(Layers *) {
|
||||
return new DefinitionNode(NULL, "test");
|
||||
static DefinitionNode *_construc1(Layers *, const std::string &name) {
|
||||
return new DefinitionNode(NULL, name);
|
||||
}
|
||||
|
||||
DefinitionNode *_construc2(Layers *parent) {
|
||||
DefinitionNode *result = new DefinitionNode(parent, "test");
|
||||
static DefinitionNode *_construc2(Layers *parent, const std::string &name) {
|
||||
DefinitionNode *result = new DefinitionNode(parent, name);
|
||||
return result;
|
||||
}
|
||||
|
||||
TEST(Layers, Constructor) {
|
||||
Layers layers1(NULL, "test", _construc1);
|
||||
EXPECT_EQ(0, layers1.count());
|
||||
EXPECT_EQ(0, layers1.getLayerCount());
|
||||
}
|
||||
|
||||
TEST(Layers, NullLayer) {
|
||||
|
@ -27,22 +29,22 @@ TEST(Layers, NullLayer) {
|
|||
EXPECT_EQ(NULL, layer->getParent());
|
||||
EXPECT_EQ(layer, layer->getRoot());
|
||||
|
||||
EXPECT_EQ("test", layer->getName());
|
||||
EXPECT_EQ("#NULL#", layer->getName());
|
||||
}
|
||||
|
||||
EXPECT_EQ(0, layers1.count());
|
||||
EXPECT_EQ(0, layers1.getLayerCount());
|
||||
}
|
||||
|
||||
TEST(Layers, copy) {
|
||||
Layers layers1(NULL, "test", _construc2);
|
||||
layers1.addLayer();
|
||||
EXPECT_EQ(1, layers1.count());
|
||||
layers1.addLayer("test");
|
||||
EXPECT_EQ(1, layers1.getLayerCount());
|
||||
|
||||
// Copy with the same constructor
|
||||
Layers layers2(NULL, "test", _construc2);
|
||||
EXPECT_EQ(0, layers2.count());
|
||||
EXPECT_EQ(0, layers2.getLayerCount());
|
||||
layers1.copy(&layers2);
|
||||
EXPECT_EQ(1, layers2.count());
|
||||
EXPECT_EQ(1, layers2.getLayerCount());
|
||||
EXPECT_EQ("test", layers1.getLayer(0)->getName());
|
||||
EXPECT_EQ(&layers1, layers1.getLayer(0)->getParent());
|
||||
EXPECT_EQ("test", layers2.getLayer(0)->getName());
|
||||
|
@ -54,32 +56,35 @@ TEST(Layers, maxLayerCount) {
|
|||
Layers layers1(NULL, "test", _construc1);
|
||||
layers1.setMaxLayerCount(2);
|
||||
|
||||
EXPECT_EQ(0, layers1.count());
|
||||
layers1.addLayer();
|
||||
EXPECT_EQ(1, layers1.count());
|
||||
layers1.addLayer();
|
||||
EXPECT_EQ(2, layers1.count());
|
||||
layers1.addLayer();
|
||||
EXPECT_EQ(2, layers1.count());
|
||||
layers1.addLayer();
|
||||
EXPECT_EQ(2, layers1.count());
|
||||
EXPECT_EQ(0, layers1.getLayerCount());
|
||||
layers1.addLayer("t1");
|
||||
EXPECT_EQ(1, layers1.getLayerCount());
|
||||
layers1.addLayer("t2");
|
||||
EXPECT_EQ(2, layers1.getLayerCount());
|
||||
layers1.addLayer("t3");
|
||||
EXPECT_EQ(2, layers1.getLayerCount());
|
||||
layers1.addLayer("t4");
|
||||
EXPECT_EQ(2, layers1.getLayerCount());
|
||||
layers1.removeLayer(0);
|
||||
EXPECT_EQ(1, layers1.count());
|
||||
layers1.addLayer();
|
||||
EXPECT_EQ(2, layers1.count());
|
||||
layers1.addLayer();
|
||||
EXPECT_EQ(2, layers1.count());
|
||||
EXPECT_EQ(1, layers1.getLayerCount());
|
||||
layers1.addLayer("t5");
|
||||
EXPECT_EQ(2, layers1.getLayerCount());
|
||||
layers1.addLayer("t6");
|
||||
EXPECT_EQ(2, layers1.getLayerCount());
|
||||
|
||||
layers1.setMaxLayerCount(1);
|
||||
EXPECT_EQ(1, layers1.getLayerCount());
|
||||
layers1.setMaxLayerCount(0);
|
||||
EXPECT_EQ(0, layers1.getLayerCount());
|
||||
}
|
||||
|
||||
TEST(Layers, saveLoad) {
|
||||
PackStream *stream;
|
||||
|
||||
Layers layers1(NULL, "test", _construc1);
|
||||
layers1.addLayer();
|
||||
layers1.addLayer();
|
||||
ASSERT_EQ(2, layers1.count());
|
||||
layers1.getLayer(0)->setName("first");
|
||||
layers1.getLayer(1)->setName("second");
|
||||
layers1.addLayer("first");
|
||||
layers1.addLayer("second");
|
||||
ASSERT_EQ(2, layers1.getLayerCount());
|
||||
|
||||
stream = new PackStream();
|
||||
stream->bindToFile("/tmp/test_paysages_pack", true);
|
||||
|
@ -93,7 +98,99 @@ TEST(Layers, saveLoad) {
|
|||
layers2.load(stream);
|
||||
delete stream;
|
||||
|
||||
ASSERT_EQ(2, layers2.count());
|
||||
ASSERT_EQ(2, layers2.getLayerCount());
|
||||
EXPECT_EQ("first", layers2.getLayer(0)->getName());
|
||||
EXPECT_EQ("second", layers2.getLayer(1)->getName());
|
||||
}
|
||||
|
||||
static void checkLayerChild(const Layers &layers, int layer, const std::string &name, int value) {
|
||||
ASSERT_EQ(1, layers.getLayerCount());
|
||||
ASSERT_TRUE(layers.getLayer(layer)->findByPath(name));
|
||||
ASSERT_EQ("int", layers.getLayer(layer)->findByPath(name)->getTypeName());
|
||||
EXPECT_EQ(value, ((IntNode *)layers.getLayer(layer)->findByPath(name))->getValue());
|
||||
}
|
||||
|
||||
class TestLayer : public DefinitionNode {
|
||||
public:
|
||||
TestLayer(Layers *parent, const std::string &name) : DefinitionNode(parent, name) {
|
||||
val = new IntNode(this, "val", 5);
|
||||
}
|
||||
IntNode *val;
|
||||
};
|
||||
|
||||
static DefinitionNode *_construc3(Layers *parent, const std::string &name) {
|
||||
return new TestLayer(parent, name);
|
||||
}
|
||||
|
||||
TEST(Layers, undoRedo) {
|
||||
Layers layers(NULL, "layers", _construc3);
|
||||
|
||||
EXPECT_EQ(0, layers.getLayerCount());
|
||||
EXPECT_EQ(0, layers.getDiffManager()->getDiffCount());
|
||||
|
||||
layers.addLayer("testlayer");
|
||||
|
||||
ASSERT_EQ(1, layers.getLayerCount());
|
||||
|
||||
TestLayer *layer = (TestLayer *)layers.getLayer(0);
|
||||
|
||||
EXPECT_EQ(1, layers.getDiffManager()->getDiffCount());
|
||||
checkLayerChild(layers, 0, "val", 5);
|
||||
|
||||
layer->val->setValue(8);
|
||||
|
||||
EXPECT_EQ(2, layers.getDiffManager()->getDiffCount());
|
||||
checkLayerChild(layers, 0, "val", 8);
|
||||
|
||||
layers.removeLayer(0);
|
||||
|
||||
EXPECT_EQ(3, layers.getDiffManager()->getDiffCount());
|
||||
EXPECT_EQ(0, layers.getLayerCount());
|
||||
|
||||
// Start undoing
|
||||
layers.getDiffManager()->undo();
|
||||
checkLayerChild(layers, 0, "val", 8);
|
||||
layers.getDiffManager()->undo();
|
||||
checkLayerChild(layers, 0, "val", 5);
|
||||
layers.getDiffManager()->undo();
|
||||
EXPECT_EQ(0, layers.getLayerCount());
|
||||
|
||||
EXPECT_EQ(3, layers.getDiffManager()->getDiffCount());
|
||||
|
||||
// Start redoing
|
||||
layers.getDiffManager()->redo();
|
||||
checkLayerChild(layers, 0, "val", 5);
|
||||
layers.getDiffManager()->redo();
|
||||
checkLayerChild(layers, 0, "val", 8);
|
||||
layers.getDiffManager()->redo();
|
||||
EXPECT_EQ(0, layers.getLayerCount());
|
||||
|
||||
EXPECT_EQ(3, layers.getDiffManager()->getDiffCount());
|
||||
|
||||
// TODO Test swapping
|
||||
}
|
||||
|
||||
TEST(Layers, generateInitDiffs) {
|
||||
Layers layers(NULL, "layers", _construc1);
|
||||
|
||||
std::vector<const DefinitionDiff *> diffs;
|
||||
layers.generateInitDiffs(&diffs);
|
||||
EXPECT_EQ(0, (int)diffs.size());
|
||||
|
||||
layers.addLayer("l1");
|
||||
layers.addLayer("l2");
|
||||
layers.addLayer("l3");
|
||||
|
||||
diffs.clear();
|
||||
layers.generateInitDiffs(&diffs);
|
||||
EXPECT_EQ(3, (int)diffs.size());
|
||||
|
||||
Layers layers1(NULL, "layers", _construc1);
|
||||
for (auto diff: diffs) {
|
||||
layers1.applyDiff(diff);
|
||||
}
|
||||
ASSERT_EQ(3, layers1.getLayerCount());
|
||||
EXPECT_EQ("l1", layers1.getLayer(0)->getName());
|
||||
EXPECT_EQ("l2", layers1.getLayer(1)->getName());
|
||||
EXPECT_EQ("l3", layers1.getLayer(2)->getName());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue