diff --git a/Control/AthViews/AthViews/ViewHelper.h b/Control/AthViews/AthViews/ViewHelper.h index 5594c244396124deac04a66bd34b6dd283f9e74c..432d14f26122ab344b7f6de2d84582001546c058 100644 --- a/Control/AthViews/AthViews/ViewHelper.h +++ b/Control/AthViews/AthViews/ViewHelper.h @@ -225,8 +225,9 @@ namespace ViewHelper } //Declare remapping + auto proxy = inputView->proxy( queryHandle.clid(), queryHandle.key() ); //shouldn't need to test validity since queryHandle already used m_sg->remap( ClassID_traits< DataVector< T > >::ID(), - inputView->viewKey (queryHandle.name()), + proxy->name(), queryHandle.name(), offset ); offset += queryHandle->size(); @@ -277,7 +278,9 @@ namespace ViewHelper template<typename T> ElementLink<T> makeLink( const SG::View* view, const SG::ReadHandle<T>& handle, size_t index ) { - return ElementLink<T>( view->viewKey (handle.key()), index ); + auto proxy = view->proxy( handle.clid(), handle.key() ); + if ( proxy == nullptr ) throw std::runtime_error( "Attempting to make element link with invalid key " + handle.key() ); + return ElementLink<T>( proxy->name(), index ); } } // EOF namspace ViewHelper diff --git a/Control/AthViews/share/ViewLinking_test.ref b/Control/AthViews/share/ViewLinking_test.ref index d394bd76b53a898c7e92a33f8e18b3aa8322917b..5629645288f9928017370885c467c711052f2fd9 100644 --- a/Control/AthViews/share/ViewLinking_test.ref +++ b/Control/AthViews/share/ViewLinking_test.ref @@ -13,7 +13,8 @@ ApplicationMgr Ready ClassIDSvc INFO getRegistryEntries: read 811 CLIDRegistry entries for module ALL ViewLinking_test INFO SG pointer: 0xdab760 ClassIDSvc INFO getRegistryEntries: read 400 CLIDRegistry entries for module ALL -ViewLinking_test INFO Views that are not linked behave correctly -ViewLinking_test INFO Views that are linked behave correctly -ViewLinking_test INFO Hiding works as expected -ViewLinking_test INFO Fall through works as expected +ViewLinking_test INFO Views that are not linked behave correctly +ViewLinking_test INFO Views that are linked behave correctly +ViewLinking_test INFO Hiding works as expected +ViewLinking_test INFO Fall through works as expected +ViewLinking_test INFO Fall through works with links as expected diff --git a/Control/AthViews/test/ViewLinking_test.cxx b/Control/AthViews/test/ViewLinking_test.cxx index eee8ae53b1686fe59ec69c33c35963889c63e005..dff7925a4ccdd4eaa295c7a83ba6e2d2a55a2caa 100644 --- a/Control/AthViews/test/ViewLinking_test.cxx +++ b/Control/AthViews/test/ViewLinking_test.cxx @@ -13,20 +13,23 @@ #include "TestTools/expect.h" #include "TestTools/expect_exception.h" #include "AthViews/View.h" +#include "AthViews/ViewHelper.h" struct TestClass { int value = 0; }; +CLASS_DEF( TestClass, 16530831, 1 ) + +typedef std::vector<TestClass*> TestContainer; +CLASS_DEF( TestContainer, 16530833, 1 ) -CLASS_DEF( TestClass , 16530831 , 1 ) using namespace SG; void testDataInView( StoreGateSvc* /*sg*/ , MsgStream& log ) { - auto parentView = new View( "ParentView", -1 ); + // Make parent view + auto parentView = new View( "ParentView", -1 ); auto t1 = std::make_unique<TestClass>(); t1->value = 1; - // auto status1 = parentView->recordObject( t1, "test1" ); - { SG::WriteHandle<TestClass> wh( "test1" ); wh.setProxyDict( parentView ).ignore(); @@ -34,78 +37,75 @@ void testDataInView( StoreGateSvc* /*sg*/ , MsgStream& log ) { VALUE( status.isSuccess() ) EXPECTED( true ); } + // Make child view auto childView = new View( "ChildView", -1 ); - auto t2 = std::make_unique<TestClass>(); t2->value = 2; { SG::WriteHandle<TestClass> wh( "test2" ); wh.setProxyDict( childView ).ignore(); auto status = wh.record( std::move( t2 ) ); - VALUE( status.isSuccess() ) EXPECTED( true ); + VALUE( status.isSuccess() ) EXPECTED( true ); } - // auto status2 = childView->recordObject( t2, "test1" ); - // all prepared, will start testing if querries respond correctly + + // All prepared, will start testing if queries respond correctly { - // rtivial test, we ask for a wrong object + // Ask for an object that doesn't exist SG::ReadHandle<TestClass> rh( "test" ); rh.setProxyDict( childView ).ignore(); VALUE( rh.isValid() ) EXPECTED( false ); } - - - { + // Ask for object in the child view SG::ReadHandle<TestClass> rh( "test2" ); rh.setProxyDict( childView ).ignore(); VALUE( rh.isValid() ) EXPECTED( true ); VALUE( rh->value ) EXPECTED( 2 ); } - { + // Ask child view for object that only exists in the parent SG::ReadHandle<TestClass> rh( "test1" ); rh.setProxyDict( childView ).ignore(); VALUE( rh.isValid() ) EXPECTED( false ); } - log << MSG::INFO << "Views that are not linked behave correctly " << endmsg; - // link them and see if data object is accessible - childView->linkParent( parentView ); + log << MSG::INFO << "Views that are not linked behave correctly" << endmsg; + // Link views and see if data object is accessible + childView->linkParent( parentView ); { + // Is the original object still there? SG::ReadHandle<TestClass> rh( "test2" ); rh.setProxyDict( childView ).ignore(); VALUE( rh.isValid() ) EXPECTED( true ); VALUE( rh->value ) EXPECTED( 2 ); } { + // Is the object from the parent now also visible? SG::ReadHandle<TestClass> rh( "test1" ); rh.setProxyDict( childView ).ignore(); VALUE( rh.isValid() ) EXPECTED( true ); VALUE( rh->value ) EXPECTED( 1 ); } - log << MSG::INFO << "Views that are linked behave correctly " << endmsg; + log << MSG::INFO << "Views that are linked behave correctly" << endmsg; - // hide object from parent by adding one in the Child + // Hide object from parent by adding one with same name to the Child auto t3 = std::make_unique<TestClass>(); t3->value = 3; - { + // Can it be recorded? (should be allowed) SG::WriteHandle<TestClass> wh( "test1" ); wh.setProxyDict( childView ).ignore(); auto status = wh.record( std::move( t3 ) ); VALUE( status.isSuccess() ) EXPECTED( true ); } - { + // Do we now see the child object in preference to the parent? SG::ReadHandle<TestClass> rh( "test1" ); rh.setProxyDict( childView ).ignore(); VALUE( rh.isValid() ) EXPECTED( true ); VALUE( rh->value ) EXPECTED ( 3 ); } - - log << MSG::INFO << "Hiding works as expected " << endmsg; - - + log << MSG::INFO << "Hiding works as expected" << endmsg; } void testFallThrough( StoreGateSvc* sg , MsgStream& log) { @@ -113,8 +113,8 @@ void testFallThrough( StoreGateSvc* sg , MsgStream& log) { SG::WriteHandle<TestClass> wh( "inStore" ); wh.setProxyDict( sg ).ignore(); auto status = wh.record( std::move( t ) ); - VALUE( status.isSuccess() ) EXPECTED( true ); - + VALUE( status.isSuccess() ) EXPECTED( true ); + // the whole trick is that the read handle is pointed to the view, // but should read from the main store if the fall though // is enabled @@ -130,21 +130,86 @@ void testFallThrough( StoreGateSvc* sg , MsgStream& log) { rh.setProxyDict( transparentView ).ignore(); VALUE( rh.isValid() ) EXPECTED( true ); } - log << MSG::INFO << "Fall through works as expected " << endmsg; + log << MSG::INFO << "Fall through works as expected" << endmsg; } +void testFallThroughLinks( StoreGateSvc* sg , MsgStream& log ) { + // Have to make a container to test element links + auto t = std::make_unique<TestContainer>(); + t->push_back( new TestClass() ); + t->back()->value = 5; + t->push_back( new TestClass() ); + t->back()->value = 4; + + // Store the container in the event-level store + SG::WriteHandle<TestContainer> wh( "inStore" ); + wh.setProxyDict( sg ).ignore(); + auto status = wh.record( std::move( t ) ); + VALUE( status.isSuccess() ) EXPECTED( true ); + + // Make another container for testing parent/child links + auto t2 = std::make_unique<TestContainer>(); + t2->push_back( new TestClass() ); + t2->back()->value = 3; + t2->push_back( new TestClass() ); + t2->back()->value = 2; + + // Make a parent view and store the container + auto parentView = new View( "parentView", -1 ); + SG::WriteHandle<TestContainer> wh2( "inParent" ); + wh2.setProxyDict( parentView ).ignore(); + status = wh2.record( std::move( t2 ) ); + VALUE( status.isSuccess() ) EXPECTED( true ); + + // Just test a straightforward element link to the parent + { + SG::ReadHandle<TestContainer> rh( "inParent" ); + auto link = ViewHelper::makeLink( parentView, rh, 0 ); + VALUE( link.isValid() ) EXPECTED( true ); + VALUE( ( *link )->value ) EXPECTED( 3 ); + VALUE( link.proxy()->name() == "_parentView_inParent" ) EXPECTED( true ); + } + + // Element links need to point to the right object + // even if it's not in the current view + { + // Child to parent + auto childView = new View( "childView", -1 ); + childView->linkParent( parentView ); + SG::ReadHandle<TestContainer> rh( "inParent" ); + auto link = ViewHelper::makeLink( childView, rh, 1 ); + VALUE( link.isValid() ) EXPECTED( true ); + VALUE( ( *link )->value ) EXPECTED( 2 ); + VALUE( link.proxy()->name() == "_parentView_inParent" ) EXPECTED( true ); + } + { + // Parent to store + SG::ReadHandle<TestContainer> rh( "inStore" ); + auto link = ViewHelper::makeLink( parentView, rh, 0 ); + VALUE( link.isValid() ) EXPECTED( true ); + VALUE( ( *link )->value ) EXPECTED( 5 ); + VALUE( link.proxy()->name() == "inStore" ) EXPECTED( true ); + } + { + // Child to store + auto childView = new View( "childView", -1 ); + childView->linkParent( parentView ); + SG::ReadHandle<TestContainer> rh( "inStore" ); + auto link = ViewHelper::makeLink( childView, rh, 1 ); + VALUE( link.isValid() ) EXPECTED( true ); + VALUE( ( *link )->value ) EXPECTED( 4 ); + VALUE( link.proxy()->name() == "inStore" ) EXPECTED( true ); + } + log << MSG::INFO << "Fall through works with links as expected" << endmsg; +} int main() { using namespace std; MsgStream log(Athena::getMessageSvc(), "ViewLinking_test"); - // MsgStream* msglog = &log; - - ISvcLocator* pSvcLoc; - //if (!Athena_test::initGaudi("test.txt", pSvcLoc)) { if (!Athena_test::initGaudi("", pSvcLoc)) { log << MSG::ERROR << "Can not intit Gaudi" << endmsg; return -1; @@ -162,6 +227,7 @@ int main() { testDataInView( pStore, log ); testFallThrough( pStore, log ); - + testFallThroughLinks( pStore, log ); + return 0; }