PLCnext API Documentation 25.0.2.69
ModuleFactory.hxx
1
2//
3// Copyright Phoenix Contact GmbH & Co. KG
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 ModuleInterfacePtr Create(const String& moduleName) const;
28 std::vector<String> GetModuleNames() const;
29 void AddFactoryFunction(const String& moduleName, FactoryFunction function);
30
31private:
32 typename FactoryFunctions::const_iterator FindByName(const String& moduleName) const;
33
34private:
35 FactoryFunctions factoryFunctions;
36};
37
38
42template<typename TModuleInterface>
43typename ModuleFactory<TModuleInterface>::ModuleInterfacePtr ModuleFactory<TModuleInterface>::Create(const String& moduleName) const
44{
45 auto it = this->FindByName(moduleName);
46 if (it == this->factoryFunctions.end())
47 {
48 return ModuleInterfacePtr{};
49 }
50 else
51 {
52 return it->second();
53 }
54}
55
57template<typename TModuleInterface>
59{
60 std::vector<String> result;
61 result.reserve(this->factoryFunctions.size());
62 std::transform(this->factoryFunctions.begin(), this->factoryFunctions.end(),
63 std::back_inserter(result), [](const typename FactoryFunctions::value_type & each)
64 {
65 return each.first;
66 });
67 return result;
68}
69
74template<typename TModuleInterface>
76 const String& moduleName, FactoryFunction function)
77{
78 if (moduleName.IsEmpty())
79 {
80 throw ArgumentException::Create("moduleName", moduleName, "Invalid module name");
81 }
82
83 if (function == nullptr)
84 {
85 throw ArgumentException::Create("function", static_cast<void*>(nullptr), "Invalid factory function.");
86 }
87
88 auto it = this->FindByName(moduleName);
89 if (it == this->factoryFunctions.end())
90 {
91 this->factoryFunctions.emplace_back(moduleName, function);
92 }
93 else
94 {
95 throw ArgumentException::Create("moduleName", moduleName, "Duplicate module name");
96 }
97}
98
99template<typename TModuleInterface>
101 const String& moduleName) const
102{
103 return std::find_if(this->factoryFunctions.begin(), this->factoryFunctions.end(),
104 [&moduleName](const typename FactoryFunctions::value_type & each)
105 {
106 return each.first == moduleName;
107 });
108}
109
110
111
112}}}} // namespace Arp::System::Commons::Extensibility
static ArgumentException Create(const char *paramName, const T &paramValue)
Creates an ArgumentException using a default message.
Definition: ArgumentException.hpp:92
This class represents the Arp String. The implementation is based on std::string.
Definition: String.hpp:39
bool IsEmpty(void) const
Determines if this string is empty.
Definition: String.ipp:991
Factory class for extension modules
Definition: ModuleFactory.hxx:20
void AddFactoryFunction(const String &moduleName, FactoryFunction function)
Adds a factory function
Definition: ModuleFactory.hxx:75
ModuleInterfacePtr Create(const String &moduleName) const
Creates a module instance
Definition: ModuleFactory.hxx:43
std::vector< String > GetModuleNames() const
Returns all known module names
Definition: ModuleFactory.hxx:58
Root namespace for the PLCnext API