#include <processor.h>
Inheritance diagram for Geddei::Processor:
const uint | multiplicity () const |
class | DomProcessor |
class | MultiProcessor |
class | ProcessorForwarder |
class | RLConnection |
class | LLConnection |
class | LRConnection |
class | MLConnection |
class | xLConnectionReal |
Public Types | |
enum | { Guarded = 1 } |
Custom | |
Indicates the overridden processorStarted returned false. | |
enum | ErrorType { NoError = 0, Pending, Custom, InputTypeNull, InputNotConnected, InputsNotHomogeneous, OutputsNull, RecursiveFailure, NotStarted } |
Guarded = 1 | |
Indicates a subclass is able to finish when input EOS is given. | |
InputNotConnected | |
Indicates an input port was left unconnected. | |
InputsNotHomogeneous | |
Indicates a MultiIn type Processor has inputs of differing types. | |
InputTypeNull | |
Indicates an input has been given a null type. | |
NoError = 0 | |
Indicates no error occured. | |
NotStarted | |
Internal - Indicated the operation has yet to start. | |
OutputsNull | |
Indicates one or more outputs were left undefined. | |
Pending | |
Indicates the operation has yet to finish. | |
RecursiveFailure | |
Indicates a failure of a Processor that this depends on. | |
Public Member Functions | |
virtual | ~Processor () |
Control Methods for the external control of Processor objects. | |
This section of methods are for interfacing with Processor objects.
They are generally not used when coding a new type of Processor class. | |
const float | bufferCapacity (const uint index) |
virtual const bool | confirmTypes () |
const Connection * | connect (const uint sourceIndex, const QString &sinkHost, const uint sinkKey, const QString &sinkProcessorName, const uint sinkIndex, const uint bufferSize=1) |
const Connection * | connect (const uint sourceIndex, Sink *sink, const uint sinkIndex, const uint bufferSize=1) |
void | disconnect (const uint index) |
void | disconnectAll () |
void | draw (QPainter &p) |
const QString | error () const |
const int | errorData () const |
const ErrorType | errorType () const |
const bool | go () |
const uint | height () const |
void | init (const QString &name="", const Properties &properties=Properties()) |
void | init (const QString &name, ProcessorGroup &group, const Properties &properties=Properties()) |
const bool | isInitFailed () const |
const QString & | name () const |
const uint | numInputs () const |
const uint | numOutputs () const |
ProcessorPort | operator[] (const uint port) |
void | pause () |
const bool | paused () const |
const PropertiesInfo | properties () const |
const uint | redrawPeriod () const |
void | reset () |
void | setGroup (ProcessorGroup &g) |
void | setNoGroup () |
void | share (const uint sourceIndex, const uint bufferSize=1) |
void | split (const uint sourceIndex) |
void | stop () |
const QString & | type () const |
void | unpause () |
void | waitUntilDone () |
const ErrorType | waitUntilGoing (int *errorData=0) |
const uint | width () const |
Static Public Member Functions | |
static Processor * | getCallersProcessor () |
Protected Member Functions | |
void | bail () |
virtual void | haveStoppedNow () |
virtual void | wantToStopNow () |
Derived Methods for use in derived classes. | |
These methods are protected to allow only new (derived) types of Processor class to use them.
They are not used for manipulating Processor objects externally. | |
virtual void | initFromProperties (const Properties &properties)=0 |
xLConnection & | input (const uint index) |
LxConnection & | output (const uint index) |
virtual void | paintProcessor (QPainter &p) |
void | plunge () |
Processor (const QString &type, const MultiplicityType multi=NotMulti, const uint flags=0) | |
virtual void | processor ()=0 |
virtual const bool | processorStarted () |
virtual void | processorStopped () |
virtual void | receivedPlunger () |
void | setupIO (const uint inputs, const uint outputs) |
void | setupVisual (const uint width=50, const uint height=30, const uint redrawPeriod=0) |
virtual void | specifyInputSpace (QValueVector< uint > &samples) |
virtual void | specifyOutputSpace (QValueVector< uint > &samples) |
virtual PropertiesInfo | specifyProperties () const |
const bool | thereIsInputForProcessing () |
const bool | thereIsInputForProcessing (const uint samples) |
virtual const bool | verifyAndSpecifyTypes (const SignalTypeRefs &inTypes, SignalTypeRefs &outTypes)=0 |
The methods can be generally split into two types. Those (wholly non-virtual) methods for external (to the Processor class) control of the object --- these are all public. The second type are the methods used in creating new classes of Processor. These comprise those that may (or must) be reimplemented and those that are used for internal control of the object, e.g. for setting up the internals. These are all protected.
Using Processor objects externally:
A Processor object must be initialised before use, but then may be started with go() and stop()ped, pause()d, and unpause()d. Between stopping a processor and starting it again, all processors must be reset(), in order to accomplish a synchronised restart.
All Processor objects should have a name, set on init(). All Processor- derived classes must have a type, set on class declaration. Either of these may be retrieved with the eponymous methods.
Processor objects may be put into groups with the setGroup and setNoGroup methods. This can also be done on init().
Connections between Processors may be created and destroyed with the connect() and disconnect() methods. The SignalType validity and consistency of the network may be checked (before the processors have been started) with the confirmTypes() method. split() and share() may be used to fork outputs for connection to multiple destinations.
Processor objects may inform other such Processor objects about the current plunger situation in the data stream. Plungers may be thought of as seperators in the signal data stream. They segment one portion of the stream and allow equivalent points in the data stream to be defined. You might liken them to the "Next customer please" signs at supermarket checkouts.
All Processor (-derived) objects are potential informers, however some objects may be able to "become informed". Such objects are said to have the "Guarded" attribute. In such a case they can be told to cease processing once they have been informed that (after a certain plunger) no more data will arrive. This is useful since there is a blocking method that can be called on such an object, waitUntilDone(), which waits until the object enters such a state.
See the file testfileout.cpp for a concrete example of this usage.
Creating new Processor classes:
To create your own Processor class, you must subclass this and reimplement all virtual void methods, and optionally the other virtual methods too.
The main methods to implement are: specifyProperties(), initFromProperties(), verifyAndSpecifyTypes() and processor(). It is generally sensible to implement the other methods like specifyOutputSpace() and specifyInputSpace(). See the documentation for more information.
process() is the most significant method, as it is here you define what job the Processor actually "does".
Each input or output may have an arbitrary SignalType to describe the data that flows down it. Outputs' SignalTypes must be specified with the verifyAndSpecifyTypes() and inputs' SignalTypes may be constrained also.
It can specify a number of typed Properties, and be initialised with some values for those properties. It may specify a visual size and method for drawing in a GUI.
The various error types that a Processor may trip up on.
NoError | Indicates no error occured. |
Pending | Indicates the operation has yet to finish. |
Custom | Indicates the overridden processorStarted returned false. |
InputTypeNull | Indicates an input has been given a null type. |
InputNotConnected | Indicates an input port was left unconnected. |
InputsNotHomogeneous | Indicates a MultiIn type Processor has inputs of differing types. |
OutputsNull | Indicates one or more outputs were left undefined. |
RecursiveFailure | Indicates a failure of a Processor that this depends on. |
NotStarted | Internal - Indicated the operation has yet to start. |
Geddei::Processor::Processor | ( | const QString & | type, | |
const MultiplicityType | multi = NotMulti , |
|||
const uint | flags = 0 | |||
) | [protected] |
Simple constructor.
type | This must the class name of the derived class. All sorts of things will break if it isn't. | |
multi | Declares the type of multiplicity this Processor offers. Defaults to NotMulti. |
Geddei::Processor::~Processor | ( | ) | [virtual] |
Simple, virtual, destructor.
xLConnection& Geddei::Processor::input | ( | const uint | index | ) | [inline, protected] |
Used from Processor::processor to read from the data source. Asserts index is less than the number of inputs and index is connected.
index | The input port index for which Connection is required. |
LxConnection& Geddei::Processor::output | ( | const uint | index | ) | [inline, protected] |
Used from Processor::processor to write to the data sink(s). Asserts index is less than the number of outputs and index is connected.
index | The output port index for which Connection is required. |
void Geddei::Processor::plunge | ( | ) | [protected] |
Insert a plunger into all output connections immediately.
Plungers can be thought of a stream seperators, not disimilar from those "Next customer please" signs you get at supermarket checkouts to determine where your items start and the previous person's stops.
const bool Geddei::Processor::thereIsInputForProcessing | ( | const uint | samples | ) | [protected] |
Blocks until either:
1) There will never again be enough input for any processing. In this instance, it returns false.
2) There are at least samples samples ready for reading immediately. It guarantees that reading this data will not require any more plunging. In this case, true is returned.
If there are any plungers to be read immediately, then they are read. This is only the case if the next read would cause a plunger to be read.
samples | The number of samples that there should be on an input for reading in order for this to exit true. |
const bool Geddei::Processor::thereIsInputForProcessing | ( | ) | [protected] |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. Blocks until either:
1) There will never again be enough input for any processing. In this instance, it returns false.
2) There are at least specifyInputSpace() samples (for each input)ready for reading immediately. It guarantees that reading this data will not require any more plunging. In this case, true is returned.
If there are any plungers to be read immediately, then they are read. This is only the case if the next read would cause a plunger to be read.
void Geddei::Processor::setupIO | ( | const uint | inputs, | |
const uint | outputs | |||
) | [protected] |
Call this from initFromProperties to initialise I/O connections.
inputs | The number of inputs this Processor should have. May be Undefined iff the Processor has been declared as a multi of Input (not ConstInput though). | |
outputs | The number of outputs this Processor should have. May be Undefined iff the Processor has been declared as a multi of Output (not ConstOutput though). |
void Geddei::Processor::setupVisual | ( | const uint | width = 50 , |
|
const uint | height = 30 , |
|||
const uint | redrawPeriod = 0 | |||
) | [protected] |
Call this from initFromProperties to initialise the visual properties of the class.
If this is not called, the size will default to 50x30 and no redraw.
width | The width of the drawing canvas. Should be a multiple of 10. | |
height | The height of the drawing canvas. Should be a multiple of 10. | |
redrawPeriod | The rate for which the processor's visual should be redrawn in milliseconds. A value of zero means no explicit redraw. |
void Geddei::Processor::paintProcessor | ( | QPainter & | p | ) | [protected, virtual] |
Reimplement for to define how the processor should be drawn visually.
p | The painting canvas onto which the visual may be drawn. |
virtual void Geddei::Processor::processor | ( | ) | [protected, pure virtual] |
Reimplement to control execution to do processing. Use Buffer's waitFor methods to control flow for theInputs/theOutputs. This doesn't ever have to return explicitly - typically a
while(thereIsInputForProcessing()) {}
virtual const bool Geddei::Processor::processorStarted | ( | ) | [inline, protected, virtual] |
Reimplement to initialise any stuff that processor may need to be open/ locked/whatever. Does nothing by default.
Note this is executed inside the go() call, and as such MUST NEVER BLOCK under any circumstances, as doing so will almost certainly break the main program.
This different from initFromProperties, since that represents a one-off initialiser for the object, like the constructor. This is called potentially many times in an object's life, each time it is started.
Generally you wont have to use this since you'll be able to do any internal initialisations inside processor() much more easily. However this is useful if you need to reset some external or shared value that must happen before the main program gets past the starting stage.
The other reason for using this method to specify initialisation procedures is because it facilitates error detection and reporting. By returning false, all startup can be simply aborted.
virtual void Geddei::Processor::processorStopped | ( | ) | [inline, protected, virtual] |
Reimplement to cleanup any stuff that processor may have left open/locked/ whatever. Does nothing by default.
Note this is executed directly after processor() has exited, in the same thread. There is another similar (internal) method haveStoppedNow() that you probably shouldn't touch unless you know you have to.
virtual void Geddei::Processor::receivedPlunger | ( | ) | [inline, protected, virtual] |
Reimplement to (synchronously) handle any sub-data signals ("plungers"). Does nothing by default.
This will be called from inside the processor() thread when elements are being read. Make sure that this *under no circumstances* blocks, since there will likely be nothing to unblock it.
virtual PropertiesInfo Geddei::Processor::specifyProperties | ( | ) | const [inline, protected, virtual] |
Reimplement to provide property specifications and default values for this Processor.
virtual void Geddei::Processor::initFromProperties | ( | const Properties & | properties | ) | [protected, pure virtual] |
Initialises from the Properties; should call setupIO() and setupVisual() at least.
properties | The given properties. |
virtual const bool Geddei::Processor::verifyAndSpecifyTypes | ( | const SignalTypeRefs & | inTypes, | |
SignalTypeRefs & | outTypes | |||
) | [protected, pure virtual] |
Reimplement to restrict signal types this class can handle, and define signaltypes it will output.
Examples of correct usage:
outTypes[0] = new Wave(2600.0);
outTypes[1] = inTypes[0]->copy();
TIP: Don't forget inTypes is const, so if you're dynamic_cast<...>'ing a member, you'll have to cast it something else const!
inTypes | An array-like type populated with the input types of the connections. If the Processor is declared as a MultiIn, then you are guaranteed that all input types are the same basic class (parameters may be different); you don't need an extra test. | |
outTypes | An array-like type to contain the output types of the connections. They are all initially null, and if this method returns true, they must be defined. The array is large enough to store all the connections' types in. If the Processor is declared as a MultiOut, then you only have to define the first type. Any entries left undefined will be populated by copies of the first entry. They must all be of the same basic class. |
void Geddei::Processor::specifyInputSpace | ( | QValueVector< uint > & | samples | ) | [protected, virtual] |
Reimplement to force the inputs' buffer size to be at least samples big, explicitly allowing a readSamples(s) to be legal, where s is the size given.
This gets called *after* verifyAndSpecifyTypes(), but before specifyOutputSpace(), and so must be based only upon the types and any properties accumulated.
The default implementation requests only a single sample's worth of data to be available.
samples | A correctly-sized array (well; QValueVector) into which your minima can be placed. |
void Geddei::Processor::specifyOutputSpace | ( | QValueVector< uint > & | samples | ) | [protected, virtual] |
Reimplement to force the outputs' buffer size to be at least samples big, explicitly allowing a makeScratchSamples(s) on an empty scratch to be legal, where s is the size given (to make a mSS(s) always efficient and never block, a minimum of 2*s should be given).
This gets called *after* verifyAndSpecifyTypes() and specifyInputSpace(), and so can be based upon the types, properties and the inputs' buffer sizes.
The default implementation requests only a single sample's worth of data to be available.
samples | A correctly-sized array (well; QValueVector) into which your minima can be placed. |
void Geddei::Processor::setGroup | ( | ProcessorGroup & | g | ) |
Puts the Processor into a gvien ProcessorGroup.
g | The ProcessorGroup the Processor should become a member of. |
void Geddei::Processor::setNoGroup | ( | ) |
Resets the group of the object. The processor will not be associated with any group after this call.
const PropertiesInfo Geddei::Processor::properties | ( | ) | const |
Returns information about the properties of the object and gives their default values.
void Geddei::Processor::init | ( | const QString & | name, | |
ProcessorGroup & | group, | |||
const Properties & | properties = Properties() | |||
) | [inline] |
Performs basic object construction that cannot otherwise be done in the constructor due to shared library limitations. Initialises the object fully ready for connect()s and then go().
name | This Processor instance's name, and should be unique across any group or network the processor is in. | |
group | A reference to the ProcessorGroup (if any) that you may use to control a set of objects. | |
properties | The properties with which to initialise this object. This defaults to an empty properties set. If a needed property is left undefined, the default value is taken from the properties() method. |
void Geddei::Processor::init | ( | const QString & | name = "" , |
|
const Properties & | properties = Properties() | |||
) | [inline] |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. Performs basic object construction that cannot otherwise be done in the constructor due to shared library limitations. Initialises the object fully ready for connect()s and then go().
name | This Processor instance's name, and should be unique across any group or network the processor is in. This defaults to the empty name, which can be used iff the object is not contained in a ProcessorGroup. | |
properties | The properties with which to initialise this object. This defaults to an empty properties set. If a needed property is left undefined, the default value is taken from the properties() method. |
const bool Geddei::Processor::isInitFailed | ( | ) | const [inline] |
void Geddei::Processor::split | ( | const uint | sourceIndex | ) |
Use this method for driving multiple inputs from one output.
All data is explicitly copied to each connection buffer. Any type of connection may be used. Once called, just keep calling connect as many times as you need.
sourceIndex | The index of the output port you wish to drive multiple inputs from. |
void Geddei::Processor::share | ( | const uint | sourceIndex, | |
const uint | bufferSize = 1 | |||
) |
Use this method for driving multiple inputs from one output.
This explicitly shares the data, using only one buffer and is extremely efficient. Once called, just keep calling connect as many times as you need.
sourceIndex | The index of the output port you wish to drive multiple inputs with. | |
bufferSize | The minimum size of the connection buffer in elements. Defaults to 1. Under normal circumstances this will not need to be changed. |
const Connection * Geddei::Processor::connect | ( | const uint | sourceIndex, | |
Sink * | sink, | |||
const uint | sinkIndex, | |||
const uint | bufferSize = 1 | |||
) |
Create a connection to another Processor object running in this program. Connection uses a shared memory method, thus the processor must be local.
sourceIndex | The index of the output port you wish to connect from. | |
sink | A pointer to the Processor object you wish to connect to. | |
sinkIndex | The input port of sink that you wish to connect to. | |
bufferSize | The minimum size of the connection buffer in elements. Defaults to 1. Under normal circumstances this will not need to be changed. |
const Connection * Geddei::Processor::connect | ( | const uint | sourceIndex, | |
const QString & | sinkHost, | |||
const uint | sinkKey, | |||
const QString & | sinkProcessorName, | |||
const uint | sinkIndex, | |||
const uint | bufferSize = 1 | |||
) |
Create a connection to another Processor object. Connection uses a TCP/IP method, thus the processor can be remote.
sourceIndex | The index of the output port you wish to connect from. | |
sinkHost | The TCP/IP hostname (or IP address) of the host on which the object resides. | |
sinkKey | The predefined key into the remote session. This comes from the remote node's server software. | |
sinkProcessorName | The name of the Processor object you wish to connect to. | |
sinkIndex | The input port of sink that you wish to connect to. | |
bufferSize | The minimum size of the connection buffer in elements. Defaults to 1. Under normal circumstances this will not need to be changed. |
void Geddei::Processor::disconnect | ( | const uint | index | ) |
void Geddei::Processor::disconnectAll | ( | ) |
Destoy all outgoing connections.
ProcessorPort Geddei::Processor::operator[] | ( | const uint | port | ) | [inline] |
Returns convenience object that represents one of this object's input/outputs. Can be used for creating connections.
port | The index of the port that you wish to reference. |
const bool Geddei::Processor::confirmTypes | ( | ) | [virtual] |
Checks the types (recursively if necessary) and reports if all is ok. Sets up Connections types on its way. Note this is done automatically if necessary at go() anyway.
const bool Geddei::Processor::go | ( | ) |
Make the thing start doing stuff. i.e. Starts processor thread.
const Processor::ErrorType Geddei::Processor::waitUntilGoing | ( | int * | errorData = 0 |
) |
Blocks until processor is active, and gives error information if processor startup failed along the way.
errorData | If non-zero, an integer will be placed where this points in case error occurs in startup. This may represent some numerical data for the error. It depends on the error type, but may e.g. point to a specific port. Defaults to zero. |
void Geddei::Processor::waitUntilDone | ( | ) |
Blocks until the Processor object is finished and has exited it's main processor() method.
This is not the same as a Processor object that has stop()ed. In this case, the object is in a "zombie" state. While not yet stopped, it will never again process any data.
const ErrorType Geddei::Processor::errorType | ( | ) | const [inline] |
Get the last error (if any) from starting up.
const int Geddei::Processor::errorData | ( | ) | const [inline] |
Get any (numerical) data associated with the error condition given by errorType().
This value is undefined in the case of no error (or Pending startup).
const QString Geddei::Processor::error | ( | ) | const |
Get a string which is a human readable interpretation of the last error that occured.
TODO: Implement.
void Geddei::Processor::pause | ( | ) |
void Geddei::Processor::unpause | ( | ) |
const bool Geddei::Processor::paused | ( | ) | const [inline] |
void Geddei::Processor::stop | ( | ) |
void Geddei::Processor::reset | ( | ) |
const uint Geddei::Processor::numInputs | ( | ) | const [inline] |
Gets the number of inputs this processor has.
const uint Geddei::Processor::numOutputs | ( | ) | const [inline] |
Gets the number of outputs this processor has.
const uint Geddei::Processor::width | ( | ) | const [inline] |
Gets the width of the processor's image. Used by the Nite for drawing.
const uint Geddei::Processor::height | ( | ) | const [inline] |
Gets the height of the processor's image. Used by the Nite for drawing.
const uint Geddei::Processor::redrawPeriod | ( | ) | const [inline] |
Gets the (automatic) redraw period of the processor in milliseconds. Used by the Nite for drawing.
void Geddei::Processor::draw | ( | QPainter & | p | ) |
Front-end routing for drawing the Processor to a canvas. Used by the Nite for drawing.
p | The painting canvas onto which the drawing should take place. |
const float Geddei::Processor::bufferCapacity | ( | const uint | index | ) |
Determine how full the buffer at input index is. Used by the Nite for drawing.
index | The input port's index. |
const QString& Geddei::Processor::name | ( | ) | const [inline] |
Gets the (instance-wise) name of the processor. This is unique for any group or network the processor is in.
const QString& Geddei::Processor::type | ( | ) | const [inline] |
friend class DomProcessor [friend] |
Start/stop subsystem.
friend class LLConnection [friend] |
Plunger subsystem, in collaboration with Buffer.