00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef _GEDDEI_PROCESSOR_H
00012 #define _GEDDEI_PROCESSOR_H
00013
00014 #include <qmutex.h>
00015 #include <qthread.h>
00016 #include <qthreadstorage.h>
00017 #include <qpainter.h>
00018 #include <qstring.h>
00019 #include <qptrlist.h>
00020 #include <qvaluevector.h>
00021
00022 #ifdef __GEDDEI_BUILD
00023 #include "qcleaner.h"
00024 #include "globals.h"
00025 #include "bufferdata.h"
00026 #include "lxconnection.h"
00027 #include "xlconnection.h"
00028 #include "rlconnection.h"
00029 #include "properties.h"
00030 #include "source.h"
00031 #include "sink.h"
00032 #include "multisource.h"
00033 #include "multisink.h"
00034 #include "signaltyperefs.h"
00035 #include "processorport.h"
00036 #else
00037 #include <qtextra/qcleaner.h>
00038 #include <geddei/globals.h>
00039 #include <geddei/bufferdata.h>
00040 #include <geddei/lxconnection.h>
00041 #include <geddei/xlconnection.h>
00042 #include <geddei/rlconnection.h>
00043 #include <geddei/properties.h>
00044 #include <geddei/source.h>
00045 #include <geddei/sink.h>
00046 #include <geddei/multisource.h>
00047 #include <geddei/multisink.h>
00048 #include <geddei/signaltyperefs.h>
00049 #include <geddei/processorport.h>
00050 #endif
00051 using namespace Geddei;
00052
00053 namespace Geddei
00054 {
00055
00056 class DomProcessor;
00057 class Buffer;
00058 class ProcessorGroup;
00059
00067 class BailException
00068 {
00069 };
00070
00144 class Processor: protected QThread, virtual public Source, virtual public Sink, public MultiSource, public MultiSink
00145 {
00146 public:
00150 enum ErrorType
00151 { NoError = 0,
00152 Pending,
00153 Custom,
00154 InputTypeNull,
00155 InputNotConnected,
00156 InputsNotHomogeneous,
00157 OutputsNull,
00158 RecursiveFailure,
00159 NotStarted
00160 };
00161
00162 enum
00163 { Guarded = 1
00164 };
00165
00166 private:
00171 static QThreadStorage<Processor **> theOwningProcessor;
00172
00174
00175 QString theName;
00176 const QString theType;
00177 uint theFlags;
00178 int theWidth, theHeight, theRedrawPeriod;
00179 ProcessorGroup *theGroup;
00181
00183
00184 friend class DomProcessor;
00185 friend class MultiProcessor;
00186 mutable QMutex theStop;
00187 QFastWaitCondition theAllDoneChanged;
00188 bool theIOSetup, theStopping, theIsInitialised, theAllDone;
00189 void doInit(const QString &name, ProcessorGroup *group, const Properties &properties);
00191
00192 protected:
00197 void bail();
00198
00202 virtual void wantToStopNow() {}
00203
00216 virtual void haveStoppedNow() {}
00217
00218 private:
00220
00221 mutable QMutex theConfirming;
00222 SignalTypeRefs theTypesCache;
00223 QValueVector<uint> theSizesCache;
00224 bool theTypesConfirmed;
00226
00228
00229 mutable QMutex thePause;
00230 QFastWaitCondition theUnpaused;
00231 bool thePaused;
00232 void guard();
00234
00236
00237 mutable QMutex theErrorSystem;
00238 QFastWaitCondition theErrorWritten;
00239 ErrorType theError;
00240 int theErrorData;
00242
00244 virtual void run();
00245
00246 public:
00251 static Processor *getCallersProcessor();
00252
00253 private:
00255
00256 QValueVector<xLConnection *> theInputs;
00257 QValueVector<LxConnection *> theOutputs;
00258 friend class RLConnection;
00259 friend class ProcessorForwarder;
00260 void dropInput(const uint index);
00262
00264
00265 MultiplicityType theMulti;
00266 uint theGivenMultiplicity;
00268
00270
00271 const bool knowMultiplicity() const { return theIsInitialised; }
00272 protected:
00273 const uint multiplicity() const { return theMulti&Out ? numOutputs() : numInputs(); }
00274 private:
00275 const bool initGiven() const { return theIsInitialised || theDeferredInit; }
00277
00279
00280 virtual ProcessorPort sourcePort(const uint i) { return (*this)[i]; }
00281 virtual void connectCheck() const { assert(theMulti&Out); }
00283
00285
00286 virtual ProcessorPort sinkPort(const uint i) { return (*this)[i]; }
00288
00290
00291 friend class LLConnection;
00292 friend class LRConnection;
00293 friend class xLConnectionReal;
00294 friend class MLConnection;
00295 QValueVector<uint> thePlungedInputs;
00296 mutable QMutex thePlungerSystem;
00297 QValueVector<uint> thePlungersLeft, thePlungersNotified;
00298 bool thePlungersStarted, thePlungersEnded;
00299 virtual void startPlungers();
00300 virtual void plungerSent(const uint index);
00301 virtual void noMorePlungers();
00303
00305
00306 virtual void plunged(const uint index);
00307 virtual void resetTypes();
00309
00311
00312 virtual void doRegisterOut(LxConnection *me, const uint port);
00313 virtual void undoRegisterOut(LxConnection *me, const uint port);
00315
00317
00318 virtual void doRegisterIn(xLConnection *me, const uint port);
00319 virtual void undoRegisterIn(xLConnection *me, const uint port);
00320 virtual const bool readyRegisterIn(const uint sinkIndex) const;
00321 virtual void waitToStop() { wait(); }
00322 virtual const bool waitUntilReady();
00324
00326
00327 virtual void checkExit();
00329
00330 protected:
00339
00348 xLConnection &input(const uint index)
00349 {
00350 #ifdef EDEBUG
00351 assert(index < theInputs.size());
00352 assert(theInputs[index]);
00353 #endif
00354 return *(theInputs[index]);
00355 }
00356
00365 LxConnection &output(const uint index)
00366 {
00367 #ifdef EDEBUG
00368 assert(index < theOutputs.size());
00369 assert(theOutputs[index]);
00370 #endif
00371 return *(theOutputs[index]);
00372 }
00373
00384 void plunge();
00385
00404 const bool thereIsInputForProcessing(const uint samples);
00405
00422 const bool thereIsInputForProcessing();
00423
00433 void setupIO(const uint inputs, const uint outputs);
00434
00447 void setupVisual(const uint width = 50, const uint height = 30, const uint redrawPeriod = 0);
00448
00454 virtual void paintProcessor(QPainter &p);
00455
00465 virtual void processor() = 0;
00466
00493 virtual const bool processorStarted() { return true; }
00494
00503 virtual void processorStopped() { }
00504
00513 virtual void receivedPlunger() {}
00514
00521 virtual PropertiesInfo specifyProperties() const { return PropertiesInfo(); }
00522
00528 virtual void initFromProperties(const Properties &properties) = 0;
00529
00553
00554 virtual const bool verifyAndSpecifyTypes(const SignalTypeRefs &inTypes, SignalTypeRefs &outTypes) = 0;
00555
00569 virtual void specifyInputSpace(QValueVector<uint> &samples);
00570
00586 virtual void specifyOutputSpace(QValueVector<uint> &samples);
00587
00596 Processor(const QString &type, const MultiplicityType multi = NotMulti, const uint flags = 0);
00597
00599
00600 public:
00608
00616 void setGroup(ProcessorGroup &g);
00617
00624 void setNoGroup();
00625
00631 const PropertiesInfo properties() const;
00632
00646 void init(const QString &name, ProcessorGroup &group, const Properties &properties = Properties()) { doInit(name, &group, properties); }
00647
00662 void init(const QString &name = "", const Properties &properties = Properties()) { doInit(name, 0, properties); }
00663
00670 const bool isInitFailed() const { return !(theIsInitialised || theDeferredInit); }
00671
00683 void split(const uint sourceIndex);
00684
00702 void share(const uint sourceIndex, const uint bufferSize = 1);
00703
00719 const Connection *connect(const uint sourceIndex, Sink *sink, const uint sinkIndex, const uint bufferSize = 1);
00720
00739 const Connection *connect(const uint sourceIndex, const QString &sinkHost, const uint sinkKey, const QString &sinkProcessorName, const uint sinkIndex, const uint bufferSize = 1);
00740
00741
00742
00743
00744
00745
00752 void disconnect(const uint index);
00753
00757 void disconnectAll();
00758
00768 ProcessorPort operator[](const uint port) { return ProcessorPort(this, port); }
00769
00781 virtual const bool confirmTypes();
00782
00790 const bool go();
00791
00804 const ErrorType waitUntilGoing(int *errorData = 0);
00805
00814 void waitUntilDone();
00815
00825 const ErrorType errorType() const { QMutexLocker lock(&theErrorSystem); return theError; }
00826
00837 const int errorData() const { QMutexLocker lock(&theErrorSystem); return theErrorData; }
00838
00847 const QString error() const;
00848
00858 void pause();
00859
00868 void unpause();
00869
00877 const bool paused() const { QMutexLocker lock(&thePause); return thePaused; }
00878
00884 void stop();
00885
00892 void reset();
00893
00899 const uint numInputs() const { return theInputs.size(); }
00900
00906 const uint numOutputs() const { return theOutputs.size(); }
00907
00913 const uint width() const { return theWidth; }
00914
00920 const uint height() const { return theHeight; }
00921
00928 const uint redrawPeriod() const { return theRedrawPeriod; }
00929
00936 void draw(QPainter &p);
00937
00946 const float bufferCapacity(const uint index);
00947
00954 const QString &name() const { return theName; }
00955
00961 const QString &type() const { return theType; }
00962
00964
00968 virtual ~Processor();
00969 };
00970
00971 }
00972
00973 #endif
00974