1 /*=========================================================================
4 Module: $RCSfile: bbtkPackage.h,v $
6 Date: $Date: 2008/07/24 14:37:05 $
7 Version: $Revision: 1.10 $
9 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10 l'Image). All rights reserved. See doc/license.txt or
11 http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
13 This software is distributed WITHOUT ANY WARRANTY; without even
14 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 PURPOSE. See the above copyright notices for more information.
17 =========================================================================*/
20 * \brief Class bbtk::Package : registers black boxes descriptors and is able to create instances of the black boxes registered.
23 * \class bbtk::Package
24 * \brief registers black boxes descriptors and is able to create instances of the black boxes registered.
27 #ifndef __bbtkPackage_h__
28 #define __bbtkPackage_h__
30 #include "bbtkBlackBox.h"
31 #include "bbtkDynamicLibraryHandling.h"
37 BBTK_FORWARD_DECLARE_POINTER(Factory);
39 class BBTK_EXPORT Package : public Object
41 BBTK_OBJECT_INTERFACE(Package);
42 typedef Object Superclass;
44 /// Creates a new package
45 static Pointer New(const std::string& name,
46 const std::string& author,
47 const std::string& description,
48 const std::string& version,
49 const std::string& BBTKVersion);
50 /// Creates a package from a dynamic library
51 static Pointer CreateFromDynamicLibrary(const std::string& libname,
52 const std::string& pkgname,
53 const std::string& path);
55 /// UnLoads the package dynamic library
56 /// (if any and if the package is released)
57 /// If doit == false then does not do it but just
58 /// put the package in the list of ReleasedDynamicallyLoadedPackages.
59 /// This is because we cannot close the dl from inside a
60 /// package member method or the program crashes.
61 /// The actual dl close must be done by an external user
62 /// calling UnLoadReleasedDynamicallyLoadedPackages
63 static void UnLoadDynamicLibrary(Package::WeakPointer p, bool doit = true);
65 /// UnLoads released packages that were loaded dynamically
66 /// see UnLoadDynamicLibrary and ReleaseBlackBoxDescriptor
67 static void UnLoadReleasedDynamicallyLoadedPackages();
69 /// "Releases" the package
70 /// Signals the package that it can free its descriptors
71 /// if they are no more used and frees and unloads the package
72 /// if it is no more used (released)
73 /// Note : Any non-weak pointer on the package must have been freed
74 static void Release(Package::WeakPointer p);
75 /// "Releases" a black box descriptor
76 /// Signals the package that it can free the given descriptor
77 /// if it is no more used and frees and put it the the
78 /// ReleasedDynamicallyLoadedPackages if it is dyn loaded
79 /// and no more used (released)
80 /// Note : Any non-weak pointer on the package must have been freed
81 static void ReleaseBlackBoxDescriptor(Package::WeakPointer p,
82 BlackBoxDescriptor::WeakPointer d);
85 typedef Package::Pointer (*DLGetPackageFunction)();
86 typedef void (*DLDeletePackageFunction)();
87 typedef const std::string& (*DLGetPackageBBTKVersionFunction)();
89 /// Opens a dynamic library which contains a bbtk package
90 /// Returns the handler
91 /// Load the package management symbols from the lib
92 /// returns false if a problem occured hence can be used
93 /// to test that a dyn lib is a valid bbtk package lib
94 /// NB : The BBTK version exported from the library
95 /// is tested against the current bbtk version
96 static DynamicLibraryHandler OpenDynamicLibrary
97 ( const std::string& dynamic_library_path,
98 const std::string& package_name,
99 DLGetPackageFunction&,
100 DLDeletePackageFunction&);
103 /// Returns the name of the package
104 const std::string& GetName() const { return mName; }
106 /// Returns the author of the package
107 const std::string& GetAuthor() const { return mAuthor; }
109 /// Returns the category of the package
110 const std::string& GetCategory() const { return mCategory; }
112 /// Returns the description of the package
113 const std::string& GetDescription() const { return mDescription; }
115 /// Returns the version of the package
116 const std::string& GetVersion() const { return mVersion; }
118 bool ContainsBlackBox(const std::string& boxname) const;
121 BlackBox::Pointer NewBlackBox(const std::string& type,
122 const std::string& name) const;
124 BlackBox::Pointer NewAdaptor(const DataInfo& typein,
125 const DataInfo& typeout,
126 const std::string& name) const;
128 BlackBox::Pointer NewWidgetAdaptor(const DataInfo& typein,
129 const DataInfo& typeout,
130 const std::string& name) const;
131 bool FindAdaptor(const DataInfo& typein,
132 const DataInfo& typeout,
133 std::string& adaptor) const;
134 bool FindWidgetAdaptor(const DataInfo& typein,
135 const DataInfo& typeout,
136 std::string& adaptor) const;
138 bool RegisterBlackBox(BlackBoxDescriptor::Pointer);
140 void PrintBlackBoxes(bool description = false,
141 bool adaptors = false) const;
142 void PrintAdaptors(bool description = false) const;
143 void HelpBlackBox(const std::string& name, bool full=true) const;
145 void CreateHtmlPage(const std::string& filename,
146 const std::string& caller = "?",
147 const std::string& source = "?",
148 const std::string& custom_header = "",
149 const std::string& custom_title = "",
152 bool relative_link = false ) const;
154 void SetDocURL(std::string url){ mDocURL=url; }
155 const std::string& GetDocURL() const { return mDocURL; }
157 void SetDocRelativeURL(std::string url){ mDocRelativeURL=url; }
158 const std::string& GetDocRelativeURL() const { return mDocRelativeURL; }
161 unsigned int GetNumberOfBlackBoxes() const { return mBlackBoxMap.size(); }
163 /// Changes the name of a black box type
164 void ChangeBlackBoxName( const std::string& oldname,
165 const std::string& newname );
166 /// The type of map of descriptors
167 typedef std::map< std::string, BlackBoxDescriptor::Pointer>
169 const BlackBoxMapType& GetBlackBoxMap() const { return mBlackBoxMap; }
170 BlackBoxMapType& GetBlackBoxMap() { return mBlackBoxMap; }
172 /// The type of key in the map of adaptor descriptors
176 AdaptorKey( const DataInfo& typein, const DataInfo& typeout,
177 BlackBoxDescriptor::Kind kind )
178 : mTypeIn(typein), mTypeOut(typeout), mKind(kind) {}
180 bool operator< ( const AdaptorKey& k ) const
182 return ( ( mKind < k.mKind ) ||
183 ( ( mKind == k.mKind ) &&
184 ( ( mTypeIn < k.mTypeIn ) ||
185 ( ( mTypeIn == k.mTypeIn ) &&
186 ( mTypeOut < k.mTypeOut ) ) ) ) );
189 bool operator== ( const AdaptorKey& k ) const
191 return ( ( mKind == k.mKind ) &&
192 ( mTypeIn == k.mTypeIn ) &&
193 ( mTypeOut == k.mTypeOut ) );
197 BlackBoxDescriptor::Kind mKind;
200 /// The type of map of adaptor descriptors
201 typedef std::map< AdaptorKey, BlackBoxDescriptor::WeakPointer> AdaptorMapType;
204 const AdaptorMapType& GetAdaptorMap() const { return mAdaptorMap; }
207 // Factories management
208 /// Adds the factory to the set of factories which use the package
209 void AddFactory(FactoryPointer f) { mFactorySet.insert(f); }
210 /// Removes the factory from the set of factories which use the package
211 void RemoveFactory(FactoryPointer f) { mFactorySet.erase(f); }
214 typedef std::set<FactoryWeakPointer> FactorySet;
215 /// Gets the set of factories which use the package
216 FactorySet& GetFactorySet() { return mFactorySet; }
217 /// Gets the set of factories which use the package (const)
218 const FactorySet& GetFactorySet() const { return mFactorySet; }
220 void CheckBoxes() const;
223 /// Default ctor is private : use the static New method
225 /// A Package cannot be copy constructed
226 // Package(const Package&) {}
227 /// Ctor is private : use the static New method
228 Package(const std::string& name,
229 const std::string& author,
230 const std::string& description,
231 const std::string& version,
232 const std::string& BBTKVersion);
233 /// Does unload a package (no test)
234 static void UnLoad(Package::WeakPointer p);
236 /// The dynamic library handler of the package if it was loaded from a dl
237 DynamicLibraryHandler mDynamicLibraryHandler;
238 /// The pointer on the delete function of the package
239 /// in case it was loaded from a dynamic library
240 DLDeletePackageFunction mDLDeletePackageFunction;
243 /// The name of the package
245 /// The author of the package
247 /// The categories of the package
248 std::string mCategory;
249 /// The description of the package
250 std::string mDescription;
251 /// The version of the package
252 std::string mVersion;
253 /// URL of the documentation of the Package (absolute path)
255 /// URL of the documentation of the Package
256 /// (path relative to bbtk doc root)
257 std::string mDocRelativeURL;
259 /// The map of black boxes descriptors
260 BlackBoxMapType mBlackBoxMap;
262 /// The map of adaptors descriptors
263 AdaptorMapType mAdaptorMap;
266 /// The set of factories which contain the package
267 FactorySet mFactorySet;
269 /// The set of released dynamically loaded packages
270 /// to be unloaded explicitely calling
271 /// UnLoadReleasedDynamicallyLoadedPackages
272 static std::set<Package::WeakPointer>
273 mReleasedDynamicallyLoadedPackages;
276 //====================================================================
279 //====================================================================
281 #define BBTK_PACKAGE_EXPORT __declspec( dllexport )
283 #define BBTK_PACKAGE_EXPORT
284 #endif // defined(_WIN32)
285 //====================================================================
287 #define BBTK_GET_PACKAGE_FUNCTION_NAME GetPackage
288 #define BBTK_DEL_PACKAGE_FUNCTION_NAME DeletePackage
289 #define BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME GetPackageBBTKVersion
293 //====================================================================
294 #define BBTK_DECLARE_PACKAGE(NAME) \
297 bbtk::Package::Pointer& NAME ## GetPackagePointer(); \
298 BBTK_PACKAGE_EXPORT \
299 void BBTK_CDECL NAME ## DeletePackage (); \
300 BBTK_PACKAGE_EXPORT bbtk::Package::Pointer \
301 BBTK_CDECL NAME ## GetPackage (); \
302 BBTK_PACKAGE_EXPORT const std::string& \
303 BBTK_CDECL NAME ## GetPackageBBTKVersion (); \
305 //====================================================================
307 //====================================================================
308 #define BBTK_IMPLEMENT_PACKAGE(NAME,AUTHOR,DESCRIPTION,VERSION) \
311 bbtk::Package::Pointer& NAME ## GetPackagePointer() \
313 static bbtk::Package::Pointer u; \
316 BBTK_PACKAGE_EXPORT \
317 void BBTK_CDECL NAME ## DeletePackage () \
319 NAME ## GetPackagePointer().reset(); \
321 BBTK_PACKAGE_EXPORT \
322 bbtk::Package::Pointer \
323 BBTK_CDECL NAME ## GetPackage() \
325 if (!NAME ## GetPackagePointer()) \
326 NAME ## GetPackagePointer() = \
327 bbtk::Package::New(#NAME, \
331 BBTK_STRINGIFY_SYMBOL(BBTK_VERSION) \
333 bbtk::Object::InsertInPackageList( NAME ## GetPackagePointer() ); \
334 return NAME ## GetPackagePointer(); \
336 BBTK_PACKAGE_EXPORT const std::string& \
337 BBTK_CDECL NAME ## GetPackageBBTKVersion () \
338 { return bbtk::GetVersion(); } \
339 class NAME ## PackageAutodestructor \
342 NAME ## PackageAutodestructor() {} \
343 ~NAME ## PackageAutodestructor() \
345 if (NAME ## GetPackagePointer().use_count()>0) \
347 bbtk::Package::WeakPointer p = NAME ## GetPackagePointer(); \
348 bbtk::Package::Release(p); \
352 NAME ## PackageAutodestructor NAME ## PackageAutodestructorInstance; \
354 //====================================================================
356 //====================================================================
357 #define BBTK_ADD_BLACK_BOX_TO_PACKAGE(NAME,CLASS) \
358 bool bbDummy##NAME##CLASS = NAME ## GetPackage () \
359 ->RegisterBlackBox(CLASS ## Descriptor::Instance());
360 //====================================================================
362 //====================================================================
363 #define BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(NAME,CLASS,TEMPLATE_PARAM) \
364 bool bbDummy##NAME##CLASS##TEMPLATE_PARAM = NAME ## GetPackage () \
365 ->RegisterBlackBox(CLASS ## Descriptor <TEMPLATE_PARAM>::Instance());
366 //====================================================================
368 //====================================================================
369 #define BBTK_ADD_TEMPLATE2_BLACK_BOX_TO_PACKAGE(NAME,CLASS,T1,T2) \
370 bool bbDummy##NAME##CLASS##T1##T2 = NAME ## GetPackage () \
371 ->RegisterBlackBox(CLASS ## Descriptor <T1,T2>::Instance());
372 //====================================================================