PLCnext API Documentation  22.9.0.33
ModuleFactory.hxx
1 //
3 // Copyright PHOENIX CONTACT Electronics GmbH
4 //
6 #pragma once
7 #include "Arp/System/Core/Arp.h"
8 #include "Arp/System/Commons/Exceptions/ArgumentException.hpp"
9 #include <memory>
10 #include <vector>
11 
12 namespace Arp { namespace System { namespace Commons { namespace Extensibility
13 {
14 
18 template<typename TModuleInterface>
20 {
21 public:
22  // typedefs
23  using ModuleInterfacePtr = std::unique_ptr<TModuleInterface>;
24  using FactoryFunction = std::function<ModuleInterfacePtr()>;
25  using FactoryFunctions = std::vector<std::pair<String, FactoryFunction>>;
26 
27  // construction/destruction
29  ModuleFactory(void) = default;
31  ModuleFactory(const ModuleFactory& arg) = default;
33  ModuleFactory(ModuleFactory&& arg) noexcept = default;
35  ModuleFactory& operator=(const ModuleFactory& arg) = default;
37  ModuleFactory& operator=(ModuleFactory&& arg) noexcept = default;
39  virtual ~ModuleFactory(void) noexcept = default;
40 
44  ModuleInterfacePtr Create(const String& moduleName) const;
45 
47  std::vector<String> GetModuleNames() const;
48 
53  void AddFactoryFunction(const String& moduleName, FactoryFunction function);
54 
55 
56 private:
57  typename FactoryFunctions::const_iterator FindByName(const String& moduleName) const;
58 
59 private:
60  FactoryFunctions factoryFunctions;
61 };
62 
63 
64 template<typename TModuleInterface>
65 typename ModuleFactory<TModuleInterface>::ModuleInterfacePtr ModuleFactory<TModuleInterface>::Create(const String& moduleName) const
66 {
67  auto it = this->FindByName(moduleName);
68  if (it == this->factoryFunctions.end())
69  {
70  return ModuleInterfacePtr{};
71  }
72  else
73  {
74  return it->second();
75  }
76 }
77 
78 template<typename TModuleInterface>
80 {
81  std::vector<String> result;
82  result.reserve(this->factoryFunctions.size());
83  std::transform(this->factoryFunctions.begin(), this->factoryFunctions.end(),
84  std::back_inserter(result), [](const typename FactoryFunctions::value_type & each)
85  {
86  return each.first;
87  });
88  return result;
89 }
90 
91 template<typename TModuleInterface>
93  const String& moduleName, FactoryFunction function)
94 {
95  if (moduleName.IsEmpty())
96  {
97  throw ArgumentException::Create("moduleName", moduleName, "Invalid module name");
98  }
99 
100  if (function == nullptr)
101  {
102  throw ArgumentException::Create("function", static_cast<void*>(nullptr), "Invalid factory function.");
103  }
104 
105  auto it = this->FindByName(moduleName);
106  if (it == this->factoryFunctions.end())
107  {
108  this->factoryFunctions.emplace_back(moduleName, function);
109  }
110  else
111  {
112  throw ArgumentException::Create("moduleName", moduleName, "Duplicate module name");
113  }
114 }
115 
116 template<typename TModuleInterface>
118  const String& moduleName) const
119 {
120  return std::find_if(this->factoryFunctions.begin(), this->factoryFunctions.end(),
121  [&moduleName](const typename FactoryFunctions::value_type & each)
122  {
123  return each.first == moduleName;
124  });
125 }
126 
127 
128 
129 }}}} // namespace Arp::System::Commons::Extensibility
static ArgumentException Create(const char *paramName, const T &paramValue)
Creates an ArgumentException instance using a default message text.
Definition: ArgumentException.hpp:112
Factory class for extension modules
Definition: ModuleFactory.hxx:20
ModuleFactory & operator=(ModuleFactory &&arg) noexcept=default
Move-assignment operator.
void AddFactoryFunction(const String &moduleName, FactoryFunction function)
Adds a factory function
Definition: ModuleFactory.hxx:92
ModuleFactory(const ModuleFactory &arg)=default
Copy constructor.
ModuleFactory(void)=default
Constructs an ModuleFactory instance.
ModuleInterfacePtr Create(const String &moduleName) const
Creates a module instance
Definition: ModuleFactory.hxx:65
virtual ~ModuleFactory(void) noexcept=default
Destructs this instance and frees all resources.
std::vector< String > GetModuleNames() const
Returns all known module names
Definition: ModuleFactory.hxx:79
ModuleFactory & operator=(const ModuleFactory &arg)=default
Copy-assignment operator.
ModuleFactory(ModuleFactory &&arg) noexcept=default
Move constructor.
bool IsEmpty() const
Determines if this string is empty.
Definition: BasicString.hxx:1076
@ System
System components used by the System, Device, Plc or Io domains.
Root namespace for the PLCnext API