Skip to content
Permalink
Browse files

Add method to take results from another processing context and

add to the current context

With appropriate note and tests to ensure that both the current
context and that which the results being taken from share the
same thread affinity
  • Loading branch information
nyalldawson committed Jul 6, 2017
1 parent d20c68d commit 5350483c907008854553272d6f9bbacb47213873
@@ -237,6 +237,15 @@ Destination project
.. seealso:: thread()
%End

void takeResultsFrom( QgsProcessingContext &context );
%Docstring
Takes the results from another ``context`` and merges them with the results currently
stored in this context. This includes settings like any layers loaded in the temporaryLayerStore()
and layersToLoadOnCompletion().
This is only safe to call when both this context and the other ``context`` share the same
thread() affinity, and that thread is the current thread.
%End

private:
QgsProcessingContext( const QgsProcessingContext &other );
};
@@ -340,10 +340,29 @@ class CORE_EXPORT QgsProcessingContext
*/
void pushToThread( QThread *thread )
{
Q_ASSERTX( QThread::currentThread() == thread(), "QgsProcessingContext::pushToThread", "Cannot push context to another thread unless the current thread matches the existing context thread affinity" );
Q_ASSERT_X( QThread::currentThread() == QgsProcessingContext::thread(), "QgsProcessingContext::pushToThread", "Cannot push context to another thread unless the current thread matches the existing context thread affinity" );
tempLayerStore.moveToThread( thread );
}

/**
* Takes the results from another \a context and merges them with the results currently
* stored in this context. This includes settings like any layers loaded in the temporaryLayerStore()
* and layersToLoadOnCompletion().
* This is only safe to call when both this context and the other \a context share the same
* thread() affinity, and that thread is the current thread.
*/
void takeResultsFrom( QgsProcessingContext &context )
{
QMap< QString, LayerDetails > loadOnCompletion = context.layersToLoadOnCompletion();
QMap< QString, LayerDetails >::const_iterator llIt = loadOnCompletion.constBegin();
for ( ; llIt != loadOnCompletion.constEnd(); ++llIt )
{
mLayersToLoadOnCompletion.insert( llIt.key(), llIt.value() );
}
context.setLayersToLoadOnCompletion( QMap< QString, LayerDetails >() );
tempLayerStore.transferLayersFromStore( context.temporaryLayerStore() );
}

private:

QgsProcessingContext::Flags mFlags = 0;
@@ -583,12 +583,18 @@ void TestQgsProcessing::context()
context.setInvalidGeometryCheck( QgsFeatureRequest::GeometrySkipInvalid );
QCOMPARE( context.invalidGeometryCheck(), QgsFeatureRequest::GeometrySkipInvalid );

QgsVectorLayer *vector = new QgsVectorLayer( "Polygon", "vector", "memory" );
context.temporaryLayerStore()->addMapLayer( vector );
QCOMPARE( context.temporaryLayerStore()->mapLayer( vector->id() ), vector );

QgsProcessingContext context2;
context2.copyThreadSafeSettings( context );
QCOMPARE( context2.defaultEncoding(), context.defaultEncoding() );
QCOMPARE( context2.invalidGeometryCheck(), context.invalidGeometryCheck() );
QCOMPARE( context2.flags(), context.flags() );
QCOMPARE( context2.project(), context.project() );
// layers from temporaryLayerStore must not be copied by copyThreadSafeSettings
QVERIFY( context2.temporaryLayerStore()->mapLayers().isEmpty() );

// layers to load on completion
QgsVectorLayer *v1 = new QgsVectorLayer( "Polygon", "V1", "memory" );
@@ -606,6 +612,11 @@ void TestQgsProcessing::context()
QCOMPARE( context.layersToLoadOnCompletion().values().at( 0 ).name, QStringLiteral( "v1" ) );
QCOMPARE( context.layersToLoadOnCompletion().keys().at( 1 ), v2->id() );
QCOMPARE( context.layersToLoadOnCompletion().values().at( 1 ).name, QStringLiteral( "v2" ) );

// ensure that copyThreadSafeSettings doesn't copy layersToLoadOnCompletion()
context2.copyThreadSafeSettings( context );
QVERIFY( context2.layersToLoadOnCompletion().isEmpty() );

layers.clear();
layers.insert( v2->id(), QgsProcessingContext::LayerDetails( QStringLiteral( "v2" ), &p ) );
context.setLayersToLoadOnCompletion( layers );
@@ -616,8 +627,20 @@ void TestQgsProcessing::context()
QCOMPARE( context.layersToLoadOnCompletion().count(), 2 );
QCOMPARE( context.layersToLoadOnCompletion().keys().at( 0 ), v1->id() );
QCOMPARE( context.layersToLoadOnCompletion().keys().at( 1 ), v2->id() );
delete v1;
delete v2;

context.temporaryLayerStore()->addMapLayer( v1 );
context.temporaryLayerStore()->addMapLayer( v2 );

// test takeResultsFrom
context2.takeResultsFrom( context );
QVERIFY( context.temporaryLayerStore()->mapLayers().isEmpty() );
QVERIFY( context.layersToLoadOnCompletion().isEmpty() );
// should now be in context2
QCOMPARE( context2.temporaryLayerStore()->mapLayer( v1->id() ), v1 );
QCOMPARE( context2.temporaryLayerStore()->mapLayer( v2->id() ), v2 );
QCOMPARE( context2.layersToLoadOnCompletion().count(), 2 );
QCOMPARE( context2.layersToLoadOnCompletion().keys().at( 0 ), v1->id() );
QCOMPARE( context2.layersToLoadOnCompletion().keys().at( 1 ), v2->id() );
}

void TestQgsProcessing::mapLayers()

0 comments on commit 5350483

Please sign in to comment.
You can’t perform that action at this time.