Commit 25314c48 authored by Leander Schulten's avatar Leander Schulten
Browse files

new development step

parent 684b7857
......@@ -43,14 +43,15 @@ SOURCES += \
programmprototype.cpp \
programms/dmxconsumer.cpp \
programms/loopprogramm.cpp \
programms/property.cpp \
test/testloopprogramm.cpp \
settings.cpp \
syncservice.cpp \
test/DriverDummy.cpp \
usermanagment.cpp \
programms/modulemanager.cpp \
programms/programblock.cpp
programms/programblock.cpp \
programms/compiler.cpp \
test/testmodulsystem.cpp
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
......@@ -95,17 +96,19 @@ HEADERS += \
colorplot.h \
graph.h \
oscillogram.h \
programms/programm.h \
programms/filter.h \
programms/types.h \
programms/property.h \
programms/loopprogramm.h \
programms/dmxconsumer.h \
programms/consumer.h \
programms/module.h \
test/testloopprogramm.h \
programms/modulemanager.h \
programms/programblock.h
programms/programblock.h \
programms/property.hpp \
programms/programm.hpp \
programms/filter.hpp \
programms/consumer.hpp \
programms/compiler.h \
test/testmodulsystem.h
# Default rules for deployment.
......
......@@ -32,10 +32,13 @@
#include <QDir>
#include "driver.h"
#include "test/testloopprogramm.h"
#include "test/testmodulsystem.h"
int main(int argc, char *argv[])
{
Test::TestModulSystem testModulSystem;
testModulSystem.runTest();
return 0;
class CatchingErrorApplication : public QGuiApplication{
public:
......@@ -159,6 +162,9 @@ int main(int argc, char *argv[])
driver.start();*/
#endif
QLibrary l("/Users/leanderSchulten/Lichtsteuerung/programms/test");
qDebug() << "loaded : " << l.load();
qDebug() << l.isLibrary("/Users/leanderSchulten/Lichtsteuerung/programms/test");
//ControlPanel::getLastCreated()->addDimmerGroupControl();
return app.exec();
......
#include "compiler.h"
#include <QTemporaryFile>
#include <QTextStream>
#include <QProcess>
#include <QDebug>
namespace Modules{
QString Compiler::compilerCmd = "g++";
QString Compiler::compilerLibraryFlags = "-shared -fPIC";
QString Compiler::compilerFlags = "-std=c++14 -O3";
Compiler::Compiler()
{
}
int Compiler::compileToLibrary(const QFile &file,const QString &newLibraryFile){
QProcess p;
#ifdef Q_OS_MAC
p.setEnvironment(QProcess::systemEnvironment()<<"PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/Library/TeX/texbin:/usr/local/MacGPG2/bin:/usr/local/share/dotnet:/opt/X11/bin:/Library/Frameworks/Mono.framework/Versions/Current/Commands");
p.start("bash", QStringList() << "-c" << compilerCmd + " "+ compilerLibraryFlags + " " + compilerFlags + " " + file.fileName() + " -o " + newLibraryFile);
#elif defined(Q_OS_WIN)
#error Not Implemented
#endif
p.waitForFinished();
return p.exitCode();
}
int Compiler::compileToLibrary(const QString &code, const QString &newLibraryFile){
QTemporaryFile file;
file.open();
{
QTextStream out(&file);
out << code;
}
file.close();
return compileToLibrary(file,newLibraryFile);
}
}
#ifndef COMPILER_H
#define COMPILER_H
#include <QFile>
namespace Modules {
class Compiler
{
static QString compilerCmd;
static QString compilerLibraryFlags;
static QString compilerFlags;
public:
Compiler();
static void setCompilerCommand(QString s){compilerCmd = s;}
static int compileToLibrary(const QFile &file,const QString &newLibraryFile);
static int compileToLibrary(const QString &code,const QString &newLibraryFile);
};
}
#endif // COMPILER_H
#ifndef COMSUMER_H
#define COMSUMER_H
#include "types.h"
namespace Modules{
class Consumer{
public:
virtual ValueType getInputValueType()=0;
virtual void setInputSize(unsigned int)=0;
virtual void start()=0;
virtual void show(void * data) = 0;
virtual ~Consumer() = default;
};
}
#endif // COMSUMER_H
#ifndef COMSUMER_H
#define COMSUMER_H
#include "types.h"
namespace Modules{
/**
* @brief The Consumer class represents a Consumer like a driver for dmx or leds
* Treiber erben von dieser Klasse und zeigen die Entsprechenden Daten an.
*/
class Consumer:public InputDataConsumer{
public:
Consumer(const ValueType inputDataType):InputDataConsumer(inputDataType){}
virtual void setInputLength(unsigned int)=0;
virtual void start()=0;
/**
* @brief show zeigt die eingabedaten an
*/
virtual void show() = 0;
virtual void doStep(time_diff_t diff)=0;
virtual ~Consumer() = default;
};
template<typename Type>
class TypedConsumer : public Consumer{
protected:
Type * input = nullptr;
unsigned int inputLength = 0;
public:
TypedConsumer():Consumer(typeToEnum<Type>()){}
virtual void setInputData(void * data, unsigned int index, unsigned int length)override{
if(index<inputLength){
const auto l = index+length>inputLength?inputLength-index:length;
std::memcpy(input+index,data,l*sizeof (Type));
}
}
virtual void setInputLength(unsigned int length)override{
if(inputLength!=length){
delete [] input;
inputLength = length;
input = new Type[inputLength];
}
}
virtual unsigned int getInputLength()const override final{return inputLength;}
};
}
#endif // COMSUMER_H
......@@ -7,14 +7,15 @@ namespace Modules {
}
void DMXConsumer::setInputSize(unsigned int size){
void DMXConsumer::setInputLength(unsigned int size){
channel.resize(size,-1);
TypedConsumer::setInputLength(size);
}
void DMXConsumer::start(){}
void DMXConsumer::show(void * data){
brightness_t * b = static_cast<brightness_t*>(data);
void DMXConsumer::show(){
brightness_t * b = input;
for(auto i = channel.cbegin();i!=channel.cend();++i,++b){
if(*i>0){
//dmxData[*i] = *b;
......
#ifndef DMXCONSUMER_H
#define DMXCONSUMER_H
#include "consumer.h"
#include "consumer.hpp"
#include <vector>
namespace Modules {
class DMXConsumer : public Modules::Consumer
class DMXConsumer : public Modules::TypedConsumer<brightness_t>
{
std::vector<short> channel;
public:
DMXConsumer();
virtual ValueType getInputValueType()override{return Brightness;}
virtual void setInputSize(unsigned int) override;
virtual void setInputLength(unsigned int) override;
virtual void start()override;
virtual void show(void * data) override;
virtual void show() override;
const std::vector<short> & getChannelAssoziatfion()const{return channel;}
};
......
#ifndef FILTER_H
#define FILTER_H
#include "types.h"
namespace Modules {
class Filter : public PropertyBase{
public:
void setInputLength(int length);
int getOutputLength();
ValueType getInputType();
ValueType getOutputType();
void filter(void * inputData, void * outputData);
};
}
#endif // FILTER_H
#ifndef FILTER_H
#define FILTER_H
#include "types.h"
#include <cstring>
namespace Modules {
/**
* @brief The Filter class filters input data and write the filtered data in the outpur array
*/
class Filter : public PropertyBase, public OutputDataProducer, public InputDataConsumer{
public:
Filter(const ValueType inputDataType,const ValueType outputDataType):OutputDataProducer(outputDataType),InputDataConsumer(inputDataType){}
virtual void setInputLength(unsigned int length) = 0;
/**
* @brief filter override this method to filter the input data and write it to the output data
*/
virtual void filter() = 0;
/**
* @brief doStep you can modify the output data to create spezial effects like fade outs
* @return true if the output data changed
*/
virtual bool doStep(time_diff_t){return false;}
virtual ~Filter() = default;
};
template<typename InputType,typename OutputType>
class TypedFilter : public Filter{
protected:
InputType * input = nullptr;
OutputType * output = nullptr;
unsigned int inputLength = 0;
unsigned int outputLength = 0;
protected:
virtual unsigned int computeOutputLength(unsigned int inputLength) = 0;
public:
TypedFilter():Filter(typeToEnum<InputType>(),typeToEnum<OutputType>()){}
virtual unsigned int getInputLength()const final override{return inputLength;}
virtual unsigned int getOutputLength()const final override{return outputLength;}
virtual void * getOutputData()final override{return output;}
virtual void setInputData(void*data, unsigned int index, unsigned int length)final override{
if(index<inputLength){
const auto l = index+length>inputLength?inputLength-index:length;
std::memcpy(input+index,data,l * sizeof (InputType));
}
}
virtual void setInputLength(unsigned length)final override{
if(inputLength!=length){
inputLength = length;
delete [] input;
input = new InputType[inputLength];
auto newOutputLength = computeOutputLength(inputLength);
if(newOutputLength!=outputLength){
delete [] output;
outputLength = newOutputLength;
output = new OutputType[outputLength];
}
}
}
};
}
#endif // FILTER_H
#ifndef LOOPPROGRAMM_H
#define LOOPPROGRAMM_H
#include "programm.h"
#include "programm.hpp"
#include "types.h"
#include "boost/coroutine2/all.hpp"
#include <qdebug.h>
......@@ -41,6 +41,7 @@ class LoopProgramm : public BaseClass
bool first=true;
bool finished = false;
bool show_=false;
time_diff_t currentWaitTime = 0;
time_diff_t timeToWait = 0;
static_assert (std::is_base_of<Programm,BaseClass>::value,"BaseClass must be an Subclass of Programm or the clas Programm.");
......@@ -58,19 +59,19 @@ public:
loopProgramm();
finished = true;}){}
virtual ~LoopProgramm(){}
virtual bool doStep(time_diff_t t)override{
virtual ProgrammState doStep(time_diff_t t)override{
if(first){
first = false;
}
if(finished)
return true;
return {true,false};
currentWaitTime+=t;
if(currentWaitTime>=timeToWait){
currentWaitTime = 0;
coro();
return finished;
return {finished,true};
}
return false;
return {false,false};
}
};
......
......@@ -2,36 +2,42 @@
#define MODULE_GLOBAL_H
// define one of the following if your module have the type
#define HAVE_PROGRAM
#define HAVE_LOOP_PROGRAMM
#define HAVE_FILTER
#define HAVE_CONSUMER
//#define HAVE_PROGRAM
//#define HAVE_LOOP_PROGRAMM
//#define HAVE_FILTER
//#define HAVE_CONSUMER
#ifdef HAVE_PROGRAM
#include "programm.h"
#include "programm.hpp"
#endif
#ifdef HAVE_FILTER
#include "filter.h"
#include "filter.hpp"
#endif
#ifdef HAVE_CONSUMER
#include "consumer.h"
#include "consumer.hpp"
#endif
#include <string>
//disable Warning for char * as return type in extern "C" Block with clang
//#pragma GCC diagnostic ignored "-Wreturn-type-c-linkage"
#if defined(MODULE_LIBRARY)
# define MODULE_EXPORT __declspec(dllexport)
#if defined(__APPLE__) || defined(__linux__)
#define MODULE_EXPORT
#else
# define MODULE_EXPORT __declspec(dllimport)
#if defined(MODULE_LIBRARY)
# define MODULE_EXPORT __declspec(dllexport)
#else
# define MODULE_EXPORT __declspec(dllimport)
#endif
#endif
extern "C" {
enum MODUL_TYPE{Programm, LoopProgramm,Filter,Consumer};
inline MODULE_EXPORT bool have(MODUL_TYPE t){
MODULE_EXPORT bool have(MODUL_TYPE t){
switch (t) {
case Programm:
#ifdef HAVE_PROGRAM
......@@ -58,26 +64,27 @@ inline MODULE_EXPORT bool have(MODUL_TYPE t){
return false;
#endif
}
return false; // Vielleicht wird das enum in einer weiteren Version erweitert.
}
#ifdef HAVE_PROGRAM
MODULE_EXPORT unsigned int getNumberOfProgramms();
MODULE_EXPORT std::string getNameOfProgramm(unsigned int index);
MODULE_EXPORT char const * getNameOfProgramm(unsigned int index);
MODULE_EXPORT Modules::Programm * createProgramm(unsigned int index);
MODULE_EXPORT std::string getDescriptionOfProgramm(unsigned int index);
MODULE_EXPORT char const * getDescriptionOfProgramm(unsigned int index);
#endif
#ifdef HAVE_FILTER
MODULE_EXPORT unsigned int getNumberOfFilter();
MODULE_EXPORT std::string getNameOfFilter(unsigned int index);
MODULE_EXPORT std::string getDescriptionOfFilter(unsigned int index);
MODULE_EXPORT char const * getNameOfFilter(unsigned int index);
MODULE_EXPORT char const * getDescriptionOfFilter(unsigned int index);
MODULE_EXPORT Modules::Filter * createFilter(unsigned int index);
#endif
#ifdef HAVE_CONSUMER
MODULE_EXPORT unsigned int getNumberOfComsumer();
MODULE_EXPORT std::string getNameOfConsumer(unsigned int index);
MODULE_EXPORT std::string getDescriptionOfConsumer(unsigned int index);
MODULE_EXPORT char const * getNameOfConsumer(unsigned int index);
MODULE_EXPORT char const * getDescriptionOfConsumer(unsigned int index);
MODULE_EXPORT Modules::Consumer * createConsumer(unsigned int index);
#endif
......
#include "modulemanager.h"
#include <QLibrary>
#include "module.h"
#include <QDebug>
namespace Modules {
......@@ -21,8 +22,10 @@ typedef Modules::Programm* (*CreateProgramm)(unsigned int index);
QLibrary lib(name);
if(lib.load()){
Have_Func f = reinterpret_cast<Have_Func>(lib.resolve("have"));
if(!f)
if(!f){
qDebug()<<"have funktion is missing";
return;
}
if(f(MODUL_TYPE::Programm)){
loadType(lib,programms,"Programm");
}if(f(MODUL_TYPE::LoopProgramm)){
......@@ -32,6 +35,8 @@ typedef Modules::Programm* (*CreateProgramm)(unsigned int index);
}if(f(MODUL_TYPE::Consumer)){
loadType(lib,consumer,"Consumer");
}
}else{
qDebug()<<"Cant load lib :" << name;
}
}
......
......@@ -3,15 +3,16 @@
#include <vector>
#include <functional>
#include "programm.h"
#include "filter.h"
#include "consumer.h"
#include "programm.hpp"
#include "filter.hpp"
#include "consumer.hpp"
#include <cstring>
#include <QString>
#include <QFile>
#include <QDir>
#include <QLibrary>
#include <iostream>
namespace Modules {
......@@ -47,6 +48,7 @@ namespace Modules {
static void loadType(QLibrary & lib, std::vector<detail::Entry<Type>> &c,String name);
public:
ModuleManager();
static ModuleManager * singletone(){static ModuleManager m;return &m;}
void loadModule(QString name);
void loadAllModulesInDir(QDir name);
const ProgrammModulContainer & getProgrammModules(){return programms;}
......@@ -67,15 +69,15 @@ namespace Modules {
};
typedef unsigned int (*GetNumberOfXXX)();
typedef std::string (*GetNameOfXXX)(unsigned int index);
typedef std::string (*GetDescriptionOfXXX)(unsigned int index);
typedef char const * (*GetNameOfXXX)(unsigned int index);
typedef char const * (*GetDescriptionOfXXX)(unsigned int index);
template<typename Type, typename String >
void ModuleManager::loadType(QLibrary & lib, std::vector<detail::Entry<Type>> &c , String Typename){
const auto getNumberOfName = std::string("getNumberOf") + Typename;
const auto getNameOfName = std::string("getNameOf") + Typename;
const auto getDescriptionOfName = std::string("getDescriptionO") + Typename;
const auto getDescriptionOfName = std::string("getDescriptionOf") + Typename;
const auto createName = std::string("create") + Typename;
GetNumberOfXXX getNumberOfProgramms = reinterpret_cast<GetNumberOfXXX>(lib.resolve(getNumberOfName.c_str()));
......@@ -83,6 +85,7 @@ namespace Modules {
GetDescriptionOfXXX getDescriptionOfProgramm = reinterpret_cast<GetDescriptionOfXXX>(lib.resolve(getDescriptionOfName.c_str()));
Type* (*createProgramm)(unsigned int) = reinterpret_cast<Type* (*)(unsigned int)>(lib.resolve(createName.c_str()));
if(!getNumberOfProgramms || !getNameOfProgramm || !getDescriptionOfProgramm || !createProgramm){
std::cout << "Functions are missing : " << getNumberOfName <<" : " <<getNumberOfProgramms << " , " <<getNameOfName<<" : " <<getNameOfProgramm<<" , " <<getDescriptionOfName<<" : " <<getDescriptionOfProgramm<<" , " <<createName<<" : " <<createProgramm;
return;
}
for(unsigned int i = 0 ; i < getNumberOfProgramms();++i){
......
#include "programblock.h"
#include <QJsonArray>
namespace Modules {
namespace detail {
}
ProgramBlock::ProgramBlock()
{
}
ProgramBlock::ProgramBlock(const QJsonObject& o){
QJsonArray a;
/*for(const auto & i : programs){
a.push_back(i->get)
}*/
//TODO
}
bool ProgramBlock::doStep(time_diff_t diff){
bool finished = false;
for(auto & p : programs){
const auto state = p->doStep(diff);
finished |= state.finished;
dataChanged[p] = state.outputDataChanged;
}
for(auto i = filter.cbegin(); i!= filter.cend();++i){
if(doConnection(i->second)){
static_cast<Filter*>(i->second.source)->filter();
}
dataChanged[i->second.source] |= static_cast<Filter*>(i->second.source)->doStep(diff);
}
for(auto i = consumer.cbegin(); i != consumer.cend();++i){
if(doConnection(*i)){
static_cast<Consumer*>(i->source)->show();
}
}
return finished;
}
}
#ifndef PROGRAMBLOCK_H
#define PROGRAMBLOCK_H
#include "programm.h"
#include "filter.h"
#include "consumer.h"
#include "programm.hpp"
#include "filter.hpp"
#include "consumer.hpp"
#include <stdexcept>
#include <map>
#include <QJsonObject>
namespace Modules {
namespace detail{
class Range{
unsigned int startIndex, endIndex;