2 # ---------------------------------------------------------------------
4 # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
6 # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
7 # Previous Authors : Laurent Guigues, Jean-Pierre Roux
8 # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
10 # This software is governed by the CeCILL-B license under French law and
11 # abiding by the rules of distribution of free software. You can use,
12 # modify and/ or redistribute the software under the terms of the CeCILL-B
13 # license as circulated by CEA, CNRS and INRIA at the following URL
14 # http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
15 # or in the file LICENSE.txt.
17 # As a counterpart to the access to the source code and rights to copy,
18 # modify and redistribute granted by the license, users are provided only
19 # with a limited warranty and the software's author, the holder of the
20 # economic rights, and the successive licensors have only limited
23 # The fact that you are presently reading this means that you have had
24 # knowledge of the CeCILL-B license and that you accept its terms.
25 # ------------------------------------------------------------------------ */
28 /*=========================================================================
30 Module: $RCSfile: bbtkPackage.h,v $
32 Date: $Date: 2012/11/16 08:49:01 $
33 Version: $Revision: 1.18 $
34 =========================================================================*/
40 * \brief Class bbtk::Package : registers black boxes descriptors and is able to create instances of the black boxes registered.
43 * \class bbtk::Package
44 * \brief registers black boxes descriptors and is able to create instances of the black boxes registered.
47 #ifndef __bbtkPackage_h__
48 #define __bbtkPackage_h__
50 #include "bbtkBlackBox.h"
51 #include "bbtkDynamicLibraryHandling.h"
57 BBTK_FORWARD_DECLARE_POINTER(Factory);
59 class BBTK_EXPORT Package : public Object
61 BBTK_OBJECT_INTERFACE(Package);
62 typedef Object Superclass;
64 /// Creates a new package
65 static Pointer New(const std::string& name,
66 const std::string& author,
67 const std::string& description,
68 const std::string& version);
69 /// Creates a package from a dynamic library
70 static Pointer CreateFromDynamicLibrary(const std::string& libname,
71 const std::string& pkgname,
72 const std::string& path);
74 /// NOTE : All the static methods below for package destruction
75 /// are not member because they can cause the package death
76 /// and thus close the dynamic library from which it has been loaded.
77 /// If the dynamic lib which provides a function is closed while
78 /// in the function: imagine the crash !
79 /// The principal method is Release
81 /// UnLoads the package dynamic library
82 /// (if any and if the package is released)
83 /// If doit == false then does not do it but just
84 /// put the package in the list of ReleasedDynamicallyLoadedPackages.
85 /// This is because we cannot close the dl from inside a
86 /// package member method or the program crashes.
87 /// The actual dl close must be done by an external user
88 /// calling UnLoadReleasedDynamicallyLoadedPackages
89 static void UnLoadDynamicLibrary(Package::WeakPointer p, bool doit = true);
91 /// UnLoads released packages that were loaded dynamically
92 /// see UnLoadDynamicLibrary and ReleaseBlackBoxDescriptor
93 static void UnLoadReleasedDynamicallyLoadedPackages();
95 /// "Releases" the package
96 /// Signals the package that it can free its descriptors
97 /// if they are no more used
98 /// then frees and unloads the package
99 /// if it is no more used (released)
100 /// Note : Any non-weak pointer on the package must have been freed
101 static void Release(Package::WeakPointer p);
104 /// Registers the BlackBoxDescriptor in the Package
105 bool Register(BlackBoxDescriptor::Pointer);
107 /// "Releases" a black box descriptor
108 /// Signals the package that it can free the given descriptor
109 /// if it is no more used and frees and put it the the
110 /// ReleasedDynamicallyLoadedPackages if it is dyn loaded
111 /// and no more used (released)
112 /// Note : Any non-weak pointer on the package must have been freed
113 static void ReleaseBlackBoxDescriptor(Package::WeakPointer p,
114 BlackBoxDescriptor::WeakPointer d);
117 typedef Package::Pointer (*DLGetPackageFunction)();
118 typedef void (*DLDeletePackageFunction)();
119 typedef const std::string& (*DLGetPackageBBTKVersionFunction)();
121 /// Opens a dynamic library which contains a bbtk package
122 /// Returns the handler
123 /// Load the package management symbols from the lib
124 /// returns false if a problem occured hence can be used
125 /// to test that a dyn lib is a valid bbtk package lib
126 /// NB : The BBTK version exported from the library
127 /// is tested against the current bbtk version
128 static DynamicLibraryHandler OpenDynamicLibrary
129 ( const std::string& dynamic_library_path,
130 const std::string& package_name,
131 DLGetPackageFunction&,
132 DLDeletePackageFunction&);
135 /// Returns the name of the package
136 const std::string& GetName() const { return mName; }
138 /// Returns the author of the package
139 const std::string& GetAuthor() const { return mAuthor; }
141 /// Returns the category of the package
142 const std::string& GetCategory() const { return mCategory; }
144 /// Returns the description of the package
145 const std::string& GetDescription() const { return mDescription; }
147 /// Returns the version of the package
148 const std::string& GetVersion() const { return mVersion; }
150 /// Returns true iff the package contains a BlackBoxDescriptor
151 /// with the name provided
152 bool ContainsDescriptor(const std::string& name) const;
154 /// Creates a new BlackBox of given type with name name
155 BlackBox::Pointer NewBlackBox(const std::string& type,
156 const std::string& name) const;
158 /// Creates a new adaptor BlackBox for the given input and output types
160 BlackBox::Pointer NewAdaptor(const DataInfo& typein,
161 const DataInfo& typeout,
162 const std::string& name) const;
164 /// Creates a new widget adaptor BlackBox
165 /// for the given input and output types
167 BlackBox::Pointer NewWidgetAdaptor(const DataInfo& typein,
168 const DataInfo& typeout,
169 const std::string& name) const;
170 bool FindAdaptor(const DataInfo& typein,
171 const DataInfo& typeout,
172 std::string& adaptor) const;
173 bool FindWidgetAdaptor(const DataInfo& typein,
174 const DataInfo& typeout,
175 std::string& adaptor) const;
178 /// Displays the list of black box descriptors of the package
179 void PrintHelpListDescriptors(bool description = false,
180 bool adaptors = false) const;
181 /// Displays the list of adaptors of the package
182 void PrintHelpListAdaptors(bool description = false) const;
183 /// Prints help on a particular Descriptor
184 void PrintHelpDescriptor(const std::string& name, bool full=true) const;
188 void CreateHtmlPage(const std::string& filename,
189 const std::string& caller = "?",
190 const std::string& source = "?",
191 const std::string& custom_header = "",
192 const std::string& custom_title = "",
195 bool relative_link = false ) const;
197 void SetDocURL(std::string url){ mDocURL=url; }
198 const std::string& GetDocURL() const { return mDocURL; }
200 void SetDocRelativeURL(std::string url){ mDocRelativeURL=url; }
201 const std::string& GetDocRelativeURL() const { return mDocRelativeURL; }
204 unsigned int GetNumberOfDescriptors() const { return mDescriptorMap.size(); }
206 /// Changes the name of a descriptor
207 void ChangeDescriptorName( const std::string& oldname,
208 const std::string& newname );
209 /// The type of map of descriptors
210 typedef std::map< std::string, BlackBoxDescriptor::Pointer>
212 const DescriptorMapType& GetDescriptorMap() const { return mDescriptorMap; }
213 DescriptorMapType& GetDescriptorMap() { return mDescriptorMap; }
215 /// The type of key in the map of adaptor descriptors
219 AdaptorKey( const DataInfo& typein, const DataInfo& typeout,
220 BlackBoxDescriptor::Kind kind )
221 : mTypeIn(typein), mTypeOut(typeout), mKind(kind) {}
223 bool operator< ( const AdaptorKey& k ) const
225 return ( ( mKind < k.mKind ) ||
226 ( ( mKind == k.mKind ) &&
227 ( ( mTypeIn < k.mTypeIn ) ||
228 ( ( mTypeIn == k.mTypeIn ) &&
229 ( mTypeOut < k.mTypeOut ) ) ) ) );
232 bool operator== ( const AdaptorKey& k ) const
234 return ( ( mKind == k.mKind ) &&
235 ( mTypeIn == k.mTypeIn ) &&
236 ( mTypeOut == k.mTypeOut ) );
240 BlackBoxDescriptor::Kind mKind;
243 /// The type of map of adaptor descriptors
244 typedef std::map< AdaptorKey, BlackBoxDescriptor::WeakPointer> AdaptorMapType;
247 const AdaptorMapType& GetAdaptorMap() const { return mAdaptorMap; }
250 // Factories management
251 /// Adds the factory to the set of factories which use the package
252 void AddFactory(FactoryPointer f) { mFactorySet.insert(f); }
253 /// Removes the factory from the set of factories which use the package
254 void RemoveFactory(FactoryPointer f) { mFactorySet.erase(f); }
257 typedef std::set<FactoryWeakPointer> FactorySet;
258 /// Gets the set of factories which use the package
259 FactorySet& GetFactorySet() { return mFactorySet; }
260 /// Gets the set of factories which use the package (const)
261 const FactorySet& GetFactorySet() const { return mFactorySet; }
264 bool ifBoxExist( std::string boxType );
268 /// Default ctor is private : use the static New method
270 /// A Package cannot be copy constructed
271 // Package(const Package&) {}
272 /// Ctor is private : use the static New method
273 Package(const std::string& name,
274 const std::string& author,
275 const std::string& description,
276 const std::string& version);
277 /// Does unload a package (no test)
278 static void UnLoad(Package::WeakPointer p);
280 /// The dynamic library handler of the package if it was loaded from a dl
281 DynamicLibraryHandler mDynamicLibraryHandler;
282 /// The pointer on the delete function of the package
283 /// in case it was loaded from a dynamic library
284 DLDeletePackageFunction mDLDeletePackageFunction;
287 /// The name of the package
289 /// The author of the package
291 /// The categories of the package
292 std::string mCategory;
293 /// The description of the package
294 std::string mDescription;
295 /// The version of the package
296 std::string mVersion;
297 /// URL of the documentation of the Package (absolute path)
299 /// URL of the documentation of the Package
300 /// (path relative to bbtk doc root)
301 std::string mDocRelativeURL;
303 /// The map of black boxes descriptors
304 DescriptorMapType mDescriptorMap;
306 /// The map of adaptors descriptors
307 AdaptorMapType mAdaptorMap;
310 /// The set of factories which contain the package
311 FactorySet mFactorySet;
313 /// The set of released dynamically loaded packages
314 /// to be unloaded explicitely calling
315 /// UnLoadReleasedDynamicallyLoadedPackages
316 static std::set<Package::WeakPointer>
317 mReleasedDynamicallyLoadedPackages;
320 //====================================================================
323 //====================================================================
325 #define BBTK_PACKAGE_EXPORT __declspec( dllexport )
327 #define BBTK_PACKAGE_EXPORT
328 #endif // defined(_WIN32)
329 //====================================================================
331 #define BBTK_GET_PACKAGE_FUNCTION_NAME GetPackage
332 #define BBTK_DEL_PACKAGE_FUNCTION_NAME DeletePackage
333 #define BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME GetPackageBBTKVersion
337 //====================================================================
338 #define BBTK_DECLARE_PACKAGE(NAME) \
341 bbtk::Package::Pointer& NAME ## GetPackagePointer(); \
342 BBTK_PACKAGE_EXPORT \
343 void BBTK_CDECL NAME ## DeletePackage (); \
344 BBTK_PACKAGE_EXPORT bbtk::Package::Pointer \
345 BBTK_CDECL NAME ## GetPackage (); \
346 BBTK_PACKAGE_EXPORT const std::string& \
347 BBTK_CDECL NAME ## GetPackageBBTKVersion (); \
349 //====================================================================
351 //====================================================================
352 #define BBTK_IMPLEMENT_PACKAGE(NAME,AUTHOR,DESCRIPTION,VERSION) \
355 bbtk::Package::Pointer& NAME ## GetPackagePointer() \
357 static bbtk::Package::Pointer u; \
360 BBTK_PACKAGE_EXPORT \
361 void BBTK_CDECL NAME ## DeletePackage () \
363 NAME ## GetPackagePointer().reset(); \
365 BBTK_PACKAGE_EXPORT \
366 bbtk::Package::Pointer \
367 BBTK_CDECL NAME ## GetPackage() \
369 if (!NAME ## GetPackagePointer()) { \
370 NAME ## GetPackagePointer() = \
371 bbtk::Package::New(#NAME, \
376 bbtk::Object::InsertInPackageList( NAME ## GetPackagePointer() ); \
378 return NAME ## GetPackagePointer(); \
380 BBTK_PACKAGE_EXPORT const std::string& \
381 BBTK_CDECL NAME ## GetPackageBBTKVersion () \
382 { static const std::string v(BBTK_STRINGIFY_SYMBOL(BBTK_VERSION)); return v; } \
383 class NAME ## PackageAutodestructor \
386 NAME ## PackageAutodestructor() {} \
387 ~NAME ## PackageAutodestructor() \
389 if (NAME ## GetPackagePointer().use_count()>0) \
391 bbtk::Package::WeakPointer p = NAME ## GetPackagePointer(); \
392 bbtk::Package::Release(p); \
396 NAME ## PackageAutodestructor NAME ## PackageAutodestructorInstance; \
398 //====================================================================
400 //====================================================================
401 #define BBTK_ADD_BLACK_BOX_TO_PACKAGE(NAME,CLASS) \
402 bool bbDummy##NAME##CLASS = NAME ## GetPackage () \
403 ->Register(CLASS ## Descriptor::Instance());
404 //====================================================================
406 //====================================================================
407 #define BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(NAME,CLASS,TEMPLATE_PARAM) \
408 bool bbDummy##NAME##CLASS##TEMPLATE_PARAM = NAME ## GetPackage () \
409 ->Register(CLASS ## Descriptor <TEMPLATE_PARAM>::Instance());
410 //====================================================================
412 //====================================================================
413 #define BBTK_ADD_TEMPLATE2_BLACK_BOX_TO_PACKAGE(NAME,CLASS,T1,T2) \
414 bool bbDummy##NAME##CLASS##T1##T2 = NAME ## GetPackage () \
415 ->Register(CLASS ## Descriptor <T1,T2>::Instance());
416 //====================================================================