Commit 4010d5e1 authored by Leander Schulten's avatar Leander Schulten
Browse files

Add Documentation and develop property load save system

parent 32d0ade1
......@@ -20,7 +20,17 @@ namespace Modules{
*/
virtual void show() = 0;
virtual void doStep(time_diff_t diff)=0;
virtual ~Consumer() = default;
virtual ~Consumer()override = default;
virtual void load(const LoadObject &l)override{
PropertyBase::load(l);
int length = l.loadInt("inputLength");
if(length>0)
setInputLength(static_cast<unsigned>(length));
}
virtual void save(SaveObject &s) const override{
PropertyBase::save(s);
s.saveInt("inputLength",static_cast<int>(getInputLength()));
}
};
template<typename Type>
......
......@@ -6,6 +6,9 @@
namespace Modules {
/**
* @brief The Controller class controlls the whole Module system. Its load and execute it
*/
class Controller
{
std::atomic_bool run_;
......
......@@ -22,7 +22,17 @@ namespace Modules {
* @return true if the output data changed
*/
virtual bool doStep(time_diff_t){return false;}
virtual ~Filter() = default;
virtual void load(const LoadObject &l)override{
PropertyBase::load(l);
int length = l.loadInt("inputLength");
if(length>0)
setInputLength(static_cast<unsigned>(length));
}
virtual void save(SaveObject &s) const override{
PropertyBase::save(s);
s.saveInt("inputLength",static_cast<int>(getInputLength()));
}
virtual ~Filter() override = default;
};
template<typename InputType,typename OutputType>
......
......@@ -7,6 +7,9 @@
namespace Modules {
/**
* @brief The JsonLoadObject class is a wrapper around a QJsonObject that implements the LoadObject interface
*/
class JsonLoadObject : public LoadObject
{
const QJsonObject &o;
......@@ -16,7 +19,7 @@ namespace Modules {
virtual float loadFloat(const char*name) const override {return static_cast<float>(o[name].toDouble());}
virtual double loadDouble(const char*name) const override{return o[name].toDouble();}
virtual bool loadBool(const char*name) const override{return o[name].toBool();}
virtual long loadLong(const char*name) const override{return static_cast<float>(o[name].toDouble());}
virtual long loadLong(const char*name) const override{return static_cast<long>(o[name].toDouble());}
virtual char* loadStringOwn(const char*name) const override{
const auto data = o[name].toString().toLatin1();
char * d = new char[data.size()+1];
......@@ -25,6 +28,9 @@ namespace Modules {
}
};
/**
* @brief The JsonSaveObject class is a wrapper around a QJsonObject that implements the SaveObject interface
*/
class JsonSaveObject : public SaveObject{
QJsonObject &o;
public:
......@@ -33,7 +39,7 @@ namespace Modules {
o[name] = i;
}
virtual void saveFloat(const char*name,float f) override{
o[name] = f;
o[name] = static_cast<double>(f);
}
virtual void saveDouble(const char*name,double d) override{
o[name] = d;
......
......@@ -35,6 +35,9 @@ namespace Modules {
};
}
/**
* @brief The ModuleManager class load Modules and register them. You con load a Programm/Filter/Consumer by Name from an loaded Module
*/
class ModuleManager
{
typedef std::vector<detail::Entry<Programm>> ProgrammModulContainer;
......
......@@ -2,6 +2,7 @@
#include <QJsonArray>
#include <stdexcept>
#include "modulemanager.h"
#include "json_storage.h"
namespace Modules {
......@@ -31,6 +32,13 @@ namespace Modules {
}
template<typename T>
void loadProperties(const QJsonObject &o, T*t){
const auto prop = o["properties"].toObject();
JsonLoadObject lo(prop);
t->load(lo);
}
ProgramBlock::ProgramBlock(const QJsonObject& o){
// Wir erstellen erstmal alle objecte mit passendem Typ und ID
std::map<QString,std::shared_ptr<Programm>> programs;
......@@ -46,6 +54,7 @@ namespace Modules {
if(!p){
throw std::runtime_error(std::string("Program with name '") + str + "' does not exist.");
}
loadProperties(obj,p.get());
programs.insert(std::make_pair(qstr,p));
}
}
......@@ -59,6 +68,7 @@ namespace Modules {
if(!p){
throw std::runtime_error(std::string("Filter with name '") + str + "' does not exist.");
}
loadProperties(obj,p.get());
filter.insert(std::make_pair(qstr,p));
}
}
......@@ -72,6 +82,7 @@ namespace Modules {
if(!p){
throw std::runtime_error(std::string("Consumer with name '") + str + "' does not exist.");
}
loadProperties(obj,p.get());
consumer.insert(std::make_pair(qstr,p));
}
}
......@@ -140,6 +151,7 @@ namespace Modules {
throw std::runtime_error("one outputdataproducer is unknown");
}
}
assert(c.sourceType == detail::Connection::Filter);
filter.emplace(layer,std::move(c));
}
......@@ -149,6 +161,7 @@ namespace Modules {
throw std::runtime_error("one outputdataproducer is unknown");
}
}
assert(c.sourceType == detail::Connection::Consumer);
consumer.push_back(std::move(c));
}
......@@ -174,6 +187,13 @@ namespace Modules {
return finished;
}
template<typename Type>
void saveProperties(QJsonObject &o, Type * p){
QJsonObject prop;
JsonSaveObject jo(prop);
p->save(jo);
o["properties"] = prop;
}
void ProgramBlock::writeJsonObject(QJsonObject &o){
// Wir speichern zu jedem Programm/Filter/Consumer ein Object ab, das den Typnamen und eine ID, wir nehmen die Adresse im Arbeitsspeicher.
......@@ -184,6 +204,7 @@ namespace Modules {
QJsonObject p;
p["typename"] = (*i)->getName();
p["id"] = QString::number(reinterpret_cast<size_t>(i->get()));
saveProperties(p,i->get());
static_assert (sizeof (size_t) == sizeof (Programm*), "Pointer must have same size as size_t");
progs.push_back(p);
}
......@@ -199,6 +220,7 @@ namespace Modules {
con["source"] = QString::number(reinterpret_cast<size_t>(i.second.source.get()));
e["typename"] = reinterpret_cast<Named*>(i.second.source.get())->getName();
e["id"] = QString::number(reinterpret_cast<size_t>(i.second.source.get()));
saveProperties(e,static_cast<Filter*>(i.second.source.get()));
con["level"] = i.first;
static_assert (sizeof (size_t) == sizeof (Filter*), "Pointer must have same size as size_t");
filter.push_back(e);
......@@ -225,11 +247,7 @@ namespace Modules {
con["source"] = QString::number(reinterpret_cast<size_t>(i.source.get()));
e["typename"] = reinterpret_cast<Named*>(i.source.get())->getName();
e["id"] = QString::number(reinterpret_cast<size_t>(i.source.get()));
{
QJsonObject prop;
// TODO save properties of object
//e["properties"] =
}
saveProperties(e,static_cast<Consumer*>(i.source.get()));
static_assert (sizeof (size_t) == sizeof (Filter*), "Pointer must have same size as size_t");
consumer.push_back(e);
QJsonArray targets;
......
......@@ -21,8 +21,18 @@ namespace Modules {
unsigned int startIndex;
};
typedef unsigned int length_t;
const enum SourceType {Filter,Consumer} sourceType;
std::shared_ptr<InputDataConsumer> source;
Connection(std::shared_ptr<InputDataConsumer> source):source(source){}
template<typename Type>
Connection(std::shared_ptr<Type> source):source(source){
static_assert (std::is_base_of<InputDataConsumer,Type>::value,"Der Typ ist keine Subklasse eines InputDataConsumer.");
static_assert (std::is_base_of<Modules::Filter,Type>::value||std::is_base_of<Modules::Consumer,Type>::value,"Der Typ ist Filter oder Consumer.");
if(std::is_base_of<Modules::Filter,Type>::value){
*const_cast<SourceType*>(&sourceType) = Filter;
}else{
*const_cast<SourceType*>(&sourceType) = Consumer;
}
}
Connection(const QJsonObject &o);
/**
* @brief addTarget add a target for a range in the InputDataConsumer
......
......@@ -28,7 +28,17 @@ public:
virtual void setOutputLength(unsigned int length)=0;
virtual void start() = 0;
virtual ProgrammState doStep(time_diff_t) = 0;
virtual ~Programm(){}
virtual ~Programm() override = default;
virtual void load(const LoadObject &l)override{
PropertyBase::load(l);
int length = l.loadInt("outputLength");
if(length>0)
setOutputLength(static_cast<unsigned>(length));
}
virtual void save(SaveObject &s) const override{
PropertyBase::save(s);
s.saveInt("outputLength",static_cast<int>(getOutputLength()));
}
};
template<typename value_type_t>
......
......@@ -13,6 +13,9 @@ namespace Modules {
class StringProperty;
/**
* @brief The Property class holds a property. A Property have a name and a description.
*/
class Property : public Serilerizeable
{
protected:
......@@ -38,18 +41,9 @@ namespace Modules {
return description;
}
NumericProperty<int> * asInt(){
if(type == Int){
return reinterpret_cast<NumericProperty<int>*>(this);
}
return nullptr;
}
NumericProperty<float> * asFloat(){
if(type == Int){
return reinterpret_cast<NumericProperty<float>*>(this);
}
return nullptr;
}
template<typename T>
NumericProperty<T> * asNumeric();
StringProperty * asString(){
if(type == String){
return reinterpret_cast<StringProperty*>(this);
......@@ -62,7 +56,7 @@ namespace Modules {
template<typename t>
Property::Type toEnum(){
static_assert (std::is_same<t,float>::value||std::is_same<t,int>::value||std::is_same<t,long>::value||std::is_same<t,double>::value||std::is_same<t,bool>::value,"Wrong Type. Con be only int or float");
static_assert (std::is_same<t,float>::value||std::is_same<t,int>::value||std::is_same<t,long>::value||std::is_same<t,double>::value||std::is_same<t,bool>::value,"Wrong Type. Con be only int float long double bool std::string");
if(std::is_same<t,int>::value){
return Property::Int;
}else if(std::is_same<t,long>::value){
......@@ -71,15 +65,25 @@ namespace Modules {
return Property::Float;
}else if(std::is_same<t,double>::value){
return Property::Double;
}else if(std::is_same<t,std::string>::value){
return Property::String;
}else {
return Property::Bool;
}
}
}
template<typename T>
NumericProperty<T> * Property::asNumeric(){
if(type == defail::toEnum<T>()){
return reinterpret_cast<NumericProperty<T>*>(this);
}
return nullptr;
}
template<typename Type_t>
class NumericProperty : public Property{
static_assert (std::is_same<Type_t,float>::value||std::is_same<Type_t,int>::value,"Wrong Type. Con be only int or float");
static_assert (std::is_same<Type_t,float>::value||std::is_same<Type_t,int>::value||std::is_same<Type_t,long>::value||std::is_same<Type_t,double>::value,"Wrong Type. Con only be signed numeric");
Type_t min;
Type_t max;
Type_t value;
......@@ -158,9 +162,31 @@ namespace Modules {
this->value = value;
return true;
}
std::string getString()const{return value;}
virtual ~StringProperty() = default;
};
class BoolProperty : public Property{
protected:
bool value;
public:
BoolProperty(bool value):Property(Property::Bool),value(value){}
void save(SaveObject &o)const override{
o.saveBool(name.c_str(),value);
}
void load(const LoadObject &l)override{
value = l.loadBool(name.c_str());
}
void setValue(bool value){
this->value = value;
}
bool getValue()const{
return value;
}
};
}
#endif // VARIABLE_H
......@@ -3,6 +3,9 @@
namespace Modules {
/**
* @brief The SaveObject interface defines Methods to save Primitive data
*/
class SaveObject
{
public:
......@@ -14,6 +17,9 @@ public:
virtual void saveString(const char*name,const char * c) = 0;
};
/**
* @brief The LoadObject interface defines methods to load Primitive data
*/
class LoadObject
{
public:
......@@ -22,9 +28,17 @@ public:
virtual double loadDouble(const char*name) const = 0;
virtual bool loadBool(const char*name) const = 0;
virtual long loadLong(const char*name) const = 0;
/**
* @brief loadStringOwn loads a string, the caller own the string and have to delete it
* @param name the name of the property
* @return the string or a nullptr if the property does not exist
*/
virtual char* loadStringOwn(const char*name) const = 0;
};
/**
* @brief A Superclass for objects that can be load and stored
*/
class Serilerizeable{
public:
virtual void save(SaveObject &s)const=0;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment