From 5d6de1acdbee38b4501468daf0d1ad18d64bf6e4 Mon Sep 17 00:00:00 2001
From: Kasper Marstal <kaspermarstal@gmail.com>
Date: Thu, 22 Oct 2015 17:36:12 +0200
Subject: [PATCH] ENH: Add/Get/Set component

---
 .../Core/Blueprints/include/elxBlueprint.h    | 56 ++++++-----
 .../include/elxComponentDescriptor.h          | 34 -------
 Modules/Core/Blueprints/src/elxBlueprint.cxx  | 98 ++++++++++++-------
 .../Blueprints/src/elxComponentDescriptor.cxx | 18 ----
 Testing/Unit/elxBluePrintTest.cxx             | 25 ++---
 5 files changed, 106 insertions(+), 125 deletions(-)
 delete mode 100644 Modules/Core/Blueprints/include/elxComponentDescriptor.h
 delete mode 100644 Modules/Core/Blueprints/src/elxComponentDescriptor.cxx

diff --git a/Modules/Core/Blueprints/include/elxBlueprint.h b/Modules/Core/Blueprints/include/elxBlueprint.h
index 8b42694b..81b2c92a 100644
--- a/Modules/Core/Blueprints/include/elxBlueprint.h
+++ b/Modules/Core/Blueprints/include/elxBlueprint.h
@@ -1,55 +1,57 @@
 #ifndef __Blueprint_h
 #define __Blueprint_h
 
+#include "boost/graph/graph_traits.hpp"
+#include "boost/graph/directed_graph.hpp"
+
 #include "itkObjectFactory.h"
 #include "itkDataObject.h"
 
 #include "elxMacro.h"
