ModuleRegistry.cc
1 /*
2  * MoMEMta: a modular implementation of the Matrix Element Method
3  * Copyright (C) 2016 Universite catholique de Louvain (UCL), Belgium
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include <momemta/Logging.h>
20 #include <momemta/ModuleRegistry.h>
21 
22 namespace momemta {
23 
24 ModuleRegistryInterface::~ModuleRegistryInterface() {}
25 
27  static ModuleRegistry s_instance;
28  return s_instance;
29 }
30 
31 ModuleRegistry::ModuleRegistry() { }
32 
33 void ModuleRegistry::registerModule(RegisterOp registration_op) {
34  std::unique_lock<std::mutex> lock(mutex_);
35  if (!initialized_) {
36  deferred_.emplace_back(registration_op);
37  } else {
38  registerModuleWithLock(registration_op);
39  }
40 }
41 
42 void ModuleRegistry::deregisterModule(const std::string& module_name) {
43  std::unique_lock<std::mutex> lock(mutex_);
44  callDeferred();
45 
46  registry_.erase(module_name);
47 }
48 
49 const ModuleRegistrationData& ModuleRegistry::find(const std::string& module_name) const {
50 
51  const ModuleRegistrationData* data = nullptr;
52 
53  {
54  std::unique_lock<std::mutex> lock(mutex_);
55  callDeferred();
56 
57  auto it = registry_.find(module_name);
58  if (it != registry_.end())
59  data = &it->second;
60  }
61 
62  if (! data) {
63  throw module_not_found_error("Module '" + module_name + "' is not present in the registry");
64  }
65 
66  return *data;
67 }
68 
69 void ModuleRegistry::exportList(bool ignore_internal, ModuleList& list) const {
70  list.clear();
71 
72  std::unique_lock<std::mutex> lock(mutex_);
73  callDeferred();
74 
75  for (const auto& it: registry_) {
76  if (ignore_internal && it.second.module_def.internal)
77  continue;
78 
79  list.emplace_back(it.second.module_def);
80  }
81 }
82 
84  std::unique_lock<std::mutex> lock(mutex_);
85  callDeferred();
86 }
87 
88 void ModuleRegistry::callDeferred() const {
89  if (initialized_)
90  return;
91 
92  initialized_ = true;
93 
94  for (auto& fn: deferred_) {
95  registerModuleWithLock(fn);
96  }
97 
98  deferred_.clear();
99 }
100 
101 void ModuleRegistry::registerModuleWithLock(RegisterOp registration_op) const {
102  auto registration_data = registration_op();
103 
104  // Insert module into registry
105  auto it = registry_.find(registration_data.module_def.name);
106  if (it != registry_.end())
107  throw module_already_exists_error("The module '" + registration_data.module_def.name + "' already exists.");
108 
109  registry_.emplace(registration_data.module_def.name, registration_data);
110 }
111 
112 namespace registration {
113 
114 
115 ModuleDefBuilderReceiver::ModuleDefBuilderReceiver(const ModuleDefBuilder& builder) {
116  name_ = builder.name();
117  ModuleRegistry::get().registerModule([builder]() -> ModuleRegistrationData {
118  return builder.Build();
119  });
120 }
121 
122 ModuleDefBuilderReceiver::~ModuleDefBuilderReceiver() {
124 }
125 
126 }
127 }
void deregisterModule(const std::string &module_name)
static ModuleRegistry & get()
A singleton available at startup.
const ModuleRegistrationData & find(const std::string &module_name) const override
Definition: Graph.h:21
void exportList(bool ignore_internal, ModuleList &list) const