WIP on c++ layers

This commit is contained in:
Michaël Lemaire 2013-10-31 17:59:18 +01:00 committed by Michael Lemaire
parent 8b9c3b2de1
commit 5dfa34dd56
23 changed files with 493 additions and 289 deletions

View file

@ -22,21 +22,14 @@ BaseDefinition::~BaseDefinition()
}
}
void BaseDefinition::addChild(BaseDefinition* child)
void BaseDefinition::setName(QString name)
{
if (not children.contains(child))
{
children.append(child);
}
}
void BaseDefinition::removeChild(BaseDefinition* child)
{
children.removeOne(child);
this->name = name;
}
void BaseDefinition::save(PackStream* pack)
{
pack->write(name);
QListIterator<BaseDefinition*> it(children);
while (it.hasNext())
{
@ -46,9 +39,39 @@ void BaseDefinition::save(PackStream* pack)
void BaseDefinition::load(PackStream* pack)
{
name = pack->readString();
QListIterator<BaseDefinition*> it(children);
while (it.hasNext())
{
it.next()->load(pack);
}
}
void BaseDefinition::copy(BaseDefinition* destination)
{
// TODO
}
void BaseDefinition::validate()
{
QListIterator<BaseDefinition*> it(children);
while (it.hasNext())
{
it.next()->validate();
}
}
void BaseDefinition::addChild(BaseDefinition* child)
{
if (not children.contains(child))
{
children.append(child);
child->parent = this;
child->root = this->root;
}
}
void BaseDefinition::removeChild(BaseDefinition* child)
{
children.removeOne(child);
}

View file

@ -4,6 +4,7 @@
#include "definition_global.h"
#include <QList>
#include <QString>
#include "PackStream.h" // TODO Delete when c++ migration is done
namespace paysages {
@ -21,6 +22,12 @@ public:
virtual void save(PackStream* pack);
virtual void load(PackStream* pack);
virtual void copy(BaseDefinition* destination);
virtual void validate();
inline const QString& getName() {return name;}
void setName(QString name);
protected:
void addChild(BaseDefinition* child);
void removeChild(BaseDefinition* child);
@ -28,6 +35,7 @@ protected:
private:
BaseDefinition* parent;
BaseDefinition* root;
QString name;
QList<BaseDefinition*> children;
};

220
src/definition/Layers.cpp Normal file
View file

@ -0,0 +1,220 @@
#include "Layers.h"
Layers::Layers(BaseDefinition* parent, LayerConstructor layer_constructor, LayerType* legacy_type):
BaseDefinition(parent), layer_constructor(layer_constructor)
{
if (legacy_type)
{
this->legacy_type = *legacy_type;
}
max_layer_count = 100;
null_layer = layer_constructor(this);
}
Layers::~Layers()
{
clear();
delete null_layer;
}
void Layers::copy(Layers* destination)
{
// don't call overridden method, it will copy again the children
// FIXME ... but the definition name (and other future attributes) is not copied
destination->clear();
destination->max_layer_count = max_layer_count;
destination->legacy_type = legacy_type;
null_layer->copy(destination->null_layer);
QListIterator<BaseDefinition*> it(layers);
while (it.hasNext())
{
int position = destination->addLayer();
BaseDefinition* new_layer = destination->getLayer(position);
it.next()->copy(new_layer);
}
}
void Layers::setMaxLayerCount(int max_layer_count)
{
this->max_layer_count = max_layer_count;
// TODO Delete overlimit layers ?
}
int Layers::count()
{
return layers.count();
}
BaseDefinition* Layers::getLayer(int position)
{
if (position >= 0 and position < layers.size())
{
return layers[position];
}
else
{
qWarning("Asked for a undefined layer %d on a total of %d", position, layers.size());
return null_layer;
}
}
int Layers::findLayer(BaseDefinition* layer)
{
int result = layers.indexOf(layer);
if (result < 0)
{
qWarning("Layer %p not found, on a total of %d, returning %d", layer, layers.size(), result);
}
return result;
}
int Layers::addLayer(BaseDefinition* layer)
{
if (layers.size() < max_layer_count)
{
layers.append(layer);
addChild(layer);
return layers.size() - 1;
}
else
{
qWarning("Add layer ignored because limit of %d reached", max_layer_count);
return -1;
}
}
int Layers::addLayer()
{
return addLayer(layer_constructor(this));
}
void Layers::removeLayer(int position)
{
if (position >= 0 and position < layers.size())
{
BaseDefinition* removed = layers.takeAt(position);
removeChild(removed);
delete removed;
}
}
void Layers::removeLayer(BaseDefinition* layer)
{
removeLayer(findLayer(layer));
}
void Layers::moveLayer(int old_position, int new_position)
{
// TODO
}
void Layers::moveLayer(BaseDefinition* layer, int new_position)
{
moveLayer(findLayer(layer), new_position);
}
void Layers::clear()
{
while (layers.size() > 0)
{
removeLayer(0);
}
}
// Transitional C-API
BaseDefinition* _legacyLayerConstructor(Layers* layers)
{
return new LegacyLayer(layers, &layers->legacy_type);
}
Layers* layersCreate(LayerType type, int max_layer_count)
{
Layers* result = new Layers(NULL, _legacyLayerConstructor, &type);
result->setMaxLayerCount(max_layer_count);
return result;
}
Layers* layersCreateCopy(Layers* original)
{
Layers* result = new Layers(NULL, _legacyLayerConstructor, &original->legacy_type);
original->copy(result);
return result;
}
void layersDelete(Layers* layers)
{
delete layers;
}
void layersCopy(Layers* source, Layers* destination)
{
source->copy(destination);
}
void layersValidate(Layers* layers)
{
layers->validate();
}
void layersSave(PackStream* stream, Layers* layers)
{
layers->save(stream);
}
void layersLoad(PackStream* stream, Layers* layers)
{
layers->load(stream);
}
const char* layersGetName(Layers* layers, int layer)
{
return "TODO";
}
void layersSetName(Layers* layers, int layer, const char* name)
{
layers->getLayer(layer)->setName(name);
}
void layersClear(Layers* layers)
{
layers->clear();
}
int layersCount(Layers* layers)
{
return layers->count();
}
void* layersGetLayer(Layers* layers, int layer)
{
LegacyLayer* legacy = (LegacyLayer*)(layers->getLayer(layer));
return legacy->getLegacyDefinition();
}
int layersAddLayer(Layers* layers, void* definition)
{
int position;
LegacyLayer* legacy = new LegacyLayer(layers, &layers->legacy_type);
if (definition)
{
layers->legacy_type.callback_copy(definition, legacy->getLegacyDefinition());
}
position = layers->addLayer(legacy);
return position;
}
void layersDeleteLayer(Layers* layers, int layer)
{
layers->removeLayer(layer);
}
void layersMove(Layers* layers, int layer, int new_position)
{
layers->moveLayer(layer, new_position);
}

98
src/definition/Layers.h Normal file
View file

@ -0,0 +1,98 @@
#ifndef LAYERS_H
#define LAYERS_H
#include "definition_global.h"
#include "PackStream.h"
#include "LegacyLayer.h"
#ifdef __cplusplus
#include "BaseDefinition.h"
namespace paysages {
namespace definition {
class Layers;
typedef BaseDefinition* (*LayerConstructor)(Layers* parent);
/**
* @brief Layers of definitions, ideally all of the same type.
*/
class DEFINITIONSHARED_EXPORT Layers:public BaseDefinition
{
public:
Layers(BaseDefinition* parent, LayerConstructor layer_constructor, LayerType* legacy_type=0);
virtual ~Layers();
virtual void copy(Layers* destination);
void setMaxLayerCount(int max_layer_count);
int count();
BaseDefinition* getLayer(int position);
int findLayer(BaseDefinition* layer);
/**
* @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.
*/
int addLayer(BaseDefinition* layer);
int addLayer();
void removeLayer(int position);
void removeLayer(BaseDefinition* layer);
void moveLayer(int old_position, int new_position);
void moveLayer(BaseDefinition* layer, int new_position);
void clear();
// Transitional data storage
LayerType legacy_type;
private:
LayerConstructor layer_constructor;
int max_layer_count;
QList<BaseDefinition*> layers;
BaseDefinition* null_layer;
};
}
}
extern "C" {
#endif
// Transitional C-API
#ifndef __cplusplus
typedef struct Layers Layers;
#endif
DEFINITIONSHARED_EXPORT Layers* layersCreate(LayerType type, int max_layer_count);
DEFINITIONSHARED_EXPORT Layers* layersCreateCopy(Layers* original);
DEFINITIONSHARED_EXPORT void layersDelete(Layers* layers);
DEFINITIONSHARED_EXPORT void layersCopy(Layers* source, Layers* destination);
DEFINITIONSHARED_EXPORT void layersValidate(Layers* layers);
DEFINITIONSHARED_EXPORT void layersSave(PackStream* stream, Layers* layers);
DEFINITIONSHARED_EXPORT void layersLoad(PackStream* stream, Layers* layers);
DEFINITIONSHARED_EXPORT const char* layersGetName(Layers* layers, int layer);
DEFINITIONSHARED_EXPORT void layersSetName(Layers* layers, int layer, const char* name);
DEFINITIONSHARED_EXPORT void layersClear(Layers* layers);
DEFINITIONSHARED_EXPORT int layersCount(Layers* layers);
DEFINITIONSHARED_EXPORT void* layersGetLayer(Layers* layers, int layer);
DEFINITIONSHARED_EXPORT int layersAddLayer(Layers* layers, void* definition);
DEFINITIONSHARED_EXPORT void layersDeleteLayer(Layers* layers, int layer);
DEFINITIONSHARED_EXPORT void layersMove(Layers* layers, int layer, int new_position);
#ifdef __cplusplus
}
#endif
#endif // LAYERS_H

View file

@ -0,0 +1,32 @@
#include "LegacyLayer.h"
LegacyLayer::LegacyLayer(BaseDefinition* parent, LayerType* type):
BaseDefinition(parent), type(*type)
{
legacy = type->callback_create();
}
LegacyLayer::~LegacyLayer()
{
type.callback_delete(legacy);
}
void LegacyLayer::save(PackStream* pack)
{
type.callback_save(pack, legacy);
}
void LegacyLayer::load(PackStream* pack)
{
type.callback_load(pack, legacy);
}
void LegacyLayer::copy(LegacyLayer* destination)
{
type.callback_copy(legacy, destination->legacy);
}
void LegacyLayer::validate()
{
type.callback_validate(legacy);
}

View file

@ -0,0 +1,50 @@
#ifndef LEGACYLAYER_H
#define LEGACYLAYER_H
#include <PackStream.h>
typedef void* (*LayerCallbackCreate)();
typedef void (*LayerCallbackDelete)(void* layer);
typedef void (*LayerCallbackCopy)(void* source, void* definition);
typedef void (*LayerCallbackValidate)(void* layer);
typedef void (*LayerCallbackSave)(PackStream* stream, void* layer);
typedef void (*LayerCallbackLoad)(PackStream* stream, void* layer);
typedef struct {
LayerCallbackCreate callback_create;
LayerCallbackDelete callback_delete;
LayerCallbackCopy callback_copy;
LayerCallbackValidate callback_validate;
LayerCallbackSave callback_save;
LayerCallbackLoad callback_load;
} LayerType;
#ifdef __cplusplus
#include <BaseDefinition.h>
/**
* @brief Wrapper around the old LayerType, used by C code.
*/
class LegacyLayer:public BaseDefinition
{
public:
LegacyLayer(BaseDefinition* parent, LayerType* type);
virtual ~LegacyLayer();
virtual void save(PackStream* pack);
virtual void load(PackStream* pack);
virtual void copy(LegacyLayer* destination);
virtual void validate();
inline void* getLegacyDefinition() { return legacy; }
private:
LayerType type;
void* legacy;
};
#endif
#endif // LEGACYLAYER_H

View file

@ -12,11 +12,15 @@ TEMPLATE = lib
DEFINES += DEFINITION_LIBRARY
SOURCES += \
BaseDefinition.cpp
BaseDefinition.cpp \
Layers.cpp \
LegacyLayer.cpp
HEADERS +=\
definition_global.h \
BaseDefinition.h
BaseDefinition.h \
Layers.h \
LegacyLayer.h
unix:!symbian {
maemo5 {

View file

@ -12,7 +12,7 @@
#include "PackStream.h"
#include "rendering/tools/lighting.h"
#include "rendering/noise.h"
#include "rendering/layers.h"
#include "Layers.h"
class QPushButton;
class QComboBox;

View file

@ -135,7 +135,7 @@ void BaseFormLayer::layerRenamedEvent(int layer, QString new_name)
void BaseFormLayer::layerSelectedEvent(int layer)
{
if (_layers_modified)
if (_layers_modified && layer >= 0)
{
layerReadCurrentFrom(layersGetLayer(_layers_modified, layer));
}

View file

@ -4,7 +4,7 @@
/* Base form, with automatic layer control */
#include "baseform.h"
#include "rendering/layers.h"
#include "Layers.h"
class BaseFormLayer:public BaseForm
{

View file

@ -2,7 +2,7 @@
#define _EDITING_COMMON_FREELAYERHELPER_H_
#include <QObject>
#include "rendering/layers.h"
#include "Layers.h"
class QTableWidget;
class QPushButton;

View file

@ -6,7 +6,7 @@
#include <QListWidget>
#include "tools.h"
#include "rendering/layers.h"
#include "Layers.h"
class DialogLayers;
class BaseFormLayer;

View file

@ -4,7 +4,7 @@
#include <QWidget>
#include "baseinput.h"
#include "dialoglayers.h"
#include "rendering/layers.h"
#include "Layers.h"
class InputLayers:public BaseInput
{

View file

@ -33,3 +33,15 @@ else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../system/debug/ -l
else:unix: LIBS += -L$$OUT_PWD/../system/ -lpaysages_system
INCLUDEPATH += $$PWD/../system
DEPENDPATH += $$PWD/../system
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../definition/release/ -lpaysages_definition
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../definition/debug/ -lpaysages_definition
else:unix: LIBS += -L$$OUT_PWD/../definition/ -lpaysages_definition
INCLUDEPATH += $$PWD/../definition
DEPENDPATH += $$PWD/../definition
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../basics/release/ -lpaysages_basics
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../basics/debug/ -lpaysages_basics
else:unix: LIBS += -L$$OUT_PWD/../basics/ -lpaysages_basics
INCLUDEPATH += $$PWD/../basics
DEPENDPATH += $$PWD/../basics

View file

@ -6,7 +6,6 @@
#include "../tools/euclid.h"
#include "../tools/color.h"
#include "PackStream.h"
#include "../layers.h"
#include "../shared/types.h"
#ifdef __cplusplus

View file

@ -7,7 +7,7 @@
#include "../tools/curve.h"
#include "../tools/euclid.h"
#include "../noise.h"
#include "../layers.h"
#include "Layers.h"
#ifdef __cplusplus
extern "C" {

View file

@ -1,210 +0,0 @@
#include "layers.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#define LAYERS_MAX_NAME_LENGTH 50
typedef struct
{
void* definition;
char name[LAYERS_MAX_NAME_LENGTH + 1];
} LayerInfo;
struct Layers {
LayerType type;
int count;
int max_count;
void* null_layer;
LayerInfo* layers_info;
};
Layers* layersCreate(LayerType type, int max_layer_count)
{
Layers* result = malloc(sizeof(Layers));
result->type = type;
result->count = 0;
result->max_count = max_layer_count;
result->null_layer = type.callback_create();
result->layers_info = malloc(sizeof(LayerInfo) * max_layer_count);
return result;
}
Layers* layersCreateCopy(Layers* original)
{
Layers* result = layersCreate(original->type, original->max_count);
layersCopy(original, result);
return result;
}
void layersDelete(Layers* layers)
{
int i;
for (i = 0; i < layers->count; i++)
{
layers->type.callback_delete(layers->layers_info[i].definition);
}
layers->type.callback_delete(layers->null_layer);
free(layers->layers_info);
free(layers);
}
void layersCopy(Layers* source, Layers* destination)
{
int i;
assert(source->type.callback_copy == destination->type.callback_copy);
assert(source->type.callback_create == destination->type.callback_create);
assert(source->type.callback_delete == destination->type.callback_delete);
assert(source->type.callback_load == destination->type.callback_load);
assert(source->type.callback_save == destination->type.callback_save);
assert(source->type.callback_validate == destination->type.callback_validate);
assert(source->max_count == destination->max_count);
/* TODO Optimize by reusing common layers */
while (destination->count > 0)
{
layersDeleteLayer(destination, 0);
}
for (i = 0; i < source->count; i++)
{
layersAddLayer(destination, source->layers_info[i].definition);
layersSetName(destination, i, layersGetName(source, i));
}
}
void layersValidate(Layers* layers)
{
int i;
for (i = 0; i < layers->count; i++)
{
layers->type.callback_validate(layers->layers_info[i].definition);
layers->layers_info[i].name[LAYERS_MAX_NAME_LENGTH] = '\0';
}
}
void layersSave(PackStream* stream, Layers* layers)
{
int i;
packWriteInt(stream, &layers->count);
for (i = 0; i < layers->count; i++)
{
packWriteString(stream, layers->layers_info[i].name, LAYERS_MAX_NAME_LENGTH);
layers->type.callback_save(stream, layers->layers_info[i].definition);
}
}
void layersLoad(PackStream* stream, Layers* layers)
{
int i;
packReadInt(stream, &layers->count);
for (i = 0; i < layers->count; i++)
{
packReadString(stream, layers->layers_info[i].name, LAYERS_MAX_NAME_LENGTH);
layers->type.callback_load(stream, layers->layers_info[i].definition);
}
layersValidate(layers);
}
const char* layersGetName(Layers* layers, int layer)
{
if (layer >= 0 && layer < layers->count)
{
return layers->layers_info[layer].name;
}
else
{
return "";
}
}
void layersSetName(Layers* layers, int layer, const char* name)
{
if (layer >= 0 && layer < layers->count)
{
strncpy(layers->layers_info[layer].name, name, LAYERS_MAX_NAME_LENGTH);
}
}
void layersClear(Layers* layers)
{
while (layersCount(layers))
{
layersDeleteLayer(layers, 0);
}
}
int layersCount(Layers* layers)
{
return layers->count;
}
void* layersGetLayer(Layers* layers, int layer)
{
if (layer >= 0 && layer < layers->count)
{
return layers->layers_info[layer].definition;
}
else
{
return layers->null_layer;
}
}
int layersAddLayer(Layers* layers, void* definition)
{
if (layers->count < layers->max_count)
{
layers->layers_info[layers->count].definition = layers->type.callback_create();
if (definition)
{
layers->type.callback_copy(definition, layers->layers_info[layers->count].definition);
}
layers->count++;
layersSetName(layers, layers->count - 1, "unnamed");
return layers->count - 1;
}
else
{
return -1;
}
}
void layersDeleteLayer(Layers* layers, int layer)
{
if (layer >= 0 && layer < layers->count)
{
layers->type.callback_delete(layers->layers_info[layer].definition);
if (layers->count > 1 && layer < layers->count - 1)
{
memmove(layers->layers_info + layer, layers->layers_info + layer + 1, sizeof(LayerInfo) * (layers->count - layer - 1));
}
layers->count--;
}
}
void layersMove(Layers* layers, int layer, int new_position)
{
if (layer >= 0 && layer < layers->count && new_position != layer && new_position >= 0 && new_position < layers->count)
{
LayerInfo temp;
temp = layers->layers_info[layer];
if (new_position > layer)
{
memmove(layers->layers_info + layer, layers->layers_info + layer + 1, sizeof(LayerInfo) * (new_position - layer));
}
else
{
memmove(layers->layers_info + new_position + 1, layers->layers_info + new_position, sizeof(LayerInfo) * (layer - new_position));
}
layers->layers_info[new_position] = temp;
}
}

View file

@ -1,55 +0,0 @@
#ifndef _PAYSAGES_LAYERS_H_
#define _PAYSAGES_LAYERS_H_
/* Factorized layer management (with names) */
#include "rendering_global.h"
#include "PackStream.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void* (*LayerCallbackCreate)();
typedef void (*LayerCallbackDelete)(void* layer);
typedef void (*LayerCallbackCopy)(void* source, void* definition);
typedef void (*LayerCallbackValidate)(void* layer);
typedef void (*LayerCallbackSave)(PackStream* stream, void* layer);
typedef void (*LayerCallbackLoad)(PackStream* stream, void* layer);
typedef struct {
LayerCallbackCreate callback_create;
LayerCallbackDelete callback_delete;
LayerCallbackCopy callback_copy;
LayerCallbackValidate callback_validate;
LayerCallbackSave callback_save;
LayerCallbackLoad callback_load;
} LayerType;
typedef struct Layers Layers;
RENDERINGSHARED_EXPORT Layers* layersCreate(LayerType type, int max_layer_count);
RENDERINGSHARED_EXPORT Layers* layersCreateCopy(Layers* original);
RENDERINGSHARED_EXPORT void layersDelete(Layers* layers);
RENDERINGSHARED_EXPORT void layersCopy(Layers* source, Layers* destination);
RENDERINGSHARED_EXPORT void layersValidate(Layers* layers);
RENDERINGSHARED_EXPORT void layersSave(PackStream* stream, Layers* layers);
RENDERINGSHARED_EXPORT void layersLoad(PackStream* stream, Layers* layers);
RENDERINGSHARED_EXPORT const char* layersGetName(Layers* layers, int layer);
RENDERINGSHARED_EXPORT void layersSetName(Layers* layers, int layer, const char* name);
RENDERINGSHARED_EXPORT void layersClear(Layers* layers);
RENDERINGSHARED_EXPORT int layersCount(Layers* layers);
RENDERINGSHARED_EXPORT void* layersGetLayer(Layers* layers, int layer);
RENDERINGSHARED_EXPORT int layersAddLayer(Layers* layers, void* definition);
RENDERINGSHARED_EXPORT void layersDeleteLayer(Layers* layers, int layer);
RENDERINGSHARED_EXPORT void layersMove(Layers* layers, int layer, int new_position);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -18,7 +18,6 @@ SOURCES += main.c \
noiseperlin.c \
noisenaive.c \
noise.c \
layers.c \
geoarea.c \
camera.c \
atmosphere/atm_render.c \
@ -74,7 +73,6 @@ HEADERS += \
noisenaive.h \
noise.h \
main.h \
layers.h \
geoarea.h \
camera.h \
atmosphere/public.h \

View file

@ -2,7 +2,7 @@
#define _PAYSAGES_TEXTURES_PUBLIC_H_
#include "../rendering_global.h"
#include "rendering/layers.h"
#include "Layers.h"
#include "rendering/tools/zone.h"
#include "rendering/tools/lighting.h"
#include "rendering/terrain/public.h"

View file

@ -7,7 +7,7 @@
#include "../tools/curve.h"
#include "../tools/euclid.h"
#include "../noise.h"
#include "../layers.h"
#include "Layers.h"
#ifdef __cplusplus
extern "C" {

View file

@ -58,6 +58,14 @@ void PackStream::write(char* value, int max_length)
}
}
void PackStream::write(QString value)
{
if (stream)
{
*stream << value;
}
}
void PackStream::read(int* value)
{
if (stream and value and not stream->atEnd())
@ -89,6 +97,20 @@ void PackStream::read(char* value, int max_length)
}
}
QString PackStream::readString()
{
if (stream and not stream->atEnd())
{
QString output;
*stream >> output;
return output;
}
else
{
return QString();
}
}
// Transitional C-API
PackStream* packReadFile(const char* filepath)

View file

@ -5,6 +5,7 @@
#ifdef __cplusplus
#include <QString>
class QFile;
class QDataStream;
@ -27,10 +28,12 @@ public:
void write(int* value);
void write(double* value);
void write(char* value, int max_length);
void write(QString value);
void read(int* value);
void read(double* value);
void read(char* value, int max_length);
QString readString();
private:
QFile* file;