Commit 9ab45081 authored by Leander Schulten's avatar Leander Schulten
Browse files

Extract the Name and Description property in a NamedObject class.

Adding Support for QObject
parent 5a95d1f0
......@@ -16,7 +16,8 @@ SOURCES += main.cpp \
device.cpp \
programmprototype.cpp \
programm.cpp \
applicationdata.cpp
applicationdata.cpp \
namedobject.cpp
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
......@@ -37,4 +38,5 @@ HEADERS += \
idbase.h \
programmprototype.h \
programm.h \
applicationdata.h
applicationdata.h \
namedobject.h
#include "channel.h"
Channel::Channel(const QJsonObject &o):IDBase(o),index(o["index"].toInt()),name(o["name"].toString()),description(o["description"].toString()){}
Channel::Channel(const QJsonObject &o):NamedObject(o),IDBase<Channel>(o),index(o["index"].toInt()){}
void Channel::writeJsonObject(QJsonObject &o) const{
IDBase::writeJsonObject(o);
NamedObject::writeJsonObject(o);
IDBase<Channel>::writeJsonObject(o);
o.insert("index",index);
o.insert("name",name);
o.insert("description",description);
}
......@@ -2,41 +2,30 @@
#define CHANNEL_H
#include <QString>
#include "idbase.h"
#include "namedobject.h"
/**
* @brief The Channel class give us information about a channel in a devicePrototype
* Eine Klasse die die jeweiligen ChannelInformationen für ein deviecPrototype hält
*/
class Channel : public IDBase<Channel>
class Channel : public NamedObject, public IDBase<Channel>
{
Q_OBJECT
Q_PROPERTY(int index READ getIndex)
private:
/**
* @brief index Der DMX Index (Offset) von der späteren tatsächlichen start Adresse eines bestimmten Geräts
*/
int index;
/**
* @brief name Der Name des Channels, zb Red, Green, Blue, Speed, Programm, ...
*/
QString name;
/**
* @brief description Eine Beschreibung des Channels, zb um deutlich zu machen, was er macht
*/
QString description;
friend class DevicePrototype;
public:
Channel(int index, QString name = "Unknown", QString description=""):index(index),name(name),description(description){}
Channel(int index, QString name = "Unknown", QString description=""):NamedObject(name,description),index(index){}
Channel(const QJsonObject &o);
int getIndex()const{return index;}
QString getName()const{return name;}
void setName(const QString &newName){name = newName;}
void setDescription(const QString &newDescription){name = newDescription;}
QString getDescription()const{return description;}
void writeJsonObject(QJsonObject &o)const;
};
#endif // CHANNEL_H
#include "device.h"
Device::Device(const QJsonObject &o):IDBase(o),
Device::Device(const QJsonObject &o):NamedObject(o),IDBase<Device>(o),
prototype(IDBase<DevicePrototype>::getIDBaseObjectByID(o["prototype"].toString().toLong())),
name(o["name"].toString()),
desciption(o["description"].toString()),
position(o["position"].toObject()["x"].toInt(),o["position"].toObject()["y"].toInt()),
startDMXChannel(o["startDMXChannel"].toInt()){
startDMXChannel(o["startDMXChannel"].toInt()),
position(o["position"].toObject()["x"].toInt(),o["position"].toObject()["y"].toInt()){
}
void Device::writeJsonObject(QJsonObject &o) const{
IDBase::writeJsonObject(o);
NamedObject::writeJsonObject(o);
IDBase<Device>::writeJsonObject(o);
o.insert("prototype",prototype?QString::number(prototype->getID().value()):0);
o.insert("name",name);
o.insert("desciption",desciption);
QJsonObject position;
position.insert("x",this->position.x());
position.insert("y",this->position.y());
......
......@@ -3,41 +3,49 @@
#include "deviceprototype.h"
#include "QPoint"
#include "idbase.h"
#include "namedobject.h"
/**
* @brief The Device class Ein "echtes" Gerät, zb der Laser oben rechts über der Bier Theke
*/
class Device : public IDBase<Device>
class Device : public NamedObject, public IDBase<Device>
{
protected:
Q_OBJECT
Q_PROPERTY(DevicePrototype * prototype READ getPrototype CONSTANT)
Q_PROPERTY(int startDMXChannel READ getStartDMXChannel WRITE setStartDMXChannel NOTIFY startDMXChannelChanged)
Q_PROPERTY(QPoint position READ getPosition WRITE setPosition NOTIFY positionChanged)
public:
/**
* @brief prototype Ein Pointer auf den Typ/Prototype, von dem das Gerät ist. (Ist es eine Lamp, ein Laser, .. ?)
*/
DevicePrototype * prototype;
/**
* @brief name Der Name des Geräts
*/
QString name;
const DevicePrototype * prototype;
DevicePrototype * getPrototype()const{return const_cast<DevicePrototype *>(prototype);}
protected:
/**
* @brief desciption Eine beschreibung des Geräts
* @brief startDMXChannel Der Start DMX Channel
*/
QString desciption;
int startDMXChannel;
/**
* @brief position Die Position des Geräts, es wird eine Karte geben, wo dann dieses Gerät mit diese Position eingezeichnet wird
*/
QPoint position;
/**
* @brief startDMXChannel Der Start DMX Channel
*/
int startDMXChannel;
public:
Device(const QJsonObject &o);
Device(DevicePrototype * prototype, int startDMXChannel, QString name, QString desciption="",QPoint position = QPoint(-1,-1)):NamedObject(name,desciption),prototype(prototype),startDMXChannel(startDMXChannel),position(position){}
void writeJsonObject(QJsonObject &o)const;
QPoint getPosition()const{return position;}
Q_SLOT void setPosition(const QPoint &p){if(p == position)return;position = p;emit positionChanged(position);}
int getStartDMXChannel()const{return startDMXChannel;}
Q_SLOT void setStartDMXChannel(int newStart){if(newStart == startDMXChannel)return;startDMXChannel = newStart; emit startDMXChannelChanged(startDMXChannel);}
signals:
void startDMXChannelChanged(int newStartDMXChannel);
void positionChanged(const QPoint & newPosition);
};
#endif // DEVICE_H
......@@ -7,6 +7,7 @@ void DevicePrototype::removeChannels(int newMaxIndex){
}
// Elemente ganz hinten löschen
for (int i = 0; i < getNumberOfChannels() - newMaxIndex; ++i) {
delete channels.back();
channels.pop_back();
}
}
......@@ -15,18 +16,18 @@ void DevicePrototype::addChannel(int channel, QString name, QString description)
// dummy Channels einfügen
if (channel>=getNumberOfChannels()) {
for (int i = getNumberOfChannels(); i <= channel; ++i) {
channels.push_back(Channel(i));
channels.push_back(new Channel(i));
}
}
// eigenschaften setzten
channels[channel].name = name;
channels[channel].description = description;
channels[channel]->setName(name);
channels[channel]->setDescription(description);
}
const Channel * DevicePrototype::getChannelById(const int id) const{
for(auto c = channels.cbegin();c!=channels.cend();++c){
if (c->getID().value() == id) {
return &(*c);
if ((**c).getID().value() == id) {
return *c;
}
}
return nullptr;
......@@ -34,8 +35,8 @@ const Channel * DevicePrototype::getChannelById(const int id) const{
const Channel * DevicePrototype::getChannelByName(const QString &name) const{
for(auto c = channels.cbegin();c!=channels.cend();++c){
if (c->name == name) {
return &(*c);
if ((**c).getName() == name) {
return *c;
}
}
return nullptr;
......@@ -45,23 +46,23 @@ const Channel * DevicePrototype::getChannelByIndex(const unsigned int channelInd
if (channelIndex>=channels.size()) {
return nullptr;
}
return &channels[channelIndex];
return channels[channelIndex];
}
DevicePrototype::DevicePrototype(const QJsonObject &o):IDBase(o){
DevicePrototype::DevicePrototype(const QJsonObject &o):NamedObject(o),IDBase(o){
auto array = o["channels"].toArray();
for(const auto c : array){
channels.push_back(Channel(c.toObject()));
channels.push_back(new Channel(c.toObject()));
}
}
void DevicePrototype::writeJsonObject(QJsonObject &o) const{
NamedObject::writeJsonObject(o);
IDBase::writeJsonObject(o);
o.insert("name",name);
QJsonArray channels;
for(const auto c : this->channels){
QJsonObject o;
c.writeJsonObject(o);
c->writeJsonObject(o);
channels.append(o);
}
o.insert("channels",channels);
......
......@@ -10,21 +10,19 @@
/** Jedes Gerät(Scanner/Laser/Lampe/...) bekommt ein Device Prototype, wo festgelegt wird, auf welchem Channel welche Daten anliegen
* @brief The DevicePrototype class
*/
class DevicePrototype : public IDBase<DevicePrototype>
class DevicePrototype : public NamedObject, public IDBase<DevicePrototype>
{
Q_OBJECT
Q_PROPERTY(int numberOfChannels READ getNumberOfChannels NOTIFY numberOfChannelsChanged)
private:
/**
* @brief name Der Name des DevicePrototypen, zb Scanner, Licht, Laser, ...
*/
QString name;
/**
* @brief channels Ein vector die die einzelnen Channel Informationen hält
*/
std::vector<Channel> channels;
std::vector<Channel*> channels;
public:
DevicePrototype(const QJsonObject &o);
DevicePrototype(QString name):name(name){}
int getNumberOfChannels()const{return channels.size()+1;}
DevicePrototype(QString name):NamedObject(name){}
int getNumberOfChannels()const{return channels.size();}
/**
* @brief removeChannels Entfernt Channel bis zu einem bestimmten Index
* @param newMaxIndex Der neue Maximale Index (Inclusiv)
......@@ -42,7 +40,11 @@ public:
const Channel * getChannelById(const int id)const;
const Channel * getChannelByIndex(const unsigned int channelIndex)const;
const std::vector<Channel*> & getChannels()const{return channels;};
void writeJsonObject(QJsonObject &o)const;
signals:
void numberOfChannelsChanged();
};
......
......@@ -61,7 +61,7 @@
private:
static IDBaseSet idBaseObjectsByID;
void removeIDBaseObject(IDBase * c)const{
idBaseObjectsByID.erase(idBaseObjectsByID.find(static_cast<Subclass*>(c)));
idBaseObjectsByID.erase(static_cast<Subclass*>(c));
}
void addIDBaseObject(IDBase * c)const{
idBaseObjectsByID.insert(static_cast<Subclass*>(c));
......
#include "namedobject.h"
#ifndef NAMEDOBJECT_H
#define NAMEDOBJECT_H
#include "idbase.h"
#include <QObject>
class NamedObject : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ getName WRITE setName NOTIFY nameChanged)
Q_PROPERTY(QString description READ getDescription WRITE setDescription NOTIFY descriptionChanged)
private:
/**
* @brief name Der Name des Objects
*/
QString name;
/**
* @brief description Eine Beschreibung des Objects, zb um deutlich zu machen, was es macht
*/
QString description;
public:
//explicit NamedObject(QObject *parent = 0);
NamedObject(QString name, QString description=""):name(name),description(description){}
NamedObject(const QJsonObject &o):name(o["name"].toString()),description(o["description"].toString()){}
Q_SLOT void setName(const QString &n){if(n==name)return;name=n;emit nameChanged(name);}
QString getName()const{return name;}
Q_SLOT void setDescription(const QString &d){if(d==description)return;description=d;emit descriptionChanged(description);}
QString getDescription()const{return description;}
void writeJsonObject(QJsonObject &o) const{
o.insert("name",name);
o.insert("description",description);
}
signals:
void nameChanged(const QString &);
void descriptionChanged(const QString &);
};
#endif // NAMEDOBJECT_H
......@@ -2,27 +2,26 @@
#include <QJsonArray>
Programm::Programm(const QJsonObject &o):IDBase(o),name(o["name"].toString()),description(o["description"].toString())
Programm::Programm(const QJsonObject &o):NamedObject(o),IDBase<Programm>(o)
{
auto array = o["programms"].toArray();
for(const auto r : array){
const auto o = r.toObject();
programms.emplace_back(o["offset"].toDouble(),
IDBase<Device>::getIDBaseObjectByID(o["device"].toString().toLong()),
IDBase<ProgrammPrototype>::getIDBaseObjectByID(o["programmPrototype"].toString().toLong()));
programms.emplace_back(IDBase<Device>::getIDBaseObjectByID(o["device"].toString().toLong()),
IDBase<ProgrammPrototype>::getIDBaseObjectByID(o["programmPrototype"].toString().toLong()),
o["offset"].toDouble());
}
}
void Programm::writeJsonObject(QJsonObject &o) const{
NamedObject::writeJsonObject(o);
IDBase<Programm>::writeJsonObject(o);
o.insert("name",name);
o.insert("description",description);
QJsonArray array;
for(const auto dp : programms){
QJsonObject o;
o.insert("offset",dp.offset);
o.insert("device",QString::number(dp.device->getID().value()));
o.insert("programmPrototype",QString::number(dp.programmPrototype->getID().value()));
o.insert("programmPrototype",QString::number(dp.getProgrammPrototyp()->getID().value()));
array.append(o);
}
o.insert("programms",array);
......@@ -36,7 +35,7 @@ void Programm::fill(unsigned char *data, size_t length, double time){
for(const auto dp : p->programms){
//für jedes Channel Programm
for(const auto cp : dp.programmPrototype->getChannelProgramms()){
for(const auto cp : dp.getProgrammPrototyp()->getChannelProgramms()){
const auto channelNummer = dp.device->getStartDMXChannel() + cp.channel->getIndex();
if(channelNummer<length){
data[channelNummer] = cp.getValueForTime(time + dp.offset);
......@@ -46,3 +45,16 @@ void Programm::fill(unsigned char *data, size_t length, double time){
}
}
}
bool Programm::addDeviceProgramm(Device * device, ProgrammPrototype * programmPrototype, double offset){
if(device->prototype != programmPrototype->devicePrototype){
return false;
}
for(const auto cp : programms){
if(cp.device == device){
return false;
}
}
programms.emplace_back(device, programmPrototype, offset);
return true;
}
......@@ -4,26 +4,41 @@
#include "programmprototype.h"
#include "device.h"
class Programm : public IDBase<Programm>
class Programm : public NamedObject, public IDBase<Programm>
{
QString name;
QString description;
Q_OBJECT
Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged RESET stop)
bool isRunning_ = false;
class DeviceProgramm{
private:
ProgrammPrototype * programmPrototype;
public:
const Device * device;
double offset;
Device * device;
ProgrammPrototype * programmPrototype;
DeviceProgramm(double offset,Device * device,ProgrammPrototype * programmPrototype):offset(offset),device(device),programmPrototype(programmPrototype){}
DeviceProgramm(Device * device,ProgrammPrototype * programmPrototype,double offset):programmPrototype(programmPrototype),device(device),offset(offset){}
bool setProgrammPrototype(ProgrammPrototype * p){
if(p->devicePrototype!=device->prototype){
return false;
}
programmPrototype = p;
return true;
}
ProgrammPrototype * getProgrammPrototyp()const{return programmPrototype;}
};
std::vector<DeviceProgramm> programms;
public:
Programm(const QJsonObject &o);
void run(){isRunning_ = true;}
void stop(){isRunning_ = false;}
Programm(QString name,QString description = ""):NamedObject(name,description){}
Q_SLOT void setRunning(bool run){if(run != isRunning_)emit runningChanged(run);isRunning_ = run;}
void run(){if(!isRunning_)emit runningChanged(true);isRunning_ = true;}
void stop(){if(isRunning_)emit runningChanged(false);isRunning_ = false;}
bool isRunning(){return isRunning_;}
static void fill(unsigned char * data, size_t length, double time);
void writeJsonObject(QJsonObject &o)const;
const std::vector<DeviceProgramm>& getDeviceProgramms()const{return programms;}
bool addDeviceProgramm(Device * device, ProgrammPrototype * programmPrototype, double offset = 0);
signals:
void runningChanged(bool running);
};
#endif // PROGRAMM_H
......@@ -2,6 +2,11 @@
#include <cmath>
#include <QJsonArray>
ProgrammPrototype::ProgrammPrototype(DevicePrototype *devicePrototype, QString name, QString description):NamedObject(name,description),devicePrototype(devicePrototype){
for(const auto channel : devicePrototype->getChannels()){
programm.push_back(ChannelProgramm(channel));
}
}
unsigned char ProgrammPrototype::ChannelProgramm::getValueForTime(double t)const{
......@@ -51,7 +56,7 @@ void ProgrammPrototype::ChannelProgramm::changeTimeOfTimePoint(double time, doub
}
}
void ProgrammPrototype::TimePoint::writeJsonObject(QJsonObject &o) const{
void TimePoint::writeJsonObject(QJsonObject &o) const{
o.insert("time",time);
o.insert("value",value);
o.insert("type",easingCurveToNextPoint.type());
......@@ -74,9 +79,8 @@ void ProgrammPrototype::ChannelProgramm::writeJsonObject(QJsonObject &o) const{
void ProgrammPrototype::writeJsonObject(QJsonObject &o) const{
IDBase<ProgrammPrototype>::writeJsonObject(o);
NamedObject::writeJsonObject(o);
o.insert("devicePrototype",QString::number(devicePrototype->getID().value()));
o.insert("name",name);
o.insert("description",description);
QJsonArray array;
for(const auto p : programm){
QJsonObject o;
......@@ -86,7 +90,7 @@ void ProgrammPrototype::writeJsonObject(QJsonObject &o) const{
o.insert("programm",array);
}
ProgrammPrototype::TimePoint::TimePoint(const QJsonObject &o):time(o["time"].toDouble()),value(o["value"].toInt()),easingCurveToNextPoint(QEasingCurve::Type(o["type"].toInt())){
TimePoint::TimePoint(const QJsonObject &o):time(o["time"].toDouble()),value(o["value"].toInt()),easingCurveToNextPoint(QEasingCurve::Type(o["type"].toInt())){
const auto a = o.find("amplitude");
if(a != o.end()) easingCurveToNextPoint.setAmplitude(a->toDouble());
const auto b = o.find("overshoot");
......@@ -101,11 +105,24 @@ ProgrammPrototype::ChannelProgramm::ChannelProgramm(const QJsonObject &o):channe
}
}
ProgrammPrototype::ProgrammPrototype(const QJsonObject &o):IDBase(o),
devicePrototype(IDBase<DevicePrototype>::getIDBaseObjectByID(o["devicePrototype"])),
name(o["name"].toString()),
description(o["description"].toString()){
ProgrammPrototype::ProgrammPrototype(const QJsonObject &o):NamedObject(o),IDBase<ProgrammPrototype>(o),
devicePrototype(IDBase<DevicePrototype>::getIDBaseObjectByID(o["devicePrototype"])){
for(const auto p : o["programm"].toArray()){
programm.emplace_back(p.toObject());
}
}
ProgrammPrototype::ChannelProgramm * ProgrammPrototype::getChannelProgramm(const Channel * channel){
for(auto p = programm.begin() ; p != programm.end() ;++p){
if(p->channel == channel)
return &*p;
}
return nullptr;
}
ProgrammPrototype::ChannelProgramm * ProgrammPrototype::getChannelProgramm(int index){
for(auto p = programm.begin() ; p != programm.end() ;++p){
if(p->channel->getIndex() == index)
return &*p;
}
return nullptr;
}
......@@ -4,34 +4,38 @@
#include "deviceprototype.h"
#include <QEasingCurve>
class ProgrammPrototype : public IDBase<ProgrammPrototype>
class TimePoint{
public:
TimePoint(const QJsonObject &o);
const double time;
mutable unsigned char value;
mutable QEasingCurve easingCurveToNextPoint;
TimePoint(double time,unsigned char value,QEasingCurve easingCurveToNextPoint):time(time),value(value),easingCurveToNextPoint(easingCurveToNextPoint){}
bool operator < (const TimePoint & o)const{return time < o.time;}
bool operator < (const double& o)const{return time < o;}
friend bool operator < (const double& l, const TimePoint &r){return l < r.time;}
void writeJsonObject(QJsonObject &o)const;
};
class ProgrammPrototype : public NamedObject, public IDBase<ProgrammPrototype>
{
private:
Q_OBJECT
Q_PROPERTY(DevicePrototype* devicePrototype READ getDevicePrototype CONSTANT)
public:
/**
* @brief devicePrototype Für diesen Typ soll das Programm sein.
*/
const DevicePrototype * devicePrototype;
QString name;
QString description;
class TimePoint{
public:
TimePoint(const QJsonObject &o);
const double time;
mutable unsigned char value;
mutable QEasingCurve easingCurveToNextPoint;
TimePoint(double time,unsigned char value,QEasingCurve easingCurveToNextPoint):time(time),value(value),easingCurveToNextPoint(easingCurveToNextPoint){}
bool operator < (const TimePoint & o)const{return time < o.time;}
bool operator < (const double& o)const{return time < o;}
friend bool operator < (const double& l, const TimePoint &r){return l < r.time;}
void writeJsonObject(QJsonObject &o)const;
};
DevicePrototype * getDevicePrototype()const{return const_cast<DevicePrototype *>(devicePrototype);}
public:
enum RepeatPolicy{Continue, Oscillate};
class ChannelProgramm{
public:
ChannelProgramm(const QJsonObject &o);
ChannelProgramm(const Channel * channel):channel(channel){}
const Channel * channel;
RepeatPolicy repeatPolicy;
std::set<TimePoint,std::less<>> timeline;
mutable std::set<TimePoint,std::less<>> timeline;
unsigned char getValueForTime(double t)const;
void changeTimeOfTimePoint(double time, double newTime);
void writeJsonObject(QJsonObject &o)const;
......@@ -39,8 +43,9 @@ private:
std::vector<ChannelProgramm> programm;
public:
ProgrammPrototype(const QJsonObject &o);
ProgrammPrototype(ProgrammPrototype * devicePrototype);
ProgrammPrototype(DevicePrototype * devicePrototype, QString name, QString description="");
ChannelProgramm * getChannelProgramm(const Channel * channel);
ChannelProgramm * getChannelProgramm(int channelIndex);
const std::vector<ChannelProgramm>& getChannelProgramms()const{return programm;}
void writeJsonObject(QJsonObject &o)const;
};
......
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