Commit 301e21ec authored by Floris Berendsen's avatar Floris Berendsen
Browse files

ENH refactoring of Handshake: AcceptConnectionFrom uses any criteria

instead of a name only
parent b7570fef
......@@ -55,7 +55,7 @@ public:
typedef std::map< std::string, std::string > InterfaceCriteriaType;
virtual InterfaceStatus AcceptConnectionFrom( const char *, ComponentBase * ) = 0;
virtual int AcceptConnectionFrom(ComponentBase*, const InterfaceCriteriaType) = 0;
virtual int AcceptConnectionFrom( ComponentBase * ) = 0;
......
......@@ -59,7 +59,7 @@ class Accepting<>
{
public:
static unsigned int CountMeetsCriteria(const ComponentBase::InterfaceCriteriaType) { return 0; }
InterfaceStatus ConnectFromImpl(const char *, ComponentBase *) { return InterfaceStatus::noaccepter; } //no interface called interfacename ;
int ConnectFromImpl(ComponentBase* other, const ComponentBase::InterfaceCriteriaType interfaceCriteria) { return 0; } //no interface called interfacename ;
InterfaceStatus CanAcceptConnectionFrom(ComponentBase* other, const ComponentBase::InterfaceCriteriaType interfaceCriteria) { return InterfaceStatus::noaccepter; }
int ConnectFromImpl(ComponentBase *) { return 0; } //Empty RestInterfaces does 0 successful connects ;
......@@ -73,7 +73,7 @@ class Accepting< FirstInterface, RestInterfaces ... > : public InterfaceAcceptor
{
public:
static unsigned int CountMeetsCriteria(const ComponentBase::InterfaceCriteriaType);
InterfaceStatus ConnectFromImpl(const char *, ComponentBase *);
int ConnectFromImpl(ComponentBase* other, const ComponentBase::InterfaceCriteriaType interfaceCriteria);
InterfaceStatus CanAcceptConnectionFrom(ComponentBase* other, const ComponentBase::InterfaceCriteriaType interfaceCriteria);
int ConnectFromImpl( ComponentBase * );
......@@ -130,8 +130,7 @@ public:
using AcceptingInterfacesTypeList = AcceptingInterfaces;
using ProvidingInterfacesTypeList = ProvidingInterfaces;
// todo replace interfacename with interfaceCriteria
virtual InterfaceStatus AcceptConnectionFrom( const char *, ComponentBase * );
virtual int AcceptConnectionFrom(ComponentBase * other, const InterfaceCriteriaType interfaceCriteria);
virtual int AcceptConnectionFrom( ComponentBase * );
......
......@@ -49,10 +49,10 @@ InterfaceAcceptor< InterfaceT >::CanAcceptConnectionFrom(ComponentBase * provide
//////////////////////////////////////////////////////////////////////////
template< typename AcceptingInterfaces, typename ProvidingInterfaces >
InterfaceStatus
SuperElastixComponent< AcceptingInterfaces, ProvidingInterfaces >::AcceptConnectionFrom( const char * interfacename, ComponentBase * other )
int
SuperElastixComponent< AcceptingInterfaces, ProvidingInterfaces >::AcceptConnectionFrom(ComponentBase * other, const InterfaceCriteriaType interfaceCriteria)
{
return AcceptingInterfaces::ConnectFromImpl( interfacename, other );
return AcceptingInterfaces::ConnectFromImpl(other, interfaceCriteria);
}
......@@ -73,28 +73,21 @@ SuperElastixComponent< AcceptingInterfaces, ProvidingInterfaces >
//////////////////////////////////////////////////////////////////////////
template< typename FirstInterface, typename ... RestInterfaces >
InterfaceStatus
Accepting< FirstInterface, RestInterfaces ... >::ConnectFromImpl( const char * interfacename, ComponentBase * other )
int
Accepting< FirstInterface, RestInterfaces ... >::ConnectFromImpl(ComponentBase * other, const ComponentBase::InterfaceCriteriaType interfaceCriteria)
{
// does our component have an accepting interface called interfacename?
if( InterfaceName< InterfaceAcceptor< FirstInterface >>::Get() == std::string( interfacename ) )
// Does our component have an accepting interface sufficing the right criteria (e.g interfaceName)?
if (Count<FirstInterface>::MeetsCriteria(interfaceCriteria) == 1) // We use the FirstInterface only (of each recursion level), thus the count can be 0 or 1
{
// cast always succeeds since we know via the template arguments of the component which InterfaceAcceptors its base classes are.
InterfaceAcceptor< FirstInterface > * acceptIF = this;
// See if the other component has the right interface and try to connect them
if( 1 == acceptIF->Connect( other ) )
{
//success. By terminating this function, we assume only one interface listens to interfacename and that one connection with the other component can be made by this name
return InterfaceStatus::success;
}
else
{
// interfacename was found, but other component doesn't match
return InterfaceStatus::noprovider;
}
// Make the connection to the other component by this interface and add the number of successes.
return acceptIF->Connect(other) + Accepting< RestInterfaces ... >::ConnectFromImpl(other, interfaceCriteria);
}
else
{
return Accepting< RestInterfaces ... >::ConnectFromImpl(other, interfaceCriteria);
}
return Accepting< RestInterfaces ... >::ConnectFromImpl( interfacename, other );
}
......
......@@ -282,22 +282,17 @@ Overlord::ConnectComponents()
ComponentBase::Pointer targetComponent = this->m_ComponentSelectorContainer[ outgoingName ]->GetComponent();
Blueprint::ParameterMapType connectionProperties = this->m_Blueprint->GetConnection( name, outgoingName );
int numberOfConnections = 0;
if( connectionProperties.count( keys::NameOfInterface ) > 0 )
{
// connect only via interfaces provided by user configuration
for( auto const & interfaceName : connectionProperties[ keys::NameOfInterface ] )
{
numberOfConnections
+= ( targetComponent->AcceptConnectionFrom( interfaceName.c_str(),
sourceComponent) == InterfaceStatus::success ? 1 : 0);
}
}
else
{
// connect via all possible interfaces
numberOfConnections = targetComponent->AcceptConnectionFrom( sourceComponent );
}
ComponentBase::InterfaceCriteriaType interfaceCriteria;
std::for_each(connectionProperties.begin(), connectionProperties.end(), [&interfaceCriteria](Blueprint::ParameterMapType::value_type kv) mutable { if (kv.second.size() > 0) interfaceCriteria[kv.first] = kv.second[0]; });
int numberOfConnections = targetComponent->AcceptConnectionFrom(sourceComponent, interfaceCriteria);
//todo cleanup: if interfaceCriteria is empty we could call
// numberOfConnections = targetComponent->AcceptConnectionFrom( sourceComponent );
// to connect via all possible interfaces, but the effect is equal to calling AcceptConnectionFrom
// with empty interfaceCriteria except for speed and clarity ?
if( numberOfConnections == 0 )
{
......
......@@ -93,26 +93,29 @@ TEST_F( InterfaceTest, DynamicCast )
TEST_F( InterfaceTest, ConnectByName )
{
InterfaceStatus IFstatus;
EXPECT_NO_THROW( IFstatus = optimizer3p->AcceptConnectionFrom( "MetricValueInterface", metric3p ) );
EXPECT_NO_THROW(IFstatus = optimizer3p->CanAcceptConnectionFrom( metric3p, { { "NameOfInterface", "MetricValueInterface" } }));
EXPECT_EQ( IFstatus, InterfaceStatus::success );
EXPECT_NO_THROW( IFstatus = optimizer3p->AcceptConnectionFrom( "MetricValueInterface", metric4p ) );
EXPECT_NO_THROW(IFstatus = optimizer3p->CanAcceptConnectionFrom( metric4p, { { "NameOfInterface", "MetricValueInterface" } }));
EXPECT_EQ( IFstatus, InterfaceStatus::success );
EXPECT_NO_THROW( IFstatus = optimizer4p->AcceptConnectionFrom( "MetricValueInterface", metric3p ) );
EXPECT_NO_THROW(IFstatus = optimizer4p->CanAcceptConnectionFrom( metric3p, { { "NameOfInterface", "MetricValueInterface" } }));
EXPECT_EQ( IFstatus, InterfaceStatus::success );
EXPECT_NO_THROW( IFstatus = optimizer4p->AcceptConnectionFrom( "MetricValueInterface", metric4p ) );
EXPECT_NO_THROW(IFstatus = optimizer4p->CanAcceptConnectionFrom( metric4p, { { "NameOfInterface", "MetricValueInterface" } }));
EXPECT_EQ( IFstatus, InterfaceStatus::success );
EXPECT_NO_THROW( IFstatus = optimizer3p->AcceptConnectionFrom( "MetricDerivativeInterface", metric3p ) );
EXPECT_NO_THROW(IFstatus = optimizer3p->CanAcceptConnectionFrom( metric3p, { { "NameOfInterface", "MetricDerivativeInterface" } }));
EXPECT_EQ( IFstatus, InterfaceStatus::success );
EXPECT_NO_THROW( IFstatus = optimizer3p->AcceptConnectionFrom( "MetricDerivativeInterface", metric4p ) );
EXPECT_NO_THROW(IFstatus = optimizer3p->CanAcceptConnectionFrom( metric4p, { { "NameOfInterface", "MetricDerivativeInterface" } }));
EXPECT_EQ( IFstatus, InterfaceStatus::noprovider );
EXPECT_NO_THROW( IFstatus = optimizer4p->AcceptConnectionFrom( "MetricDerivativeInterface", metric3p ) );
EXPECT_NO_THROW(IFstatus = optimizer4p->CanAcceptConnectionFrom( metric3p, { { "NameOfInterface", "MetricDerivativeInterface" } }));
EXPECT_EQ( IFstatus, InterfaceStatus::noaccepter );
EXPECT_NO_THROW(IFstatus = optimizer3p->CanAcceptConnectionFrom(metric3p, { }));
EXPECT_EQ(IFstatus, InterfaceStatus::multiple);
}
TEST_F( InterfaceTest, ConnectAll )
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment