PLCnext API Documentation 23.6.0.37
ModuleFactory.hxx
1
2//
3// Copyright PHOENIX CONTACT Electronics GmbH
4//
6#pragma once
8#include "Arp/System/Commons/Exceptions/ArgumentException.hpp"
9#include <memory>
10#include <vector>
11
12namespace Arp { namespace System { namespace Commons { namespace Extensibility
13{
14
18template<typename TModuleInterface>
20{
21public:
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
56private:
57 typename FactoryFunctions::const_iterator FindByName(const String& moduleName) const;
58
59private:
60 FactoryFunctions factoryFunctions;
61};
62
63
64template<typename TModuleInterface>
65typename 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
78template<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
91template<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
116template<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:1086
Root namespace for the PLCnext API