1 /*=========================================================================
3 Module: $RCSfile: bbtkPackage.h,v $
5 Date: $Date: 2010/09/12 14:52:25 $
6 Version: $Revision: 1.16 $
7 =========================================================================*/
9 /* ---------------------------------------------------------------------
11 * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
12 * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
14 * This software is governed by the CeCILL-B license under French law and
15 * abiding by the rules of distribution of free software. You can use,
16 * modify and/ or redistribute the software under the terms of the CeCILL-B
17 * license as circulated by CEA, CNRS and INRIA at the following URL
18 * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
19 * or in the file LICENSE.txt.
21 * As a counterpart to the access to the source code and rights to copy,
22 * modify and redistribute granted by the license, users are provided only
23 * with a limited warranty and the software's author, the holder of the
24 * economic rights, and the successive licensors have only limited
27 * The fact that you are presently reading this means that you have had
28 * knowledge of the CeCILL-B license and that you accept its terms.
29 * ------------------------------------------------------------------------ */
33 * \brief Class bbtk::Package : registers black boxes descriptors and is able to create instances of the black boxes registered.
36 * \class bbtk::Package
37 * \brief registers black boxes descriptors and is able to create instances of the black boxes registered.
40 #ifndef __bbtkPackage_h__
41 #define __bbtkPackage_h__
43 #include "bbtkBlackBox.h"
44 #include "bbtkDynamicLibraryHandling.h"
50 BBTK_FORWARD_DECLARE_POINTER(Factory);
52 class BBTK_EXPORT Package : public Object
54 BBTK_OBJECT_INTERFACE(Package);
55 typedef Object Superclass;
57 /// Creates a new package
58 static Pointer New(const std::string& name,
59 const std::string& author,
60 const std::string& description,
61 const std::string& version);
62 /// Creates a package from a dynamic library
63 static Pointer CreateFromDynamicLibrary(const std::string& libname,
64 const std::string& pkgname,
65 const std::string& path);
67 /// NOTE : All the static methods below for package destruction
68 /// are not member because they can cause the package death
69 /// and thus close the dynamic library from which it has been loaded.
70 /// If the dynamic lib which provides a function is closed while
71 /// in the function: imagine the crash !
72 /// The principal method is Release
74 /// UnLoads the package dynamic library
75 /// (if any and if the package is released)
76 /// If doit == false then does not do it but just
77 /// put the package in the list of ReleasedDynamicallyLoadedPackages.
78 /// This is because we cannot close the dl from inside a
79 /// package member method or the program crashes.
80 /// The actual dl close must be done by an external user
81 /// calling UnLoadReleasedDynamicallyLoadedPackages
82 static void UnLoadDynamicLibrary(Package::WeakPointer p, bool doit = true);
84 /// UnLoads released packages that were loaded dynamically
85 /// see UnLoadDynamicLibrary and ReleaseBlackBoxDescriptor
86 static void UnLoadReleasedDynamicallyLoadedPackages();
88 /// "Releases" the package
89 /// Signals the package that it can free its descriptors
90 /// if they are no more used
91 /// then frees and unloads the package
92 /// if it is no more used (released)
93 /// Note : Any non-weak pointer on the package must have been freed
94 static void Release(Package::WeakPointer p);
97 /// Registers the BlackBoxDescriptor in the Package
98 bool Register(BlackBoxDescriptor::Pointer);
100 /// "Releases" a black box descriptor
101 /// Signals the package that it can free the given descriptor
102 /// if it is no more used and frees and put it the the
103 /// ReleasedDynamicallyLoadedPackages if it is dyn loaded
104 /// and no more used (released)
105 /// Note : Any non-weak pointer on the package must have been freed
106 static void ReleaseBlackBoxDescriptor(Package::WeakPointer p,
107 BlackBoxDescriptor::WeakPointer d);
110 typedef Package::Pointer (*DLGetPackageFunction)();
111 typedef void (*DLDeletePackageFunction)();
112 typedef const std::string& (*DLGetPackageBBTKVersionFunction)();
114 /// Opens a dynamic library which contains a bbtk package
115 /// Returns the handler
116 /// Load the package management symbols from the lib
117 /// returns false if a problem occured hence can be used
118 /// to test that a dyn lib is a valid bbtk package lib
119 /// NB : The BBTK version exported from the library
120 /// is tested against the current bbtk version
121 static DynamicLibraryHandler OpenDynamicLibrary
122 ( const std::string& dynamic_library_path,
123 const std::string& package_name,
124 DLGetPackageFunction&,
125 DLDeletePackageFunction&);
128 /// Returns the name of the package
129 const std::string& GetName() const { return mName; }
131 /// Returns the author of the package
132 const std::string& GetAuthor() const { return mAuthor; }
134 /// Returns the category of the package
135 const std::string& GetCategory() const { return mCategory; }
137 /// Returns the description of the package
138 const std::string& GetDescription() const { return mDescription; }
140 /// Returns the version of the package
141 const std::string& GetVersion() const { return mVersion; }
143 /// Returns true iff the package contains a BlackBoxDescriptor
144 /// with the name provided
145 bool ContainsDescriptor(const std::string& name) const;
147 /// Creates a new BlackBox of given type with name name
148 BlackBox::Pointer NewBlackBox(const std::string& type,
149 const std::string& name) const;
151 /// Creates a new adaptor BlackBox for the given input and output types
153 BlackBox::Pointer NewAdaptor(const DataInfo& typein,
154 const DataInfo& typeout,
155 const std::string& name) const;
157 /// Creates a new widget adaptor BlackBox
158 /// for the given input and output types
160 BlackBox::Pointer NewWidgetAdaptor(const DataInfo& typein,
161 const DataInfo& typeout,
162 const std::string& name) const;
163 bool FindAdaptor(const DataInfo& typein,
164 const DataInfo& typeout,
165 std::string& adaptor) const;
166 bool FindWidgetAdaptor(const DataInfo& typein,
167 const DataInfo& typeout,
168 std::string& adaptor) const;
171 /// Displays the list of black box descriptors of the package
172 void PrintHelpListDescriptors(bool description = false,
173 bool adaptors = false) const;
174 /// Displays the list of adaptors of the package
175 void PrintHelpListAdaptors(bool description = false) const;
176 /// Prints help on a particular Descriptor
177 void PrintHelpDescriptor(const std::string& name, bool full=true) const;
181 void CreateHtmlPage(const std::string& filename,
182 const std::string& caller = "?",
183 const std::string& source = "?",
184 const std::string& custom_header = "",
185 const std::string& custom_title = "",
188 bool relative_link = false ) const;
190 void SetDocURL(std::string url){ mDocURL=url; }
191 const std::string& GetDocURL() const { return mDocURL; }
193 void SetDocRelativeURL(std::string url){ mDocRelativeURL=url; }
194 const std::string& GetDocRelativeURL() const { return mDocRelativeURL; }
197 unsigned int GetNumberOfDescriptors() const { return mDescriptorMap.size(); }
199 /// Changes the name of a descriptor
200 void ChangeDescriptorName( const std::string& oldname,
201 const std::string& newname );
202 /// The type of map of descriptors
203 typedef std::map< std::string, BlackBoxDescriptor::Pointer>
205 const DescriptorMapType& GetDescriptorMap() const { return mDescriptorMap; }
206 DescriptorMapType& GetDescriptorMap() { return mDescriptorMap; }
208 /// The type of key in the map of adaptor descriptors
212 AdaptorKey( const DataInfo& typein, const DataInfo& typeout,
213 BlackBoxDescriptor::Kind kind )
214 : mTypeIn(typein), mTypeOut(typeout), mKind(kind) {}
216 bool operator< ( const AdaptorKey& k ) const
218 return ( ( mKind < k.mKind ) ||
219 ( ( mKind == k.mKind ) &&
220 ( ( mTypeIn < k.mTypeIn ) ||
221 ( ( mTypeIn == k.mTypeIn ) &&
222 ( mTypeOut < k.mTypeOut ) ) ) ) );
225 bool operator== ( const AdaptorKey& k ) const
227 return ( ( mKind == k.mKind ) &&
228 ( mTypeIn == k.mTypeIn ) &&
229 ( mTypeOut == k.mTypeOut ) );
233 BlackBoxDescriptor::Kind mKind;
236 /// The type of map of adaptor descriptors
237 typedef std::map< AdaptorKey, BlackBoxDescriptor::WeakPointer> AdaptorMapType;
240 const AdaptorMapType& GetAdaptorMap() const { return mAdaptorMap; }
243 // Factories management
244 /// Adds the factory to the set of factories which use the package
245 void AddFactory(FactoryPointer f) { mFactorySet.insert(f); }
246 /// Removes the factory from the set of factories which use the package
247 void RemoveFactory(FactoryPointer f) { mFactorySet.erase(f); }
250 typedef std::set<FactoryWeakPointer> FactorySet;
251 /// Gets the set of factories which use the package
252 FactorySet& GetFactorySet() { return mFactorySet; }
253 /// Gets the set of factories which use the package (const)
254 const FactorySet& GetFactorySet() const { return mFactorySet; }
257 bool ifBoxExist( std::string boxType );
261 /// Default ctor is private : use the static New method
263 /// A Package cannot be copy constructed
264 // Package(const Package&) {}
265 /// Ctor is private : use the static New method
266 Package(const std::string& name,
267 const std::string& author,
268 const std::string& description,
269 const std::string& version);
270 /// Does unload a package (no test)
271 static void UnLoad(Package::WeakPointer p);
273 /// The dynamic library handler of the package if it was loaded from a dl
274 DynamicLibraryHandler mDynamicLibraryHandler;
275 /// The pointer on the delete function of the package
276 /// in case it was loaded from a dynamic library
277 DLDeletePackageFunction mDLDeletePackageFunction;
280 /// The name of the package
282 /// The author of the package
284 /// The categories of the package
285 std::string mCategory;
286 /// The description of the package
287 std::string mDescription;
288 /// The version of the package
289 std::string mVersion;
290 /// URL of the documentation of the Package (absolute path)
292 /// URL of the documentation of the Package
293 /// (path relative to bbtk doc root)
294 std::string mDocRelativeURL;
296 /// The map of black boxes descriptors
297 DescriptorMapType mDescriptorMap;
299 /// The map of adaptors descriptors
300 AdaptorMapType mAdaptorMap;
303 /// The set of factories which contain the package
304 FactorySet mFactorySet;
306 /// The set of released dynamically loaded packages
307 /// to be unloaded explicitely calling
308 /// UnLoadReleasedDynamicallyLoadedPackages
309 static std::set<Package::WeakPointer>
310 mReleasedDynamicallyLoadedPackages;
313 //====================================================================
316 //====================================================================
318 #define BBTK_PACKAGE_EXPORT __declspec( dllexport )
320 #define BBTK_PACKAGE_EXPORT
321 #endif // defined(_WIN32)
322 //====================================================================
324 #define BBTK_GET_PACKAGE_FUNCTION_NAME GetPackage
325 #define BBTK_DEL_PACKAGE_FUNCTION_NAME DeletePackage
326 #define BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME GetPackageBBTKVersion
330 //====================================================================
331 #define BBTK_DECLARE_PACKAGE(NAME) \
334 bbtk::Package::Pointer& NAME ## GetPackagePointer(); \
335 BBTK_PACKAGE_EXPORT \
336 void BBTK_CDECL NAME ## DeletePackage (); \
337 BBTK_PACKAGE_EXPORT bbtk::Package::Pointer \
338 BBTK_CDECL NAME ## GetPackage (); \
339 BBTK_PACKAGE_EXPORT const std::string& \
340 BBTK_CDECL NAME ## GetPackageBBTKVersion (); \
342 //====================================================================
344 //====================================================================
345 #define BBTK_IMPLEMENT_PACKAGE(NAME,AUTHOR,DESCRIPTION,VERSION) \
348 bbtk::Package::Pointer& NAME ## GetPackagePointer() \
350 static bbtk::Package::Pointer u; \
353 BBTK_PACKAGE_EXPORT \
354 void BBTK_CDECL NAME ## DeletePackage () \
356 NAME ## GetPackagePointer().reset(); \
358 BBTK_PACKAGE_EXPORT \
359 bbtk::Package::Pointer \
360 BBTK_CDECL NAME ## GetPackage() \
362 if (!NAME ## GetPackagePointer()) { \
363 NAME ## GetPackagePointer() = \
364 bbtk::Package::New(#NAME, \
369 bbtk::Object::InsertInPackageList( NAME ## GetPackagePointer() ); \
371 return NAME ## GetPackagePointer(); \
373 BBTK_PACKAGE_EXPORT const std::string& \
374 BBTK_CDECL NAME ## GetPackageBBTKVersion () \
375 { return bbtk::GetVersion(); } \
376 class NAME ## PackageAutodestructor \
379 NAME ## PackageAutodestructor() {} \
380 ~NAME ## PackageAutodestructor() \
382 if (NAME ## GetPackagePointer().use_count()>0) \
384 bbtk::Package::WeakPointer p = NAME ## GetPackagePointer(); \
385 bbtk::Package::Release(p); \
389 NAME ## PackageAutodestructor NAME ## PackageAutodestructorInstance; \
391 //====================================================================
393 //====================================================================
394 #define BBTK_ADD_BLACK_BOX_TO_PACKAGE(NAME,CLASS) \
395 bool bbDummy##NAME##CLASS = NAME ## GetPackage () \
396 ->Register(CLASS ## Descriptor::Instance());
397 //====================================================================
399 //====================================================================
400 #define BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(NAME,CLASS,TEMPLATE_PARAM) \
401 bool bbDummy##NAME##CLASS##TEMPLATE_PARAM = NAME ## GetPackage () \
402 ->Register(CLASS ## Descriptor <TEMPLATE_PARAM>::Instance());
403 //====================================================================
405 //====================================================================
406 #define BBTK_ADD_TEMPLATE2_BLACK_BOX_TO_PACKAGE(NAME,CLASS,T1,T2) \
407 bool bbDummy##NAME##CLASS##T1##T2 = NAME ## GetPackage () \
408 ->Register(CLASS ## Descriptor <T1,T2>::Instance());
409 //====================================================================