Commit 8e13dac4 authored by Floris Berendsen's avatar Floris Berendsen
Browse files

ENH: moved generic Criteria checks to BaseComponent

Interface related criteria can be handled in the MeetsCriteria in the
BaseComponent as well as the iterator over criteria, other (developer-user) specific Criteria are deligated to
MeetsCriterum per iteration.
parent 0a0a848c
......@@ -32,9 +32,12 @@ namespace selx
virtual interfaceStatus ConnectFrom(const char *, ComponentBase*) = 0;
virtual int ConnectFrom(ComponentBase*) = 0;
virtual bool MeetsCriteria(const CriteriaType &criteria) = 0;
bool MeetsCriteria(const CriteriaType &criteria);
protected:
virtual bool MeetsCriterium(const CriteriumType criterium) { return false; };
virtual bool HasAcceptingInterface(const char *) = 0;
virtual bool HasProvidingInterface(const char *) = 0;
ComponentBase() {};
virtual ~ComponentBase() {};
......
......@@ -44,6 +44,15 @@ struct InterfaceName < OptimizerUpdateInterface >
}
};
template <>
struct InterfaceName < ConflictinUpdateInterface >
{
static const char* Get()
{
return "ConflictinUpdateInterface";
}
};
template <>
struct InterfaceName < TransformedImageInterface >
{
......
......@@ -63,6 +63,8 @@ class Accepting
public:
ComponentBase::interfaceStatus ConnectFromImpl(const char *, ComponentBase*) { return ComponentBase::interfaceStatus::noaccepter; }; //no interface called interfacename ;
int ConnectFromImpl(ComponentBase*) { return 0; }; //Empty RestInterfaces does 0 successful connects ;
protected:
bool HasInterface(const char *) { return false; };
};
template<typename FirstInterface, typename ... RestInterfaces>
......@@ -71,21 +73,45 @@ class Accepting<FirstInterface, RestInterfaces... > : public InterfaceAcceptor<F
public:
ComponentBase::interfaceStatus ConnectFromImpl(const char *, ComponentBase*);
int ConnectFromImpl(ComponentBase*);
protected:
bool HasInterface(const char *);
};
template<typename... Interfaces>
class Providing : public Interfaces...
template<typename ... RestInterfaces>
class Providing
{
protected:
bool HasInterface(const char *) { return false; };
};
template<typename FirstInterface, typename ... RestInterfaces>
class Providing<FirstInterface, RestInterfaces... > : public FirstInterface, public Providing < RestInterfaces ... >
{
protected:
bool HasInterface(const char *);
};
//template<typename... Interfaces>
//class Providing : public Interfaces...
//{
//};
template<typename AcceptingInterfaces, typename ProvidingInterfaces>
class Implements : public AcceptingInterfaces, public ProvidingInterfaces, public ComponentBase
{
public:
virtual interfaceStatus ConnectFrom(const char *, ComponentBase*);
virtual int ConnectFrom(ComponentBase*);
protected:
virtual bool HasAcceptingInterface(const char *);
virtual bool HasProvidingInterface(const char *);
};
} // end namespace selx
#ifndef ITK_MANUAL_INSTANTIATION
......
......@@ -10,14 +10,15 @@ int InterfaceAcceptor<InterfaceT>::Connect(ComponentBase* providerComponent){
InterfaceT* providerInterface = dynamic_cast<InterfaceT*> (providerComponent);
if (!providerInterface)
{
std::cout << "providerComponent does not have required " << InterfaceName < InterfaceT >::Get() << std::endl;
//TODO log message?
//std::cout << "providerComponent does not have required " << InterfaceName < InterfaceT >::Get() << std::endl;
return 0;
}
// connect value interfaces
this->Set(providerInterface); // due to the input argument being uniquely defined in the multiple inheritance tree, all versions of Set() are accessible at component level
return 1;
}
//////////////////////////////////////////////////////////////////////////
template<typename AcceptingInterfaces, typename ProvidingInterfaces>
ComponentBase::interfaceStatus Implements<AcceptingInterfaces, ProvidingInterfaces>::ConnectFrom(const char * interfacename, ComponentBase* other)
{
......@@ -30,6 +31,19 @@ int Implements<AcceptingInterfaces, ProvidingInterfaces>::ConnectFrom(ComponentB
return AcceptingInterfaces::ConnectFromImpl(other);
}
template<typename AcceptingInterfaces, typename ProvidingInterfaces>
bool Implements<AcceptingInterfaces, ProvidingInterfaces>::HasAcceptingInterface(const char * interfacename)
{
return AcceptingInterfaces::HasInterface(interfacename);
}
template<typename AcceptingInterfaces, typename ProvidingInterfaces>
bool Implements<AcceptingInterfaces, ProvidingInterfaces>::HasProvidingInterface(const char * interfacename)
{
return ProvidingInterfaces::HasInterface(interfacename);
}
//////////////////////////////////////////////////////////////////////////
template<typename FirstInterface, typename ... RestInterfaces>
ComponentBase::interfaceStatus Accepting<FirstInterface, RestInterfaces... >::ConnectFromImpl(const char * interfacename, ComponentBase* other)
{
......@@ -65,6 +79,26 @@ int Accepting<FirstInterface, RestInterfaces... >::ConnectFromImpl(ComponentBase
return acceptIF->Connect(other) + Accepting< RestInterfaces ... >::ConnectFromImpl(other);
}
template<typename FirstInterface, typename ... RestInterfaces>
bool Accepting<FirstInterface, RestInterfaces... >::HasInterface(const char* interfacename)
{
if (0 == std::strcmp(InterfaceName<InterfaceAcceptor<FirstInterface>>::Get(), interfacename))
{
return true;
}
return Accepting< RestInterfaces ... >::HasInterface(interfacename);
}
template<typename FirstInterface, typename ... RestInterfaces>
bool Providing<FirstInterface, RestInterfaces... >::HasInterface(const char* interfacename)
{
if (0 == std::strcmp(InterfaceName<FirstInterface>::Get(), interfacename))
{
return true;
}
return Providing< RestInterfaces ... >::HasInterface(interfacename);
}
} // end namespace selx
......
#include "ComponentBase.h"
namespace selx
{
bool ComponentBase::MeetsCriteria(const CriteriaType &criteria)
{
bool hasUndefinedCriteria(false);
bool meetsCriteria(false);
for (CriteriaType::const_iterator it = criteria.begin(); it != criteria.end(); ++it)
{
if (strcmp(it->first.c_str(), "NameOfClass") == 0)
{
if (strcmp(it->second.c_str(), this->GetNameOfClass()) != 0)
{
meetsCriteria = false;
break;
}
}
else if (strcmp(it->first.c_str(), "HasAcceptingInterface") == 0)
{
if (this->HasAcceptingInterface(it->second.c_str()) != true)
{
meetsCriteria = false;
break;
}
}
else if (strcmp(it->first.c_str(), "HasProvidingInterface") == 0)
{
if (this->HasProvidingInterface(it->second.c_str()) != true)
{
meetsCriteria = false;
break;
}
}
else if (this->MeetsCriterium(CriteriumType(it->first, it->second)) != true)
{
meetsCriteria = false;
break;
}
else
{
meetsCriteria = false;
hasUndefinedCriteria = true;
break;
}
}
return meetsCriteria;
}
} // end namespace selx
......@@ -38,7 +38,9 @@ namespace selx
int Set(MetricValueInterface*);
int Set(MetricDerivativeInterface*);
int Update();
virtual bool MeetsCriteria(const CriteriaType &criteria);
//virtual bool MeetsCriteria(const CriteriaType &criteria);
virtual bool MeetsCriterium(const CriteriumType &criterium);
//static const char * GetName() { return "GDOptimizer3rdPartyComponent"; } ;
static const char * GetDescription() { return "GD Optimizer 3rd Party Component"; };
};
......
......@@ -40,7 +40,8 @@ namespace selx
//template <class ConflictinUpdateInterface> virtual int Update() { return 5; };
// "error" : member function templates cannot be virtual
int Update(ConflictinUpdateInterface*) { return 5; };
virtual bool MeetsCriteria(const CriteriaType &criteria);
//virtual bool MeetsCriteria(const CriteriaType &criteria);
virtual bool MeetsCriterium(const CriteriumType &criterium);
//static const char * GetName(){ return "GDOptimizer4thPartyComponent"; };
static const char * GetDescription(){ return "GD Optimizer 4th Party Component"; };
};
......
......@@ -30,6 +30,7 @@ public:
virtual int Set(TransformedImageInterface *);
virtual int GetValue(){ return 0; }
//std::string GetComponentTypeAsString() const;
//static const char * GetName(){ return "MetricComponent1"; };
static const char * GetDescription(){ return "Example Metric Component 1"; };
......@@ -44,8 +45,9 @@ private:
MetricComponent1(const Self &); // purposely not implemented
void operator=(const Self &); // purposely not implemented
virtual bool MeetsCriterium(const CriteriumType &criterium);
//virtual bool MeetsCriteria(const CriteriaType&);
virtual bool MeetsCriteria(const CriteriaType&);
};
} // end namespace selx
......
......@@ -32,7 +32,8 @@ namespace selx
Example3rdParty::SSDMetric3rdParty* theImplementation;
int GetValue();
int GetDerivative();
virtual bool MeetsCriteria(const CriteriaType &criteria);
//virtual bool MeetsCriteria(const CriteriaType &criteria);
virtual bool MeetsCriterium(const CriteriumType &criterium);
static const char * GetName(){ return "SSDMetric3rdPartyComponent"; }
static const char * GetDescription(){ return "SSD Metric 3rd Party Component"; };
};
......
......@@ -31,7 +31,8 @@ namespace selx
virtual ~SSDMetric4thPartyComponent();
Example4thParty::SSDMetric4thParty* theImplementation;
int GetValue();
virtual bool MeetsCriteria(const CriteriaType &criteria);
virtual bool MeetsCriterium(const CriteriumType &criterium);
//virtual bool MeetsCriteria(const CriteriaType &criteria);
//static const char * GetName(){ return "SSDMetric4thPartyComponent"; };
static const char * GetDescription(){ return "SSD Metric 4th Party Component"; };
......
......@@ -32,52 +32,16 @@ int GDOptimizer3rdPartyComponent::Update()
bool
GDOptimizer3rdPartyComponent
::MeetsCriteria(const CriteriaType &criteria)
::MeetsCriterium(const CriteriumType &criterium)
{
bool hasUndefinedCriteria(false);
bool meetsCriteria(true);
for (CriteriaType::const_iterator it = criteria.begin(); it != criteria.end(); ++it)
bool meetsCriteria(false);
if (strcmp(criterium.first.c_str(), "ComponentProperty") == 0)
{
if (strcmp(it->first.c_str(), "NameOfClass") == 0)
{
if (strcmp(it->second.c_str(), this->GetNameOfClass()) != 0)
{
meetsCriteria = false;
break;
}
}
else if (strcmp(it->first.c_str(), "HasDerivative") == 0)
{
if (strcmp(it->second.c_str(), "True") != 0)
{
meetsCriteria = false;
break;
}
}
else if (strcmp(it->first.c_str(), "ComponentOutput") == 0)
if (strcmp(criterium.second.c_str(), "SomeProperty") == 0) // e.g. "GradientDescent", "SupportsSparseSamples
{
if (strcmp(it->second.c_str(), "TransformUpdate") != 0)
{
meetsCriteria = false;
break;
}
meetsCriteria = true;
}
else if (strcmp(it->first.c_str(), "ComponentInput") == 0)
{
if (strcmp(it->second.c_str(), "MetricValue") != 0)
{
meetsCriteria = false;
break;
}
}
else
{
meetsCriteria = false;
hasUndefinedCriteria = true;
break;
}
}
return meetsCriteria;
}
......
......@@ -29,28 +29,16 @@ int GDOptimizer4thPartyComponent::Update()
bool
GDOptimizer4thPartyComponent
::MeetsCriteria(const CriteriaType &criteria)
::MeetsCriterium(const CriteriumType &criterium)
{
bool hasUndefinedCriteria(false);
bool meetsCriteria(true);
for (CriteriaType::const_iterator it = criteria.begin(); it != criteria.end(); ++it)
bool meetsCriteria(false);
if (strcmp(criterium.first.c_str(), "ComponentProperty") == 0)
{
if (strcmp(it->first.c_str(), "NameOfClass") == 0)
{
if (strcmp(it->second.c_str(), this->GetNameOfClass()) != 0)
{
meetsCriteria = false;
break;
}
}
else
if (strcmp(criterium.second.c_str(), "SomeProperty") == 0) // e.g. "GradientDescent", "SupportsSparseSamples
{
meetsCriteria = false;
hasUndefinedCriteria = true;
break;
meetsCriteria = true;
}
}
return meetsCriteria;
}
......
......@@ -31,48 +31,20 @@ int MetricComponent1::Set(TransformedImageInterface* providingInterface)
}
bool
MetricComponent1
::MeetsCriteria(const CriteriaType& criteria)
{
bool hasUndefinedCriteria(false);
bool meetsCriteria(true);
for (CriteriaType::const_iterator it = criteria.begin(); it != criteria.end(); ++it)
MetricComponent1
::MeetsCriterium(const CriteriumType &criterium)
{
if (strcmp(it->first.c_str(), "NameOfClass") == 0)
{
if (strcmp(it->second.c_str(), this->GetNameOfClass()) != 0)
{
meetsCriteria = false;
break;
}
}
else if (strcmp(it->first.c_str(), "ComponentOutput") == 0)
{
if (strcmp(it->second.c_str(), "Metric") != 0)
{
meetsCriteria = false;
break;
}
}
else if (strcmp(it->first.c_str(), "ComponentInput") == 0)
bool hasUndefinedCriteria(false);
bool meetsCriteria(false);
if (strcmp(criterium.first.c_str(), "ComponentProperty") == 0)
{
if (strcmp(it->second.c_str(), "Transform") != 0)
if (strcmp(criterium.second.c_str(), "SomeProperty") == 0) // e.g. "GradientDescent", "SupportsSparseSamples
{
meetsCriteria = false;
break;
meetsCriteria = true;
}
}
else
{
meetsCriteria = false;
hasUndefinedCriteria = true;
break;
}
return meetsCriteria;
}
return meetsCriteria;
}
} // end namespace selx
......
......@@ -22,28 +22,16 @@ int SSDMetric3rdPartyComponent::GetValue()
bool
SSDMetric3rdPartyComponent
::MeetsCriteria(const CriteriaType &criteria)
::MeetsCriterium(const CriteriumType &criterium)
{
bool hasUndefinedCriteria(false);
bool meetsCriteria(true);
for (CriteriaType::const_iterator it = criteria.begin(); it != criteria.end(); ++it)
bool meetsCriteria(false);
if (strcmp(criterium.first.c_str(), "ComponentProperty") == 0)
{
if (strcmp(it->first.c_str(), "NameOfClass") == 0)
{
if (strcmp(it->second.c_str(), this->GetNameOfClass()) != 0)
{
meetsCriteria = false;
break;
}
}
else
if (strcmp(criterium.second.c_str(), "SomeProperty") == 0) // e.g. "GradientDescent", "SupportsSparseSamples
{
meetsCriteria = false;
hasUndefinedCriteria = true;
break;
meetsCriteria = true;
}
}
return meetsCriteria;
}
......
......@@ -18,28 +18,16 @@ int SSDMetric4thPartyComponent::GetValue()
bool
SSDMetric4thPartyComponent
::MeetsCriteria(const CriteriaType &criteria)
::MeetsCriterium(const CriteriumType &criterium)
{
bool hasUndefinedCriteria(false);
bool meetsCriteria(true);
for (CriteriaType::const_iterator it = criteria.begin(); it != criteria.end(); ++it)
bool meetsCriteria(false);
if (strcmp(criterium.first.c_str(), "ComponentProperty") == 0)
{
if (strcmp(it->first.c_str(), "NameOfClass") == 0)
{
if (strcmp(it->second.c_str(), this->GetNameOfClass()) != 0)
{
meetsCriteria = false;
break;
}
}
else
if (strcmp(criterium.second.c_str(), "SomeProperty") == 0) // e.g. "GradientDescent", "SupportsSparseSamples
{
meetsCriteria = false;
hasUndefinedCriteria = true;
break;
meetsCriteria = true;
}
}
return meetsCriteria;
}
......
......@@ -22,6 +22,7 @@ set( ${MODULE}_LIBRARIES
# Module source files
set( ${MODULE}_SOURCE_FILES
${${MODULE}_SOURCE_DIR}/Blueprints/src/elxBlueprint.cxx
${${MODULE}_SOURCE_DIR}/ComponentInterface/src/ComponentBase.cxx
${${MODULE}_SOURCE_DIR}/ExampleComponents/src/Example3rdPartyCode.cxx
${${MODULE}_SOURCE_DIR}/ExampleComponents/src/Example4thPartyCode.cxx
${${MODULE}_SOURCE_DIR}/ExampleComponents/src/GDOptimizer3rdPartyComponent.cxx
......
......@@ -130,8 +130,8 @@ TEST_F(ComponentFactoryTest, InterfacedObjects)
EXPECT_EQ(registeredComponents.size(), 6);
CriteriaType criteria3;
criteria3["NameOfClass"] = "GDOptimizer3rdPartyComponent";
//criteria3["HasDerivative"] = "True";
//criteria3["NameOfClass"] = "GDOptimizer3rdPartyComponent";
criteria3["HasAcceptingInterface"] = "MetricDerivativeInterface";
NodePointer Node3 = ComponentSelector::New();
Node3->SetCriteria(criteria3);
ComponentType::Pointer Node3Component;
......@@ -148,7 +148,8 @@ TEST_F(ComponentFactoryTest, InterfacedObjects)
EXPECT_STREQ(Node4Component->GetNameOfClass(), "GDOptimizer4thPartyComponent");
CriteriaType criteria5;
criteria5["NameOfClass"] = "SSDMetric3rdPartyComponent";
//criteria5["NameOfClass"] = "SSDMetric3rdPartyComponent";
criteria5["HasProvidingInterface"] = "MetricDerivativeInterface";
//criteria3["HasDerivative"] = "True";
NodePointer Node5 = ComponentSelector::New();
Node5->SetCriteria(criteria5);
......@@ -164,6 +165,7 @@ TEST_F(ComponentFactoryTest, InterfacedObjects)
ComponentType::Pointer Node6Component;
EXPECT_NO_THROW(Node6Component = Node6->GetComponent());
EXPECT_STREQ(Node6Component->GetNameOfClass(), "SSDMetric4thPartyComponent");
}
......
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