Line data Source code
1 : /*
2 : * Copyright (c) 2010-2015: G-CSC, Goethe University Frankfurt
3 : * Authors: Andreas Vogel, Sebastian Reiter
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 :
33 : #ifndef __H__UG_BRIDGE__REGISTRY__
34 : #define __H__UG_BRIDGE__REGISTRY__
35 :
36 : #include <vector>
37 : #include <string>
38 : #include <cstring>
39 : #include <typeinfo>
40 : #include <iostream>
41 : #include <functional>
42 : #include <type_traits>
43 :
44 : #include "global_function.h"
45 : #include "class.h"
46 : #include "param_to_type_value_list.h"
47 : #include "parameter_stack.h"
48 : #include "common/ug_config.h"
49 :
50 : namespace ug
51 : {
52 : namespace bridge
53 : {
54 :
55 : /**
56 : * \defgroup registry Registry
57 : * \ingroup bridge
58 : * \{
59 : */
60 :
61 : // PREDECLARATIONS
62 : class Registry;
63 :
64 : /// declaration of registry callback function.
65 : /** Allows to notify listeners if the registry changes.
66 : * Since FuncRegistryChanged is a functor, you can either
67 : * pass a normal function or a member function of a class
68 : * (Have a look at boost::bind in the second case).
69 : */
70 : typedef std::function<void (Registry* pReg)> FuncRegistryChanged;
71 :
72 :
73 : /// groups classes. One of the members is the default member.
74 : class UG_API ClassGroupDesc
75 : {
76 : public:
77 303 : ClassGroupDesc() : m_defaultClass(NULL) {}
78 :
79 : /// sets name of group
80 303 : void set_name(const std::string& name) {m_name = name;}
81 :
82 : /// returns name of group
83 496525 : const std::string& name() const {return m_name;}
84 :
85 : /// adds a class to group
86 : void add_class(IExportedClass* c, const std::string& tag)
87 1474 : {m_classes.push_back(c); m_classTags.push_back(tag);}
88 :
89 : /// returns number of classes in group
90 : size_t num_classes() const {return m_classes.size();}
91 :
92 : /// returns if classes in group
93 : bool empty() const {return num_classes() == 0;}
94 :
95 : /// returns a class of the group
96 : IExportedClass* get_class(size_t i) {return m_classes[i];}
97 :
98 : /// returns a class of the group
99 0 : const IExportedClass* get_class(size_t i) const {return m_classes[i];}
100 :
101 : /// returns the class group tag for a class
102 : const std::string& get_class_tag(size_t i) const{return m_classTags[i];}
103 :
104 : /// sets the i'th class as default
105 0 : void set_default_class(size_t i) {m_defaultClass = m_classes[i];}
106 :
107 : /// if no default class is set, this method returns NULL.
108 0 : IExportedClass* get_default_class() const {return m_defaultClass;}
109 :
110 : private:
111 : /// name of class group
112 : std::string m_name;
113 :
114 : /// classes registered to the class group
115 : std::vector<IExportedClass*> m_classes;
116 :
117 : /// tags can be used to describe classes. One tag for each class.
118 : std::vector<std::string> m_classTags;
119 :
120 : /// the current default class
121 : IExportedClass* m_defaultClass;
122 : };
123 :
124 :
125 : /// Registry for functions and classes that are exported to scripts and visualizations
126 : /**
127 : * It also allows to register callbacks that are called if the registry changes.
128 : *
129 : * Please note that once a class or method is registered at the registry, it
130 : * can not be removed (This is important for the implementation of callbacks).
131 : *
132 : * Please note, that some of the methods take std::string by copy instead of
133 : * using const std::string&. This is on purpose in order to allow a call
134 : * of the method using a const char* as well.
135 : * @sa \ref pageUG4Registry
136 : */
137 : class UG_API Registry {
138 : public:
139 : /// constructor
140 : Registry();
141 :
142 : /// destructor
143 : ~Registry();
144 :
145 : /// requires every constructable class to be constructed via Smart-Pointer
146 : void set_force_construct_via_smart_pointer(bool bForceConstructionWithSmartPtr);
147 :
148 : ////////////////////////
149 : // callbacks
150 : ////////////////////////
151 :
152 : /// adds a callback which is triggered whenever Registry::registry_changed is called.
153 : void add_callback(FuncRegistryChanged callback);
154 :
155 : /// call this method if to forward changes of the registry to its listeners
156 : bool registry_changed();
157 :
158 : //////////////////////
159 : // global functions
160 : //////////////////////
161 :
162 : /**
163 : * @brief adds a function to the registry
164 : * @param funcName the name of the function
165 : * @param func function pointer of the function
166 : * @param group registry group. use / for subgroups e.g. ug4/mygroup/mysubgroup (optional)
167 : * @param retValInfos string documenting what the function returns (optional)
168 : * @param paramInfos string documenting the parameters of the function
169 : * seperate parameters with an # e.g. "x#y#z" (don't specify the type of the values) (optional)
170 : * @param toolTip small documentation for the function (optional)
171 : * @param help help string for the function
172 : * @sa \ref pageUG4Registry
173 : * @sa \ref secSTHowToSpecifyParameterInformation
174 : *
175 : * References the template function proxy_function<TFunc> and stores
176 : * it with the FuntionWrapper.
177 : */
178 : template<typename TFunc>
179 : Registry& add_function(std::string funcName, TFunc func, std::string group = "",
180 : std::string retValInfos = "", std::string paramInfos = "",
181 : std::string tooltip = "", std::string help = "");
182 :
183 : /// Similar to add_function but returns the added function instead of the registry.
184 : template<typename TFunc>
185 : ExportedFunction*
186 : add_and_get_function(std::string funcName, TFunc func, std::string group = "",
187 : std::string retValInfos = "", std::string paramInfos = "",
188 : std::string tooltip = "", std::string help = "");
189 :
190 : /// number of functions registered at the Registry (overloads are not counted)
191 : size_t num_functions() const;
192 :
193 : /// returns the first overload of an exported function
194 : ExportedFunction& get_function(size_t ind);
195 : const ExportedFunction& get_function(size_t ind) const;
196 :
197 : /// returns the number of overloads of a function
198 : size_t num_overloads(size_t ind) const;
199 :
200 : /// returns the i-th overload of a function
201 : ExportedFunction& get_overload(size_t funcInd, size_t oInd);
202 :
203 : /// returns a group which contains all overloads of a function
204 : ExportedFunctionGroup& get_function_group(size_t ind);
205 :
206 : /// returns an exported function group by name
207 : ExportedFunctionGroup* get_exported_function_group(const std::string& name);
208 :
209 : ///////////////////
210 : // classes
211 : ///////////////////
212 :
213 : /**
214 : * @brief Register a class at this registry
215 : * @param className name of the class to appear in the registry
216 : * @param group registry group. use / for subgroups e.g. ug4/mygroup/mysubgroup (optional)
217 : * @param toolTip describing text for the class (optional)
218 : */
219 : template <typename TClass>
220 : ExportedClass<TClass>& add_class_(std::string className,
221 : std::string group = "",
222 : std::string tooltip = "");
223 :
224 : /**
225 : * @brief Register a class at this registry together with its base class
226 : * @param className name of the class to appear in the registry
227 : * @param group registry group. use / for subgroups e.g. ug4/mygroup/mysubgroup (optional)
228 : * @param toolTip describing text for the class (optional)
229 : */
230 : template <typename TClass, typename TBaseClass>
231 : ExportedClass<TClass>& add_class_(std::string className,
232 : std::string group = "",
233 : std::string tooltip = "");
234 :
235 : /**
236 : * @brief Register a class at this registry together with two base classes
237 : * @param className name of the class to appear in the registry
238 : * @param group registry group. use / for subgroups e.g. ug4/mygroup/mysubgroup (optional)
239 : * @param toolTip describing text for the class (optional)
240 : */
241 : template <typename TClass, typename TBaseClass1, typename TBaseClass2>
242 : ExportedClass<TClass>& add_class_(std::string className,
243 : std::string group = "",
244 : std::string tooltip = "");
245 :
246 : /// Get Reference to already registered class
247 : template <typename TClass>
248 : ExportedClass<TClass>& get_class_();
249 :
250 : /// number of classes registered at the Registry
251 : size_t num_classes() const;
252 :
253 : /// returns an exported class
254 : const IExportedClass& get_class(size_t ind) const;
255 :
256 : /// returns an exported class
257 : IExportedClass* get_class(const std::string& name);
258 :
259 : /// returns an exported class
260 : const IExportedClass* get_class(const std::string& name) const;
261 :
262 : /// returns true if everything well-declared, else false
263 : bool check_consistency();
264 :
265 :
266 : ///////////////////
267 : // class-groups
268 : ///////////////////
269 :
270 : /// returns the number of available class groups
271 : size_t num_class_groups() const;
272 :
273 : /// returns a const pointer to the i-th class group
274 : const ClassGroupDesc* get_class_group(size_t i) const;
275 :
276 : /// returns a pointer to the i-th class group
277 : ClassGroupDesc* get_class_group(size_t i);
278 :
279 : /// Returns the class-group with the given name.
280 : /** If no such group exists at the time of calling, it will be created.*/
281 : ClassGroupDesc* get_class_group(const std::string& name);
282 :
283 : /// Returns the class-group with the given name.
284 : /** If no such group exists at the time of calling, NULL is returned.*/
285 : const ClassGroupDesc* get_class_group(const std::string& name) const;
286 :
287 : /// adds the given class to the given group.
288 : /** Groups are constructed automatically if required.
289 : * This method is just for convenience. It is effectively the same as:
290 : * get_class_group(groupName).add_class(reg.get_class(className), classTag).*/
291 : void add_class_to_group(std::string className, std::string groupName,
292 : std::string classTag = "");
293 :
294 :
295 : /// returns true if classname is already used by a class in this registry
296 : bool classname_registered(const std::string& name);
297 :
298 : /// returns true if groupname is already used by a class in this registry
299 : bool groupname_registered(const std::string& name);
300 :
301 : /// returns true if functionname is already used by a function in this registry
302 : bool functionname_registered(const std::string& name);
303 :
304 : protected:
305 : /// performs some checks, throws error if something wrong
306 : template <typename TClass, typename TBaseClass>
307 : void check_base_class(const std::string& className);
308 :
309 : private:
310 : // disallow copy
311 : Registry(const Registry& reg);
312 :
313 : /// registered functions
314 : std::vector<ExportedFunctionGroup*> m_vFunction;
315 :
316 : /// registered classes
317 : std::vector<IExportedClass*> m_vClass;
318 :
319 : /// registered class groups
320 : std::vector<ClassGroupDesc*> m_vClassGroups;
321 :
322 : /// Callback, that are called when registry changed is invoked
323 : std::vector<FuncRegistryChanged> m_callbacksRegChanged;
324 :
325 : /// flag if classes must be constructed via smart-pointer
326 : bool m_bForceConstructionWithSmartPtr;
327 : };
328 :
329 : // end group registry
330 : /// \}
331 :
332 : } // end namespace registry
333 :
334 : } // end namespace ug
335 :
336 : ////////////////////////////////
337 : // include implementation
338 : #include "registry_impl.h"
339 :
340 : #endif /* __H__UG_BRIDGE__REGISTRY__ */
|