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"
52 #include "bbtkUtilities.h"
59 BBTK_FORWARD_DECLARE_POINTER(Factory);
61 class BBTK_EXPORT Package : public Object
63 BBTK_OBJECT_INTERFACE(Package);
64 typedef Object Superclass;
66 /// Creates a new package
67 static Pointer New(const std::string& name,
68 const std::string& author,
69 const std::string& description,
70 const std::string& version);
71 /// Creates a package from a dynamic library
72 static Pointer CreateFromDynamicLibrary(const std::string& libname,
73 const std::string& pkgname,
74 const std::string& path);
76 void GetBoxesInside(NodeTreeC& tree, int cont);
77 /// NOTE : All the static methods below for package destruction
78 /// are not member because they can cause the package death
79 /// and thus close the dynamic library from which it has been loaded.
80 /// If the dynamic lib which provides a function is closed while
81 /// in the function: imagine the crash !
82 /// The principal method is Release
84 /// UnLoads the package dynamic library
85 /// (if any and if the package is released)
86 /// If doit == false then does not do it but just
87 /// put the package in the list of ReleasedDynamicallyLoadedPackages.
88 /// This is because we cannot close the dl from inside a
89 /// package member method or the program crashes.
90 /// The actual dl close must be done by an external user
91 /// calling UnLoadReleasedDynamicallyLoadedPackages
92 static void UnLoadDynamicLibrary(Package::WeakPointer p, bool doit = true);
94 /// UnLoads released packages that were loaded dynamically
95 /// see UnLoadDynamicLibrary and ReleaseBlackBoxDescriptor
96 static void UnLoadReleasedDynamicallyLoadedPackages();
98 /// "Releases" the package
99 /// Signals the package that it can free its descriptors
100 /// if they are no more used
101 /// then frees and unloads the package
102 /// if it is no more used (released)
103 /// Note : Any non-weak pointer on the package must have been freed
104 static void Release(Package::WeakPointer p);
107 /// Registers the BlackBoxDescriptor in the Package
108 bool Register(BlackBoxDescriptor::Pointer);
110 /// "Releases" a black box descriptor
111 /// Signals the package that it can free the given descriptor
112 /// if it is no more used and frees and put it the the
113 /// ReleasedDynamicallyLoadedPackages if it is dyn loaded
114 /// and no more used (released)
115 /// Note : Any non-weak pointer on the package must have been freed
116 static void ReleaseBlackBoxDescriptor(Package::WeakPointer p,
117 BlackBoxDescriptor::WeakPointer d);
120 typedef Package::Pointer (*DLGetPackageFunction)();
121 typedef void (*DLDeletePackageFunction)();
122 typedef const std::string& (*DLGetPackageBBTKVersionFunction)();
124 /// Opens a dynamic library which contains a bbtk package
125 /// Returns the handler
126 /// Load the package management symbols from the lib
127 /// returns false if a problem occured hence can be used
128 /// to test that a dyn lib is a valid bbtk package lib
129 /// NB : The BBTK version exported from the library
130 /// is tested against the current bbtk version
131 static DynamicLibraryHandler OpenDynamicLibrary
132 ( const std::string& dynamic_library_path,
133 const std::string& package_name,
134 DLGetPackageFunction&,
135 DLDeletePackageFunction&);
138 /// Returns the name of the package
139 const std::string& GetName() const { return mName; }
141 /// Returns the author of the package
142 const std::string& GetAuthor() const { return mAuthor; }
144 /// Returns the category of the package
145 const std::string& GetCategory() const { return mCategory; }
147 /// Returns the description of the package
148 const std::string& GetDescription() const { return mDescription; }
150 /// Returns the version of the package
151 const std::string& GetVersion() const { return mVersion; }
153 /// Returns true iff the package contains a BlackBoxDescriptor
154 /// with the name provided
155 bool ContainsDescriptor(const std::string& name) const;
157 /// Creates a new BlackBox of given type with name name
158 BlackBox::Pointer NewBlackBox(const std::string& type,
159 const std::string& name) const;
161 /// Creates a new adaptor BlackBox for the given input and output types
163 BlackBox::Pointer NewAdaptor(const DataInfo& typein,
164 const DataInfo& typeout,
165 const std::string& name) const;
167 /// Creates a new widget adaptor BlackBox
168 /// for the given input and output types
170 BlackBox::Pointer NewWidgetAdaptor(const DataInfo& typein,
171 const DataInfo& typeout,
172 const std::string& name) const;
173 bool FindAdaptor(const DataInfo& typein,
174 const DataInfo& typeout,
175 std::string& adaptor) const;
176 bool FindWidgetAdaptor(const DataInfo& typein,
177 const DataInfo& typeout,
178 std::string& adaptor) const;
181 /// Displays the list of black box descriptors of the package
182 void PrintHelpListDescriptors(bool description = false,
183 bool adaptors = false) const;
184 /// Displays the list of adaptors of the package
185 void PrintHelpListAdaptors(bool description = false) const;
186 /// Prints help on a particular Descriptor
187 void PrintHelpDescriptor(const std::string& name, bool full=true) const;
191 void CreateHtmlPage(const std::string& filename,
192 const std::string& caller = "?",
193 const std::string& source = "?",
194 const std::string& custom_header = "",
195 const std::string& custom_title = "",
198 bool relative_link = false ) const;
200 void SetDocURL(std::string url){ mDocURL=url; }
201 const std::string& GetDocURL() const { return mDocURL; }
203 void SetDocRelativeURL(std::string url){ mDocRelativeURL=url; }
204 const std::string& GetDocRelativeURL() const { return mDocRelativeURL; }
207 unsigned int GetNumberOfDescriptors() const { return mDescriptorMap.size(); }
209 /// Changes the name of a descriptor
210 void ChangeDescriptorName( const std::string& oldname,
211 const std::string& newname );
212 /// The type of map of descriptors
213 typedef std::map< std::string, BlackBoxDescriptor::Pointer>
215 const DescriptorMapType& GetDescriptorMap() const { return mDescriptorMap; }
216 DescriptorMapType& GetDescriptorMap() { return mDescriptorMap; }
218 /// The type of key in the map of adaptor descriptors
222 AdaptorKey( const DataInfo& typein, const DataInfo& typeout,
223 BlackBoxDescriptor::Kind kind )
224 : mTypeIn(typein), mTypeOut(typeout), mKind(kind) {}
226 bool operator< ( const AdaptorKey& k ) const
228 return ( ( mKind < k.mKind ) ||
229 ( ( mKind == k.mKind ) &&
230 ( ( mTypeIn < k.mTypeIn ) ||
231 ( ( mTypeIn == k.mTypeIn ) &&
232 ( mTypeOut < k.mTypeOut ) ) ) ) );
235 bool operator== ( const AdaptorKey& k ) const
237 return ( ( mKind == k.mKind ) &&
238 ( mTypeIn == k.mTypeIn ) &&
239 ( mTypeOut == k.mTypeOut ) );
243 BlackBoxDescriptor::Kind mKind;
246 /// The type of map of adaptor descriptors
247 typedef std::map< AdaptorKey, BlackBoxDescriptor::WeakPointer> AdaptorMapType;
250 const AdaptorMapType& GetAdaptorMap() const { return mAdaptorMap; }
253 // Factories management
254 /// Adds the factory to the set of factories which use the package
255 void AddFactory(FactoryPointer f) { mFactorySet.insert(f); }
256 /// Removes the factory from the set of factories which use the package
257 void RemoveFactory(FactoryPointer f) { mFactorySet.erase(f); }
260 typedef std::set<FactoryWeakPointer> FactorySet;
261 /// Gets the set of factories which use the package
262 FactorySet& GetFactorySet() { return mFactorySet; }
263 /// Gets the set of factories which use the package (const)
264 const FactorySet& GetFactorySet() const { return mFactorySet; }
267 bool ifBoxExist( std::string boxType );
271 /// Default ctor is private : use the static New method
273 /// A Package cannot be copy constructed
274 // Package(const Package&) {}
275 /// Ctor is private : use the static New method
276 Package(const std::string& name,
277 const std::string& author,
278 const std::string& description,
279 const std::string& version);
280 /// Does unload a package (no test)
281 static void UnLoad(Package::WeakPointer p);
283 /// The dynamic library handler of the package if it was loaded from a dl
284 DynamicLibraryHandler mDynamicLibraryHandler;
285 /// The pointer on the delete function of the package
286 /// in case it was loaded from a dynamic library
287 DLDeletePackageFunction mDLDeletePackageFunction;
290 /// The name of the package
292 /// The author of the package
294 /// The categories of the package
295 std::string mCategory;
296 /// The description of the package
297 std::string mDescription;
298 /// The version of the package
299 std::string mVersion;
300 /// URL of the documentation of the Package (absolute path)
302 /// URL of the documentation of the Package
303 /// (path relative to bbtk doc root)
304 std::string mDocRelativeURL;
306 /// The map of black boxes descriptors
307 DescriptorMapType mDescriptorMap;
309 /// The map of adaptors descriptors
310 AdaptorMapType mAdaptorMap;
313 /// The set of factories which contain the package
314 FactorySet mFactorySet;
316 /// The set of released dynamically loaded packages
317 /// to be unloaded explicitely calling
318 /// UnLoadReleasedDynamicallyLoadedPackages
319 static std::set<Package::WeakPointer>
320 mReleasedDynamicallyLoadedPackages;
323 //====================================================================
326 //====================================================================
328 #define BBTK_PACKAGE_EXPORT __declspec( dllexport )
330 #define BBTK_PACKAGE_EXPORT
331 #endif // defined(_WIN32)
332 //====================================================================
334 #define BBTK_GET_PACKAGE_FUNCTION_NAME GetPackage
335 #define BBTK_DEL_PACKAGE_FUNCTION_NAME DeletePackage
336 #define BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME GetPackageBBTKVersion
340 //====================================================================
341 #define BBTK_DECLARE_PACKAGE(NAME) \
344 bbtk::Package::Pointer& NAME ## GetPackagePointer(); \
345 BBTK_PACKAGE_EXPORT \
346 void BBTK_CDECL NAME ## DeletePackage (); \
347 BBTK_PACKAGE_EXPORT bbtk::Package::Pointer \
348 BBTK_CDECL NAME ## GetPackage (); \
349 BBTK_PACKAGE_EXPORT const std::string& \
350 BBTK_CDECL NAME ## GetPackageBBTKVersion (); \
352 //====================================================================
354 //====================================================================
355 #define BBTK_IMPLEMENT_PACKAGE(NAME,AUTHOR,DESCRIPTION,VERSION) \
358 bbtk::Package::Pointer& NAME ## GetPackagePointer() \
360 static bbtk::Package::Pointer u; \
363 BBTK_PACKAGE_EXPORT \
364 void BBTK_CDECL NAME ## DeletePackage () \
366 NAME ## GetPackagePointer().reset(); \
368 BBTK_PACKAGE_EXPORT \
369 bbtk::Package::Pointer \
370 BBTK_CDECL NAME ## GetPackage() \
372 if (!NAME ## GetPackagePointer()) { \
373 NAME ## GetPackagePointer() = \
374 bbtk::Package::New(#NAME, \
379 bbtk::Object::InsertInPackageList( NAME ## GetPackagePointer() ); \
381 return NAME ## GetPackagePointer(); \
383 BBTK_PACKAGE_EXPORT const std::string& \
384 BBTK_CDECL NAME ## GetPackageBBTKVersion () \
385 { static const std::string v(BBTK_STRINGIFY_SYMBOL(BBTK_VERSION)); return v; } \
386 class NAME ## PackageAutodestructor \
389 NAME ## PackageAutodestructor() {} \
390 ~NAME ## PackageAutodestructor() \
392 if (NAME ## GetPackagePointer().use_count()>0) \
394 bbtk::Package::WeakPointer p = NAME ## GetPackagePointer(); \
395 bbtk::Package::Release(p); \
399 NAME ## PackageAutodestructor NAME ## PackageAutodestructorInstance; \
401 //====================================================================
403 //====================================================================
404 #define BBTK_ADD_BLACK_BOX_TO_PACKAGE(NAME,CLASS) \
405 bool bbDummy##NAME##CLASS = NAME ## GetPackage () \
406 ->Register(CLASS ## Descriptor::Instance());
407 //====================================================================
409 //====================================================================
410 #define BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(NAME,CLASS,TEMPLATE_PARAM) \
411 bool bbDummy##NAME##CLASS##TEMPLATE_PARAM = NAME ## GetPackage () \
412 ->Register(CLASS ## Descriptor <TEMPLATE_PARAM>::Instance());
413 //====================================================================
415 //====================================================================
416 #define BBTK_ADD_TEMPLATE2_BLACK_BOX_TO_PACKAGE(NAME,CLASS,T1,T2) \
417 bool bbDummy##NAME##CLASS##T1##T2 = NAME ## GetPackage () \
418 ->Register(CLASS ## Descriptor <T1,T2>::Instance());
419 //====================================================================