-#include "elxComponentDescriptor.h"
-
-#include "boost/graph/graph_traits.hpp"
-#include "boost/graph/directed_graph.hpp"
 
 namespace elx {
 
-template< class TComponentDescriptor >
 class Blueprint : public itk::DataObject
 {
 public:
 
   elxNewMacro( Blueprint, itk::DataObject );
 
-  typedef TComponentDescriptor                                                ComponentDescriptorType;
-  typedef typename TComponentDescriptor::ComponentNameType                    ComponentNameType;
+  typedef std::string                                                ParameterKeyType;
+  typedef std::vector< std::string >                                 ParameterValueType;
+  typedef std::map< ParameterKeyType, ParameterValueType >           ParameterMapType;
+
+  struct ComponentPropertyType { 
+    ParameterMapType parameterMap;
+  };
+
+  struct ConnectionPropertyType { 
+    ParameterMapType parameterMap;
+  };
   
   typedef boost::adjacency_list< boost::vecS,      
                                  boost::vecS,      
                                  boost::directedS,
-                                 ComponentDescriptorType >                    GraphType;
-
-  typedef typename boost::graph_traits< GraphType >::vertex_descriptor        ComponentType;
-  typedef typename boost::graph_traits< GraphType >::vertex_iterator          ComponentIterator, ComponentIteratorEnd;
-
-  typedef boost::vertex_index_t                                               ComponentIndexType;
-  typedef typename boost::property_map< GraphType, ComponentIndexType >::type ComponentIndexMapType;
+                                 ComponentPropertyType,
+                                 ConnectionPropertyType >            GraphType;
 
-  typedef typename boost::graph_traits< GraphType >::edge_descriptor          ConnectionDescriptorType;
-  typedef typename boost::graph_traits< GraphType >::edge_iterator            ConnectionIterator, ConnectionIteratorEnd;
+  typedef boost::graph_traits< GraphType >::vertex_descriptor        ComponentIndexType;
+  typedef boost::graph_traits< GraphType >::vertex_iterator          ComponentIterator, ComponentIteratorEnd;
 
-  typedef typename boost::graph_traits< GraphType >::in_edge_iterator         InputIterator, InputIteratorEnd;
-  typedef typename boost::graph_traits< GraphType >::out_edge_iterator        OutputIterator, OutputIteratorEnd;
+  typedef boost::graph_traits< GraphType >::edge_descriptor          ConnectionIndexType;
+  typedef boost::graph_traits< GraphType >::edge_iterator            ConnectionIterator, ConnectionIteratorEnd;
 
-  int TestFunction( void );
-  bool AddComponent( ComponentDescriptorType component );
-  bool SetComponent( ComponentIndexType componentIndex, ComponentDescriptorType component );
-  ComponentDescriptorType GetComponent( ComponentIndexType componentIndex );
-  bool RemoveComponent( ComponentDescriptorType component );
+  typedef boost::graph_traits< GraphType >::in_edge_iterator         InputIterator, InputIteratorEnd;
+  typedef boost::graph_traits< GraphType >::out_edge_iterator        OutputIterator, OutputIteratorEnd;
 
-  bool SetConnection( ComponentIndexType upstream, ComponentIndexType downstream );
-  ConnectionDescriptorType GetConnection( ConnectionDescriptorType Connection );
-  bool RemoveConnection( ConnectionDescriptorType connection );
+  ComponentIndexType AddComponent( void );
+  ComponentIndexType AddComponent( ParameterMapType parameterMap );
+  ParameterMapType GetComponent( ComponentIndexType componentDescriptor );
+  void SetComponent( ComponentIndexType, ParameterMapType parameterMap );
 
-  void PrintGraph( void );
+  const ParameterMapType& operator[]( ComponentIndexType index ) {
+    return this->GetComponent( index );
+  }
 
 private:
 
diff --git a/Modules/Core/Blueprints/include/elxComponentDescriptor.h b/Modules/Core/Blueprints/include/elxComponentDescriptor.h
deleted file mode 100644
index 8f5402e4..00000000
--- a/Modules/Core/Blueprints/include/elxComponentDescriptor.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef __ComponentDescriptor_h
-#define __ComponentDescriptor_h
-
-#include "elxMacro.h"
-#include "itkObjectFactory.h"
-#include "itkDataObject.h"
-
-namespace elx {
-
-class ComponentDescriptor : public itk::DataObject
-{
-public:
-
-  elxNewMacro( ComponentDescriptor, itk::DataObject );
-
-  // Identifier to find component in the component database
-  typedef std::string ComponentNameType;
-
-  ComponentDescriptor( void ) { this->SetComponentName( ComponentNameType() ); }
-  ComponentDescriptor( const ComponentNameType componentName );
-
-  // TODO: Setter should validate ComponentName exists in ComponentDatabase
-  itkSetMacro( ComponentName, ComponentNameType ); 
-  itkGetMacro( ComponentName, ComponentNameType );
-
-private:
-
-  ComponentNameType m_ComponentName;
-
-};
-
-}
-
-#endif // __ComponentDescriptor_h
diff --git a/Modules/Core/Blueprints/src/elxBlueprint.cxx b/Modules/Core/Blueprints/src/elxBlueprint.cxx
index b3319d01..26ed00a1 100644
--- a/Modules/Core/Blueprints/src/elxBlueprint.cxx
+++ b/Modules/Core/Blueprints/src/elxBlueprint.cxx
@@ -7,70 +7,98 @@
 
 namespace elx {
 
-/*
-Blueprint< ComponentDescriptor >::ComponentDescriptorType
-Blueprint< ComponentDescriptor >
-::AddComponent( ComponentDescriptorType component )
+Blueprint::ComponentIndexType
+Blueprint
+::AddComponent( void )
 {
-  // TODO: Check that the component is in the ComponentDatabase
   this->Modified();
-  return this->m_Graph->add_vertex( component );
+
+  // Create vertex
+  ComponentIndexType index = boost::add_vertex( this->m_Graph );
+
+  // Return component index so component can retrieved at a later time
+  return index;
 }
 
-bool
-Blueprint< ComponentDescriptor >
-::SetComponent( ComponentDescriptorType component )
+Blueprint::ComponentIndexType
+Blueprint
+::AddComponent( ParameterMapType parameterMap )
 {
   this->Modified();
-  return this->m_Graph->remove_vertex( connection );
+
+  // Create vertex
+  ComponentIndexType index = boost::add_vertex( this->m_Graph );
+  
+  // Add parameter map to vertex
+  this->m_Graph[index].parameterMap = parameterMap;
+
+  // Return component index so component can retrieved at a later time
+  return index;
 }
 
-bool
-Blueprint< ComponentDescriptor >
-::RemoveComponent( ComponentDescriptorType component )
+Blueprint::ParameterMapType
+Blueprint
+::GetComponent( ComponentIndexType index )
 {
   this->Modified();
-  return this->m_Graph->remove_vertex( connection );
+  return this->m_Graph[index].parameterMap;
 }
 
-bool
-Blueprint< ComponentDescriptor >
-::AddConnection( ComponentDescriptorType upsteam, ComponentDescriptorType downstream )
+void
+Blueprint
+::SetComponent( ComponentIndexType index, ParameterMapType parameterMap )
 {
   this->Modified();
-  return this->m_Graph->add_edge( upstream, downstream );
+  this->m_Graph[index].parameterMap = parameterMap;
 }
 
-ConnectionDescriptorType
-Blueprint< ComponentDescriptor >
-::GetConnection( ConnectionDescriptorType Connection )
+/*
+void
+Blueprint
+::RemoveComponent( ComponentIndexType component )
 {
   this->Modified();
+  clear_vertex(u, this->m_Graph);
+  remove_vertex(u, this->m_Graph);
 }
 
-void 
-Blueprint< ComponentDescriptor >
-::RemoveConnection( ConnectionType connection )
+/*
+void
+Blueprint
+::SetConnection( ComponentDescriptor upstream, ComponentDescriptor downstream )
+{
+  this->Modified();
+}
+
+void
+Blueprint
+::GetConnection( ConnectionDescriptorType Connection )
 {
   this->Modified();
-  this->m_Graph->remove_edge( connection );
 }
 
 void 
-Blueprint< ComponentDescriptor >
-::PrintGraph( void )
+Blueprint
+::RemoveConnection( ConnectionDescriptorType connection )
 {
-  // TODO: Link to graphviz library
-  // boost::write_graphviz(std::cout, this->m_Graph);
-  std::cout << "Printed graph" << std::endl;
+  this->Modified();
 }
 */
 
-template<>
-int
-Blueprint< ComponentDescriptor >
-::TestFunction( void )
-{ return 0; }
+// Blueprint::ComponentDescriptorType
+// Blueprint
+// ::GetComponentDescriptor( ComponentIndexType componentIndex )
+// {
+
+// }
+
+// void 
+// Blueprint
+// ::PrintGraph( void )
+// {
+//   // TODO: Link to graphviz library
+//   boost::write_graphviz(std::cout, this->m_Graph);
+// }
 
 } // namespace elx 
 
diff --git a/Modules/Core/Blueprints/src/elxComponentDescriptor.cxx b/Modules/Core/Blueprints/src/elxComponentDescriptor.cxx
deleted file mode 100644
index 95894517..00000000
--- a/Modules/Core/Blueprints/src/elxComponentDescriptor.cxx
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef __ComponentDescriptor_cxx
-#define __ComponentDescriptor_cxx
-
-#include "elxComponentDescriptor.h"
-
-// TODO: Need enum for component name?
-
-namespace elx {
-
-ComponentDescriptor
-::ComponentDescriptor( const ComponentNameType componentName )
-{
-  this->SetComponentName( componentName );
-}
-
-} // namespace elx
-
-#endif // __ComponentDescriptor_cxx
\ No newline at end of file
diff --git a/Testing/Unit/elxBluePrintTest.cxx b/Testing/Unit/elxBluePrintTest.cxx
index 8aa289fc..4f299bc6 100644
--- a/Testing/Unit/elxBluePrintTest.cxx
+++ b/Testing/Unit/elxBluePrintTest.cxx
@@ -1,27 +1,30 @@
 #include "elxBlueprint.h"
-#include "elxComponentDescriptor.h"
+
 #include "gtest/gtest.h"
 
 namespace elx {
 
 TEST( Blueprint, Instantiation )
 {
-  typedef Blueprint< ComponentDescriptor > BlueprintType;
+  typedef Blueprint BlueprintType;
   BlueprintType::Pointer blueprint;
   EXPECT_NO_THROW( blueprint = BlueprintType::New() );
+  
+  BlueprintType::ParameterMapType parameterMap;
+  EXPECT_NO_THROW( parameterMap["ComponentName"] = BlueprintType::ParameterValueType(1, "AdvancedMeanSquares") );
 
-  typedef BlueprintType::ComponentDescriptorType ComponentDescriptorType;
-  ComponentDescriptorType::Pointer componentDescriptor;
-  EXPECT_NO_THROW( componentDescriptor = ComponentDescriptorType::New() );
+  BlueprintType::ComponentIndexType index;
+  EXPECT_NO_THROW( index = blueprint->AddComponent() );
+  EXPECT_EQ( BlueprintType::ComponentIndexType(0), index );
 
-  typedef ComponentDescriptorType::ComponentNameType ComponentNameType;
-  ComponentNameType componentName;
-  EXPECT_NO_THROW( componentName = ComponentNameType("Metric") );
-  EXPECT_NO_THROW( componentDescriptor->SetComponentName( componentName ) );
+  EXPECT_NO_THROW( index = blueprint->AddComponent( parameterMap ) );
+  EXPECT_EQ( BlueprintType::ComponentIndexType(1), index );
 
-  EXPECT_NO_THROW( blueprint->TestFunction() );
+  BlueprintType::ParameterMapType parameterMapTest;
+  EXPECT_NO_THROW( parameterMapTest = blueprint->GetComponent( index ) );
+  EXPECT_EQ( parameterMap["ComponentName"], parameterMapTest["ComponentName"] );
 
-  ASSERT_TRUE( true );
+  blueprint[index];
 }
 
 } // namespace elx
-- 
GitLab