2013-10-31 16:59:18 +00:00
|
|
|
#include "Layers.h"
|
|
|
|
|
2015-08-13 17:49:16 +00:00
|
|
|
#include "PackStream.h"
|
2015-08-12 15:02:27 +00:00
|
|
|
#include "Logs.h"
|
2015-11-20 00:07:31 +00:00
|
|
|
#include "LayersDiff.h"
|
2015-08-12 15:02:27 +00:00
|
|
|
|
2015-12-10 23:36:50 +00:00
|
|
|
Layers::Layers(DefinitionNode *parent, const string &name, LayerConstructor layer_constructor)
|
2015-11-09 21:30:46 +00:00
|
|
|
: DefinitionNode(parent, name, "layers" + name), layer_constructor(layer_constructor) {
|
2013-10-31 16:59:18 +00:00
|
|
|
max_layer_count = 100;
|
2015-11-20 00:07:31 +00:00
|
|
|
null_layer = layer_constructor(this, "#NULL#");
|
2013-10-31 16:59:18 +00:00
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
Layers::~Layers() {
|
2013-10-31 16:59:18 +00:00
|
|
|
delete null_layer;
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Layers::save(PackStream *stream) const {
|
2015-08-13 17:49:16 +00:00
|
|
|
int layer_count = (int)layers.size();
|
|
|
|
stream->write(&layer_count);
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
for (int i = 0; i < layer_count; i++) {
|
2015-08-13 21:46:50 +00:00
|
|
|
stream->write(layers[i]->getName());
|
|
|
|
layers[i]->save(stream);
|
|
|
|
}
|
2015-08-13 17:49:16 +00:00
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Layers::load(PackStream *stream) {
|
2015-08-13 17:49:16 +00:00
|
|
|
int layer_count;
|
|
|
|
stream->read(&layer_count);
|
|
|
|
|
|
|
|
clear();
|
2015-11-09 21:30:46 +00:00
|
|
|
for (int i = 0; i < layer_count; i++) {
|
2015-11-20 00:07:31 +00:00
|
|
|
DefinitionNode *layer = layer_constructor(this, stream->readString());
|
|
|
|
layer->load(stream);
|
|
|
|
addLayer(*layer);
|
|
|
|
delete layer;
|
2015-08-13 17:49:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Layers::copy(DefinitionNode *destination_) const {
|
2015-08-12 20:21:10 +00:00
|
|
|
DefinitionNode::copy(destination_);
|
2013-10-31 23:09:51 +00:00
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
Layers *destination = (Layers *)destination_;
|
2013-10-31 16:59:18 +00:00
|
|
|
|
|
|
|
destination->clear();
|
|
|
|
|
|
|
|
destination->max_layer_count = max_layer_count;
|
|
|
|
|
|
|
|
null_layer->copy(destination->null_layer);
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
for (auto layer : layers) {
|
2015-11-20 00:07:31 +00:00
|
|
|
destination->addLayer(*layer);
|
2013-10-31 16:59:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Layers::setMaxLayerCount(int max_layer_count) {
|
2013-10-31 16:59:18 +00:00
|
|
|
this->max_layer_count = max_layer_count;
|
2015-11-20 00:07:31 +00:00
|
|
|
for (int i = getLayerCount(); i > max_layer_count; i--) {
|
|
|
|
removeLayer(i - 1);
|
|
|
|
}
|
2013-10-31 16:59:18 +00:00
|
|
|
}
|
|
|
|
|
2015-11-20 00:07:31 +00:00
|
|
|
int Layers::getLayerCount() const {
|
2013-12-10 21:32:58 +00:00
|
|
|
return layers.size();
|
2013-10-31 16:59:18 +00:00
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
DefinitionNode *Layers::getLayer(int position) const {
|
|
|
|
if (position >= 0 and position < (int)layers.size()) {
|
2013-10-31 16:59:18 +00:00
|
|
|
return layers[position];
|
2015-11-09 21:30:46 +00:00
|
|
|
} else {
|
2015-12-13 19:08:38 +00:00
|
|
|
Logs::warning("Definition") << "Asked for a undefined layer " << position << " on a total of "
|
|
|
|
<< (int)layers.size() << endl;
|
2013-10-31 16:59:18 +00:00
|
|
|
return null_layer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-20 00:07:31 +00:00
|
|
|
bool Layers::applyDiff(const DefinitionDiff *diff, bool backward) {
|
|
|
|
auto layer_diff = (LayersDiff *)diff;
|
|
|
|
LayersDiff::LayersDiffOp op = layer_diff->getOp();
|
|
|
|
int layer_count = getLayerCount();
|
2013-10-31 16:59:18 +00:00
|
|
|
|
2015-11-20 00:07:31 +00:00
|
|
|
if ((not backward and op == LayersDiff::LAYER_ADDED) or (backward and op == LayersDiff::LAYER_REMOVED)) {
|
|
|
|
if (layer_count >= max_layer_count) {
|
2015-12-13 19:08:38 +00:00
|
|
|
Logs::warning("Definition") << "Add layer ignored because limit of " << max_layer_count << " reached"
|
|
|
|
<< endl;
|
2015-11-20 00:07:31 +00:00
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
int position = layer_diff->getLayer1();
|
|
|
|
if (position < 0 or position > layer_count) {
|
2015-12-13 19:08:38 +00:00
|
|
|
Logs::error("Definition") << "Add layer ignored because requested position was incorrect" << endl;
|
2015-11-20 00:07:31 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} 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) {
|
2015-12-13 19:08:38 +00:00
|
|
|
Logs::warning("Definition") << "Removing unknown layer " << position << " on " << layer_count << " from '"
|
|
|
|
<< getName() << "'" << endl;
|
2015-11-20 00:07:31 +00:00
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
DefinitionNode *removed = layers[position];
|
|
|
|
removeChild(removed);
|
|
|
|
layers.erase(layers.begin() + position);
|
|
|
|
delete removed;
|
|
|
|
return true;
|
|
|
|
}
|
2013-10-31 16:59:18 +00:00
|
|
|
}
|
2015-11-20 00:07:31 +00:00
|
|
|
return false;
|
2013-10-31 16:59:18 +00:00
|
|
|
}
|
|
|
|
|
2015-12-10 23:36:50 +00:00
|
|
|
void Layers::generateInitDiffs(vector<const DefinitionDiff *> *diffs) const {
|
2015-11-20 00:07:31 +00:00
|
|
|
int i = 0;
|
2015-12-03 22:04:50 +00:00
|
|
|
for (auto layer : layers) {
|
2015-11-20 00:07:31 +00:00
|
|
|
auto diff = new LayersDiff(this, LayersDiff::LAYER_ADDED, i++);
|
|
|
|
diff->saveLayer(*layer);
|
|
|
|
diffs->push_back(diff);
|
2013-12-15 14:33:54 +00:00
|
|
|
}
|
2013-10-31 16:59:18 +00:00
|
|
|
}
|
|
|
|
|
2015-11-20 00:07:31 +00:00
|
|
|
void Layers::addLayer(const DefinitionNode &tocopy) {
|
|
|
|
auto diff = new LayersDiff(this, LayersDiff::LAYER_ADDED, getLayerCount());
|
|
|
|
diff->saveLayer(tocopy);
|
|
|
|
addDiff(diff);
|
2013-10-31 16:59:18 +00:00
|
|
|
}
|
|
|
|
|
2015-12-10 23:36:50 +00:00
|
|
|
void Layers::addLayer(const string &name) {
|
2015-11-20 00:07:31 +00:00
|
|
|
auto layer = layer_constructor(this, name);
|
|
|
|
addLayer(*layer);
|
|
|
|
delete layer;
|
2013-10-31 16:59:18 +00:00
|
|
|
}
|
|
|
|
|
2015-11-20 00:07:31 +00:00
|
|
|
void Layers::removeLayer(int position) {
|
|
|
|
auto diff = new LayersDiff(this, LayersDiff::LAYER_REMOVED, position);
|
|
|
|
diff->saveLayer(*getLayer(position));
|
|
|
|
addDiff(diff);
|
2013-10-31 16:59:18 +00:00
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Layers::clear() {
|
2015-11-20 00:07:31 +00:00
|
|
|
int n = getLayerCount();
|
|
|
|
for (int i = n - 1; i >= 0; i--) {
|
|
|
|
removeLayer(i);
|
2015-08-13 21:46:50 +00:00
|
|
|
}
|
|
|
|
}
|