Mantid
Loading...
Searching...
No Matches
DynamicFactory.h
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2007 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7#pragma once
8
9//----------------------------------------------------------------------
10// Includes
11//----------------------------------------------------------------------
13#include "MantidKernel/DllConfig.h"
17
18// Poco
19#include <Poco/Notification.h>
20#include <Poco/NotificationCenter.h>
21
22// std
23#include <functional>
24#include <iterator>
25#include <memory>
26#include <vector>
27
28namespace Mantid {
29namespace Kernel {
30
31//----------------------------------------------------------------------------
32// Forward declarations
33//----------------------------------------------------------------------------
34class Logger;
35
36using CaseSensitiveStringComparator = std::less<std::string>;
37
41class MANTID_KERNEL_DLL DynamicFactoryNotification : public Poco::Notification {
42public:
44};
45
51public:
53};
54
64template <class Base, class Comparator = CaseInsensitiveStringComparator> class DynamicFactory {
65
66public:
71 DynamicFactory(const DynamicFactory &) = delete;
73
76
81
86
91 virtual ~DynamicFactory() = default;
92
99 virtual std::shared_ptr<Base> create(const std::string &className) const {
100 auto it = _map.find(className);
101 if (it != _map.end())
102 return it->second->createInstance();
103 else
104 throw Exception::NotFoundError("DynamicFactory: " + className + " is not registered.\n", className);
105 }
106
116 virtual Base *createUnwrapped(const std::string &className) const {
117 auto it = _map.find(className);
118 if (it != _map.end())
119 return it->second->createUnwrappedInstance();
120 else
121 throw Exception::NotFoundError("DynamicFactory: " + className + " is not registered.\n", className);
122 }
123
130 template <class C> void subscribe(const std::string &className) {
131 subscribe(className, std::make_unique<Instantiator<C, Base>>());
132 }
133
145 void subscribe(const std::string &className, std::unique_ptr<AbstractFactory> pAbstractFactory,
146 SubscribeAction replace = ErrorIfExists) {
147 if (className.empty()) {
148 throw std::invalid_argument("Cannot register empty class name");
149 }
150
151 auto it = _map.find(className);
152 if (it == _map.end() || replace == OverwriteCurrent) {
153 _map[className] = std::move(pAbstractFactory);
155 } else {
156 throw std::runtime_error(className + " is already registered.\n");
157 }
158 }
159
164 void unsubscribe(const std::string &className) {
165 auto it = _map.find(className);
166 if (!className.empty() && it != _map.end()) {
167 _map.erase(it);
169 } else {
170 throw Exception::NotFoundError("DynamicFactory:" + className + " is not registered.\n", className);
171 }
172 }
173
177 bool exists(const std::string &className) const { return _map.find(className) != _map.end(); }
178
181 virtual const std::vector<std::string> getKeys() const {
182 std::vector<std::string> names;
183 names.reserve(_map.size());
184 std::transform(
185 _map.cbegin(), _map.cend(), std::back_inserter(names),
186 [](const std::pair<const std::string, std::unique_ptr<AbstractFactory>> &mapPair) { return mapPair.first; });
187 return names;
188 }
189
194 Poco::NotificationCenter notificationCenter;
195
196protected:
199
200private:
208
210 using FactoryMap = std::map<std::string, std::unique_ptr<AbstractFactory>, Comparator>;
215};
216
217} // namespace Kernel
218} // namespace Mantid
Base class for dynamic factory notifications.
A notification that the factory has been updated.
The dynamic factory is a base dynamic factory for serving up objects in response to requests from oth...
FactoryMap _map
The map holding the registered class names and their instantiators.
virtual Base * createUnwrapped(const std::string &className) const
Creates a new instance of the class with the given name, which is not wrapped in a boost shared_ptr.
std::map< std::string, std::unique_ptr< AbstractFactory >, Comparator > FactoryMap
A typedef for the map of registered classes.
DynamicFactory(const DynamicFactory &)=delete
void subscribe(const std::string &className)
Registers the instantiator for the given class with the DynamicFactory.
DynamicFactory & operator=(const DynamicFactory &)=delete
void unsubscribe(const std::string &className)
Unregisters the given class and deletes the instantiator for the class.
virtual std::shared_ptr< Base > create(const std::string &className) const
Creates a new instance of the class with the given name.
DynamicFactory()
Protected constructor for base class.
virtual const std::vector< std::string > getKeys() const
Returns the keys in the map.
void sendUpdateNotificationIfEnabled()
Send an update notification if they are enabled.
NotificationStatus
Defines the whether notifications are dispatched.
virtual ~DynamicFactory()=default
Destroys the DynamicFactory and deletes the instantiators for all registered classes.
NotificationStatus m_notifyStatus
Flag marking whether we should dispatch notifications.
SubscribeAction
Defines replacement behaviour.
void sendUpdateNotification()
Send an update notification.
bool exists(const std::string &className) const
Returns true if the given class is currently registered.
void subscribe(const std::string &className, std::unique_ptr< AbstractFactory > pAbstractFactory, SubscribeAction replace=ErrorIfExists)
Registers the instantiator for the given class with the DynamicFactory.
void enableNotifications()
Enable notifications.
Poco::NotificationCenter notificationCenter
Sends notifications to observers.
void disableNotifications()
Disable notifications.
Exception for when an item is not found in a collection.
Definition Exception.h:145
The instantiator is a generic class for creating objects of the template type.
std::less< std::string > CaseSensitiveStringComparator
Helper class which provides the Collimation Length for SANS instruments.