bool PipelineProcessor::__process( unsigned int serial ) { assert( requiredPinsConnected() ); assert( getState() == RUNNING ); QMutexLocker lock( &m_pleMutex ); // set the serial number m_serial = serial; bool nullDetected = false; // call pre on input pins and look for null data items for( InputPinMap::iterator itr = m_inputPins.begin(); itr != m_inputPins.end(); ++itr ) { IInputPin* in = itr->second.getPtr(); // only check synchronous connections if( in->isConnected() && in->isSynchronous() ) { unsigned int serial; bool isNull; in->peekNext(serial, isNull); if( isNull ) nullDetected = true; } in->pre(); } // if one data item is a null // we throw away all data from all synchronous pins if( nullDetected ) { for( InputPinMap::iterator itr = m_inputPins.begin(); itr != m_inputPins.end(); ++itr ) { IInputPin* in = itr->second.getPtr(); if( in->isConnected() && in->isSynchronous() ) { // just remove first data item in the in->removeFirst(); } } return true; } // call pre on output pins for( OutputPinMap::iterator itr = m_outputPins.begin(); itr != m_outputPins.end(); ++itr ) { IOutputPin* out = itr->second.getPtr(); out->pre(); } // do the actual processing lock.unlock(); // we do not want properties to change in the middle of an operation QMutexLocker lock2( m_propertyMutex ); bool retval = this->process(); lock2.unlock(); lock.relock(); // call post on input pins for( InputPinMap::iterator itr = m_inputPins.begin(); itr != m_inputPins.end(); ++itr ) { IInputPin* in = itr->second.getPtr(); in->post(); } // call post on output pins for( OutputPinMap::iterator itr = m_outputPins.begin(); itr != m_outputPins.end(); ++itr ) { IOutputPin* out = itr->second.getPtr(); out->post(); } lock.unlock(); if(!retval && getState() != ERROR) { QString msg = tr("Method process() on PipelineProcessor %1 returned false " "but error state was not set.").arg(this->getName()); qWarning() << msg; } return retval; }
bool PipelineElement::dataAvailableOnInputPins( unsigned int& nextSerial ) { // synchronous processor if( m_hasSynchronousPin ) { std::vector<unsigned int> serials; for( InputPinMap::const_iterator itr = m_inputPins.begin(); itr != m_inputPins.end(); ++itr ) { IInputPin* in = itr->second.getPtr(); // only check synchronous connections if( in->isConnected() ) { if( in->isSynchronous() ) { if( in->hasData() ) { unsigned int serial; bool isNull; in->peekNext(serial, isNull); serials.push_back( serial ); } else { return false; } } } } // check if all serials are the same (which should be the case) bool valid = true; for( unsigned int i=0; i<serials.size() && valid; ++i) { valid = (serials[0] == serials[i]); } // the model should guarantee that // this should never happen obviously if( !valid ) { setError( PlvPipelineRuntimeError, "Input corrupted" ); return false; } // save the serial nextSerial = serials[0]; return true; } // asynchronous processor, only has asynchronous pins else if( m_hasAsynchronousPin ) { std::vector<unsigned int> serials; for( InputPinMap::const_iterator itr = m_inputPins.begin(); itr != m_inputPins.end(); ++itr ) { IInputPin* in = itr->second.getPtr(); // only check asynchronous connections if( in->isConnected() ) //&& in->isAsynchronous() ) { if( in->hasData() ) { unsigned int serial; bool isNull; in->peekNext(serial, isNull); serials.push_back(serial); } } } if( serials.size() > 0 ) { std::sort( serials.begin(), serials.end() ); // return smallest serial nextSerial = serials[0]; return true; } } return false; }