From 126b64a2322cf49040e7b1beb20691f14aac7741 Mon Sep 17 00:00:00 2001 From: Floris Berendsen <floris.berendsen@gmail.com> Date: Tue, 6 Oct 2015 17:47:05 +0200 Subject: [PATCH] ENH: A ComponentFactory Object now has Set- & Add Criteria, and maintains its own possibleComponent list. --- Modules/Core/Install/itkComponentFactory.h | 14 ++-- Modules/Core/Install/itkComponentFactory.hxx | 69 +++++++++++++------- Modules/Core/Install/itkfactory.cxx | 45 +++++++++++-- 3 files changed, 97 insertions(+), 31 deletions(-) diff --git a/Modules/Core/Install/itkComponentFactory.h b/Modules/Core/Install/itkComponentFactory.h index 02d5882d..cdf5a032 100644 --- a/Modules/Core/Install/itkComponentFactory.h +++ b/Modules/Core/Install/itkComponentFactory.h @@ -42,6 +42,9 @@ public: /** Run-time type information (and related methods). */ itkTypeMacro(ComponentFactory, Object); + + /** New macro for creation of through the object factory. */ + itkNewMacro(Self); /** Convenient typedefs. */ typedef ComponentBase::Pointer ComponentBasePointer; @@ -49,21 +52,22 @@ public: typedef std::list< typename ComponentBasePointer > ComponentListType; /** set selection criteria for possibleComponents*/ + void Initialize(); void SetCriteria(const CriteriaType &criteria); /** Narrow selection criteria*/ void AddCriteria(const CriteriaType &criteria); - + + void UpdatePossibleComponents(void); /** Create the appropriate ComponentIO depending on * the particulars of the file. */ - static ComponentBasePointer - CreateComponent(const CriteriaType &criteria); - + ComponentBasePointer GetComponent(void); + protected: - CriteriaType m_Criteria; + mutable CriteriaType m_Criteria; mutable ComponentListType m_PossibleComponents; ComponentFactory(); ~ComponentFactory(); diff --git a/Modules/Core/Install/itkComponentFactory.hxx b/Modules/Core/Install/itkComponentFactory.hxx index 4b6fa215..4f4021f6 100644 --- a/Modules/Core/Install/itkComponentFactory.hxx +++ b/Modules/Core/Install/itkComponentFactory.hxx @@ -31,35 +31,60 @@ ComponentFactory::~ComponentFactory() { } - - -ComponentBase::Pointer ComponentFactory::CreateComponent(const CriteriaType &criteria) +void ComponentFactory::Initialize() { - std::list< typename ComponentBase::Pointer > possibleComponents; -// std::list< LightObject::Pointer > allobjects = -// ObjectFactoryBase::CreateAllInstance("itkComponentIOBaseTemplate"); std::list< LightObject::Pointer > allobjects = ObjectFactoryBase::CreateAllInstance("itkComponentBase"); - for ( std::list< LightObject::Pointer >::iterator i = allobjects.begin(); - i != allobjects.end(); ++i ) - { + for (std::list< LightObject::Pointer >::iterator i = allobjects.begin(); + i != allobjects.end(); ++i) + { ComponentBase *io = - dynamic_cast< ComponentBase * >( i->GetPointer() ); - if ( io ) - { - possibleComponents.push_back(io); - } - } - for (std::list< typename ComponentBase::Pointer >::iterator k = possibleComponents.begin(); - k != possibleComponents.end(); ++k) + dynamic_cast<ComponentBase *>(i->GetPointer()); + if (io) { - if ( ( *k )->MeetsCriteria(criteria) ) - { - return *k; - } + this->m_PossibleComponents.push_back(io); } - return ITK_NULLPTR; + } +} +void ComponentFactory::SetCriteria(const CriteriaType &criteria) +{ + this->Initialize(); + this->m_Criteria = criteria; + this->Modified(); + +} + +void ComponentFactory::AddCriteria(const CriteriaType &criteria) +{ + this->m_Criteria.insert(criteria.begin(), criteria.end()); + this->Modified(); +} + +// a predicate implemented as a class: +//struct FailsCriteria { +// bool operator() (const ComponentBasePointer& component) { return !component->MeetsCriteria(this->m_Criteria) } +//}; + +void ComponentFactory::UpdatePossibleComponents() +{ + // Check each possible component if it meets the criteria + // Using a Lambda function. + this->m_PossibleComponents.remove_if([&](ComponentBasePointer component){ return !component->MeetsCriteria(this->m_Criteria); }); +} +ComponentFactory::ComponentBasePointer ComponentFactory::GetComponent() +{ + //TODO check if Modified + this->UpdatePossibleComponents(); + + if (this->m_PossibleComponents.size() == 1) + { + return *(this->m_PossibleComponents.begin()); + } + else + { + return ITK_NULLPTR; + } } } // end namespace itk diff --git a/Modules/Core/Install/itkfactory.cxx b/Modules/Core/Install/itkfactory.cxx index b63a1805..ab4153da 100644 --- a/Modules/Core/Install/itkfactory.cxx +++ b/Modules/Core/Install/itkfactory.cxx @@ -60,9 +60,9 @@ int main(int argc, char *argv[]) << registeredComponents.size() << " Component objects available to the Overlord.\n" << std::endl; - std::cout << "After registering the TransformComponent1 object, "; itk::TransformComponent1Factory::RegisterOneFactory(); itk::MetricComponent1Factory::RegisterOneFactory(); + std::cout << "After registering the TransformComponent1 and MetricComponent1object, "; std::cout << "there are\n"; registeredComponents = itk::ObjectFactoryBase::CreateAllInstance("itkComponentBase"); std::cout << registeredComponents.size() @@ -80,10 +80,47 @@ int main(int argc, char *argv[]) criteria2["ComponentInput"] = "Transform"; //criteria1.insert(CriteriumType("ComponentInput", "Metric")); + CriteriaType emptyCriteria; + + typedef itk::ComponentFactory::Pointer NodePointer; + + NodePointer Node1 = itk::ComponentFactory::New(); + Node1->SetCriteria(emptyCriteria); + ComponentType::Pointer Node1Component = Node1->GetComponent(); + if (Node1Component.IsNull()) + { + std::cout << "Too few criteria means no Component could be selected." << std::endl; + } + else + { + std::cout << "FAILED" << std::endl; + } + + // Narrow down the selection criteria + Node1->AddCriteria(criteria1); + Node1Component = Node1->GetComponent(); + if (Node1Component.IsNull()) + { + std::cout << "FAILED" << std::endl; + } + else + { + std::cout << "Based on criteria, Node1 selected: " << Node1Component->GetNameOfClass() << std::endl; + } + + NodePointer Node2 = itk::ComponentFactory::New(); + Node2->SetCriteria(criteria2); + ComponentType::Pointer Node2Component = Node2->GetComponent(); + if (Node2Component.IsNull()) + { + std::cout << "FAILED" << std::endl; + } + else + { + std::cout << "Based on criteria, Node2 selected: " << Node2Component->GetNameOfClass() << std::endl; + } + - ComponentType::Pointer Node1 = itk::ComponentFactory::CreateComponent(criteria1); - - ComponentType::Pointer Node2 = itk::ComponentFactory::CreateComponent(criteria2); -- GitLab