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 <boost/function.hpp>
42 : #include <boost/type_traits.hpp>
43 :
44 :
45 : #include "global_function.h"
46 : #include "class.h"
47 : #include "param_to_type_value_list.h"
48 : #include "parameter_stack.h"
49 : #include "common/ug_config.h"
50 :
51 : namespace ug
52 : {
53 : namespace bridge
54 : {
55 :
56 : /**
57 : * \defgroup registry Registry
58 : * \ingroup bridge
59 : * \{
60 : */
61 :
62 : // PREDECLARATIONS
63 : class Registry;
64 :
65 : /// declaration of registry callback function.
66 : /** Allows to notify listeners if the registry changes.
67 : * Since FuncRegistryChanged is a functor, you can either
68 : * pass a normal function or a member function of a class
69 : * (Have a look at boost::bind in the second case).
70 : */
71 : typedef boost::function<void (Registry* pReg)> FuncRegistryChanged;
72 :
73 :
74 : /// groups classes. One of the members is the default member.
75 : class UG_API ClassGroupDesc
76 : {
77 : public:
78 273 : ClassGroupDesc() : m_defaultClass(NULL) {}
79 :
80 : /// sets name of group
81 273 : void set_name(const std::string& name) {m_name = name;}
82 :
83 : /// returns name of group
84 376305 : const std::string& name() const {return m_name;}
85 :
86 : /// adds a class to group
87 : void add_class(IExportedClass* c, const std::string& tag)
88 1264 : {m_classes.push_back(c); m_classTags.push_back(tag);}
89 :
90 : /// returns number of classes in group
91 : size_t num_classes() const {return m_classes.size();}
92 :
93 : /// returns if classes in group
94 : bool empty() const {return num_classes() == 0;}
95 :
96 : /// returns a class of the group
97 : IExportedClass* get_class(size_t i) {return m_classes[i];}
98 :
99 : /// returns a class of the group
100 0 : const IExportedClass* get_class(size_t i) const {return m_classes[i];}
101 :
102 : /// returns the class group tag for a class
103 : const std::string& get_class_tag(size_t i) const{return m_classTags[i];}
104 :
105 : /// sets the i'th class as default
106 0 : void set_default_class(size_t i) {m_defaultClass = m_classes[i];}
107 :
108 : /// if no default class is set, this method returns NULL.
109 0 : IExportedClass* get_default_class() const {return m_defaultClass;}
110 :
111 : private:
112 : /// name of class group
113 : std::string m_name;
114 :
115 : /// classes registered to the class group
116 : std::vector<IExportedClass*> m_classes;
117 :
118 : /// tags can be used to describe classes. One tag for each class.
119 : std::vector<std::string> m_classTags;
120 :
121 : /// the current default class
122 : IExportedClass* m_defaultClass;
123 : };
124 :
125 :
126 : /// Registry for functions and classes that are exported to scripts and visualizations
127 : /**
128 : * It also allows to register callbacks that are called if the registry changes.
129 : *
130 : * Please note that once a class or method is registered at the registry, it
131 : * can not be removed (This is important for the implementation of callbacks).
132 : *
133 : * Please note, that some of the methods take std::string by copy instead of
134 : * using const std::string&. This is on purpose in order to allow a call
135 : * of the method using a const char* as well.
136 : * @sa \ref pageUG4Registry
137 : */
138 : class UG_API Registry {
139 : public:
140 : /// constructor
141 : Registry();
142 :
143 : /// destructor
144 : ~Registry();
145 :
146 : /// requires every constructable class to be constructed via Smart-Pointer
147 : void set_force_construct_via_smart_pointer(bool bForceConstructionWithSmartPtr);
148 :
149 : ////////////////////////
150 : // callbacks
151 : ////////////////////////
152 :
153 : /// adds a callback which is triggered whenever Registry::registry_changed is called.
154 : void add_callback(FuncRegistryChanged callback);
155 :
156 : /// call this method if to forward changes of the registry to its listeners
157 : bool registry_changed();
158 :
159 : //////////////////////
160 : // global functions
161 : //////////////////////
162 :
163 : /**
164 : * @brief adds a function to the registry
165 : * @param funcName the name of the function
166 : * @param func function pointer of the function
167 : * @param group registry group. use / for subgroups e.g. ug4/mygroup/mysubgroup (optional)
168 : * @param retValInfos string documenting what the function returns (optional)
169 : * @param paramInfos string documenting the parameters of the function
170 : * seperate parameters with an # e.g. "x#y#z" (don't specify the type of the values) (optional)
171 : * @param toolTip small documentation for the function (optional)
172 : * @param help help string for the function
173 : * @sa \ref pageUG4Registry
174 : * @sa \ref secSTHowToSpecifyParameterInformation
175 : *
176 : * References the template function proxy_function<TFunc> and stores
177 : * it with the FuntionWrapper.
178 : */
179 : template<typename TFunc>
180 : Registry& add_function(std::string funcName, TFunc func, std::string group = "",
181 : std::string retValInfos = "", std::string paramInfos = "",
182 : std::string tooltip = "", std::string help = "");
183 :
184 : /// Similar to add_function but returns the added function instead of the registry.
185 : template<typename TFunc>
186 : ExportedFunction*
187 : add_and_get_function(std::string funcName, TFunc func, std::string group = "",
188 : std::string retValInfos = "", std::string paramInfos = "",
189 : std::string tooltip = "", std::string help = "");
190 :
191 : /// number of functions registered at the Registry (overloads are not counted)
192 : size_t num_functions() const;
193 :
194 : /// returns the first overload of an exported function
195 : ExportedFunction& get_function(size_t ind);
196 : const ExportedFunction& get_function(size_t ind) const;
197 :
198 : /// returns the number of overloads of a function
199 : size_t num_overloads(size_t ind) const;
200 :
201 : /// returns the i-th overload of a function
202 : ExportedFunction& get_overload(size_t funcInd, size_t oInd);
203 :
204 : /// returns a group which contains all overloads of a function
205 : ExportedFunctionGroup& get_function_group(size_t ind);
206 :
207 : /// returns an exported function group by name
208 : ExportedFunctionGroup* get_exported_function_group(const std::string& name);
209 :
210 : ///////////////////
211 : // classes
212 : ///////////////////
213 :
214 : /**
215 : * @brief Register a class at this registry
216 : * @param className name of the class to appear in the registry
217 : * @param group registry group. use / for subgroups e.g. ug4/mygroup/mysubgroup (optional)
218 : * @param toolTip describing text for the class (optional)
219 : */
220 : template <typename TClass>
221 : ExportedClass<TClass>& add_class_(std::string className,
222 : std::string group = "",
223 : std::string tooltip = "");
224 :
225 : /**
226 : * @brief Register a class at this registry together with its base class
227 : * @param className name of the class to appear in the registry
228 : * @param group registry group. use / for subgroups e.g. ug4/mygroup/mysubgroup (optional)
229 : * @param toolTip describing text for the class (optional)
230 : */
231 : template <typename TClass, typename TBaseClass>
232 : ExportedClass<TClass>& add_class_(std::string className,
233 : std::string group = "",
234 : std::string tooltip = "");
235 :
236 : /**
237 : * @brief Register a class at this registry together with two base classes
238 : * @param className name of the class to appear in the registry
239 : * @param group registry group. use / for subgroups e.g. ug4/mygroup/mysubgroup (optional)
240 : * @param toolTip describing text for the class (optional)
241 : */
242 : template <typename TClass, typename TBaseClass1, typename TBaseClass2>
243 : ExportedClass<TClass>& add_class_(std::string className,
244 : std::string group = "",
245 : std::string tooltip = "");
246 :
247 : /// Get Reference to already registered class
248 : template <typename TClass>
249 : ExportedClass<TClass>& get_class_();
250 :
251 : /// number of classes registered at the Registry
252 : size_t num_classes() const;
253 :
254 : /// returns an exported class
255 : const IExportedClass& get_class(size_t ind) const;
256 :
257 : /// returns an exported class
258 : IExportedClass* get_class(const std::string& name);
259 :
260 : /// returns an exported class
261 : const IExportedClass* get_class(const std::string& name) const;
262 :
263 : /// returns true if everything well-declared, else false
264 : bool check_consistency();
265 :
266 :
267 : ///////////////////
268 : // class-groups
269 : ///////////////////
270 :
271 : /// returns the number of available class groups
272 : size_t num_class_groups() const;
273 :
274 : /// returns a const pointer to the i-th class group
275 : const ClassGroupDesc* get_class_group(size_t i) const;
276 :
277 : /// returns a pointer to the i-th class group
278 : ClassGroupDesc* get_class_group(size_t i);
279 :
280 : /// Returns the class-group with the given name.
281 : /** If no such group exists at the time of calling, it will be created.*/
282 : ClassGroupDesc* get_class_group(const std::string& name);
283 :
284 : /// Returns the class-group with the given name.
285 : /** If no such group exists at the time of calling, NULL is returned.*/
286 : const ClassGroupDesc* get_class_group(const std::string& name) const;
287 :
288 : /// adds the given class to the given group.
289 : /** Groups are constructed automatically if required.
290 : * This method is just for convenience. It is effectively the same as:
291 : * get_class_group(groupName).add_class(reg.get_class(className), classTag).*/
292 : void add_class_to_group(std::string className, std::string groupName,
293 : std::string classTag = "");
294 :
295 :
296 : /// returns true if classname is already used by a class in this registry
297 : bool classname_registered(const std::string& name);
298 :
299 : /// returns true if groupname is already used by a class in this registry
300 : bool groupname_registered(const std::string& name);
301 :
302 : /// returns true if functionname is already used by a function in this registry
303 : bool functionname_registered(const std::string& name);
304 :
305 : protected:
306 : /// performs some checks, throws error if something wrong
307 : template <typename TClass, typename TBaseClass>
308 : void check_base_class(const std::string& className);
309 :
310 : private:
311 : // disallow copy
312 : Registry(const Registry& reg);
313 :
314 : /// registered functions
315 : std::vector<ExportedFunctionGroup*> m_vFunction;
316 :
317 : /// registered classes
318 : std::vector<IExportedClass*> m_vClass;
319 :
320 : /// registered class groups
321 : std::vector<ClassGroupDesc*> m_vClassGroups;
322 :
323 : /// Callback, that are called when registry changed is invoked
324 : std::vector<FuncRegistryChanged> m_callbacksRegChanged;
325 :
326 : /// flag if classes must be constructed via smart-pointer
327 : bool m_bForceConstructionWithSmartPtr;
328 : };
329 :
330 : // end group registry
331 : /// \}
332 :
333 : } // end namespace registry
334 :
335 : } // end namespace ug
336 :
337 : ////////////////////////////////
338 : // include implementation
339 : #include "registry_impl.h"
340 :
341 : #endif /* __H__UG_BRIDGE__REGISTRY__ */
|