1 /*=========================================================================
3 Module: $RCSfile: bbtkPackage.h,v $
5 Date: $Date: 2008/10/17 08:18:14 $
6 Version: $Revision: 1.11 $
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 const std::string& BBTKVersion);
63 /// Creates a package from a dynamic library
64 static Pointer CreateFromDynamicLibrary(const std::string& libname,
65 const std::string& pkgname,
66 const std::string& path);
68 /// UnLoads the package dynamic library
69 /// (if any and if the package is released)
70 /// If doit == false then does not do it but just
71 /// put the package in the list of ReleasedDynamicallyLoadedPackages.
72 /// This is because we cannot close the dl from inside a
73 /// package member method or the program crashes.
74 /// The actual dl close must be done by an external user
75 /// calling UnLoadReleasedDynamicallyLoadedPackages
76 static void UnLoadDynamicLibrary(Package::WeakPointer p, bool doit = true);
78 /// UnLoads released packages that were loaded dynamically
79 /// see UnLoadDynamicLibrary and ReleaseBlackBoxDescriptor
80 static void UnLoadReleasedDynamicallyLoadedPackages();
82 /// "Releases" the package
83 /// Signals the package that it can free its descriptors
84 /// if they are no more used and frees and unloads the package
85 /// if it is no more used (released)
86 /// Note : Any non-weak pointer on the package must have been freed
87 static void Release(Package::WeakPointer p);
88 /// "Releases" a black box descriptor
89 /// Signals the package that it can free the given descriptor
90 /// if it is no more used and frees and put it the the
91 /// ReleasedDynamicallyLoadedPackages if it is dyn loaded
92 /// and no more used (released)
93 /// Note : Any non-weak pointer on the package must have been freed
94 static void ReleaseBlackBoxDescriptor(Package::WeakPointer p,
95 BlackBoxDescriptor::WeakPointer d);
98 typedef Package::Pointer (*DLGetPackageFunction)();
99 typedef void (*DLDeletePackageFunction)();
100 typedef const std::string& (*DLGetPackageBBTKVersionFunction)();
102 /// Opens a dynamic library which contains a bbtk package
103 /// Returns the handler
104 /// Load the package management symbols from the lib
105 /// returns false if a problem occured hence can be used
106 /// to test that a dyn lib is a valid bbtk package lib
107 /// NB : The BBTK version exported from the library
108 /// is tested against the current bbtk version
109 static DynamicLibraryHandler OpenDynamicLibrary
110 ( const std::string& dynamic_library_path,
111 const std::string& package_name,
112 DLGetPackageFunction&,
113 DLDeletePackageFunction&);
116 /// Returns the name of the package
117 const std::string& GetName() const { return mName; }
119 /// Returns the author of the package
120 const std::string& GetAuthor() const { return mAuthor; }
122 /// Returns the category of the package
123 const std::string& GetCategory() const { return mCategory; }
125 /// Returns the description of the package
126 const std::string& GetDescription() const { return mDescription; }
128 /// Returns the version of the package
129 const std::string& GetVersion() const { return mVersion; }
131 bool ContainsBlackBox(const std::string& boxname) const;
134 BlackBox::Pointer NewBlackBox(const std::string& type,
135 const std::string& name) const;
137 BlackBox::Pointer NewAdaptor(const DataInfo& typein,
138 const DataInfo& typeout,
139 const std::string& name) const;
141 BlackBox::Pointer NewWidgetAdaptor(const DataInfo& typein,
142 const DataInfo& typeout,
143 const std::string& name) const;
144 bool FindAdaptor(const DataInfo& typein,
145 const DataInfo& typeout,
146 std::string& adaptor) const;
147 bool FindWidgetAdaptor(const DataInfo& typein,
148 const DataInfo& typeout,
149 std::string& adaptor) const;
151 bool RegisterBlackBox(BlackBoxDescriptor::Pointer);
153 void PrintBlackBoxes(bool description = false,
154 bool adaptors = false) const;
155 void PrintAdaptors(bool description = false) const;
156 void HelpBlackBox(const std::string& name, bool full=true) const;
158 void CreateHtmlPage(const std::string& filename,
159 const std::string& caller = "?",
160 const std::string& source = "?",
161 const std::string& custom_header = "",
162 const std::string& custom_title = "",
165 bool relative_link = false ) const;
167 void SetDocURL(std::string url){ mDocURL=url; }
168 const std::string& GetDocURL() const { return mDocURL; }
170 void SetDocRelativeURL(std::string url){ mDocRelativeURL=url; }
171 const std::string& GetDocRelativeURL() const { return mDocRelativeURL; }
174 unsigned int GetNumberOfBlackBoxes() const { return mBlackBoxMap.size(); }
176 /// Changes the name of a black box type
177 void ChangeBlackBoxName( const std::string& oldname,
178 const std::string& newname );
179 /// The type of map of descriptors
180 typedef std::map< std::string, BlackBoxDescriptor::Pointer>
182 const BlackBoxMapType& GetBlackBoxMap() const { return mBlackBoxMap; }
183 BlackBoxMapType& GetBlackBoxMap() { return mBlackBoxMap; }
185 /// The type of key in the map of adaptor descriptors
189 AdaptorKey( const DataInfo& typein, const DataInfo& typeout,
190 BlackBoxDescriptor::Kind kind )
191 : mTypeIn(typein), mTypeOut(typeout), mKind(kind) {}
193 bool operator< ( const AdaptorKey& k ) const
195 return ( ( mKind < k.mKind ) ||
196 ( ( mKind == k.mKind ) &&
197 ( ( mTypeIn < k.mTypeIn ) ||
198 ( ( mTypeIn == k.mTypeIn ) &&
199 ( mTypeOut < k.mTypeOut ) ) ) ) );
202 bool operator== ( const AdaptorKey& k ) const
204 return ( ( mKind == k.mKind ) &&
205 ( mTypeIn == k.mTypeIn ) &&
206 ( mTypeOut == k.mTypeOut ) );
210 BlackBoxDescriptor::Kind mKind;
213 /// The type of map of adaptor descriptors
214 typedef std::map< AdaptorKey, BlackBoxDescriptor::WeakPointer> AdaptorMapType;
217 const AdaptorMapType& GetAdaptorMap() const { return mAdaptorMap; }
220 // Factories management
221 /// Adds the factory to the set of factories which use the package
222 void AddFactory(FactoryPointer f) { mFactorySet.insert(f); }
223 /// Removes the factory from the set of factories which use the package
224 void RemoveFactory(FactoryPointer f) { mFactorySet.erase(f); }
227 typedef std::set<FactoryWeakPointer> FactorySet;
228 /// Gets the set of factories which use the package
229 FactorySet& GetFactorySet() { return mFactorySet; }
230 /// Gets the set of factories which use the package (const)
231 const FactorySet& GetFactorySet() const { return mFactorySet; }
233 void CheckBoxes() const;
236 /// Default ctor is private : use the static New method
238 /// A Package cannot be copy constructed
239 // Package(const Package&) {}
240 /// Ctor is private : use the static New method
241 Package(const std::string& name,
242 const std::string& author,
243 const std::string& description,
244 const std::string& version,
245 const std::string& BBTKVersion);
246 /// Does unload a package (no test)
247 static void UnLoad(Package::WeakPointer p);
249 /// The dynamic library handler of the package if it was loaded from a dl
250 DynamicLibraryHandler mDynamicLibraryHandler;
251 /// The pointer on the delete function of the package
252 /// in case it was loaded from a dynamic library
253 DLDeletePackageFunction mDLDeletePackageFunction;
256 /// The name of the package
258 /// The author of the package
260 /// The categories of the package
261 std::string mCategory;
262 /// The description of the package
263 std::string mDescription;
264 /// The version of the package
265 std::string mVersion;
266 /// URL of the documentation of the Package (absolute path)
268 /// URL of the documentation of the Package
269 /// (path relative to bbtk doc root)
270 std::string mDocRelativeURL;
272 /// The map of black boxes descriptors
273 BlackBoxMapType mBlackBoxMap;
275 /// The map of adaptors descriptors
276 AdaptorMapType mAdaptorMap;
279 /// The set of factories which contain the package
280 FactorySet mFactorySet;
282 /// The set of released dynamically loaded packages
283 /// to be unloaded explicitely calling
284 /// UnLoadReleasedDynamicallyLoadedPackages
285 static std::set<Package::WeakPointer>
286 mReleasedDynamicallyLoadedPackages;
289 //====================================================================
292 //====================================================================
294 #define BBTK_PACKAGE_EXPORT __declspec( dllexport )
296 #define BBTK_PACKAGE_EXPORT
297 #endif // defined(_WIN32)
298 //====================================================================
300 #define BBTK_GET_PACKAGE_FUNCTION_NAME GetPackage
301 #define BBTK_DEL_PACKAGE_FUNCTION_NAME DeletePackage
302 #define BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME GetPackageBBTKVersion
306 //====================================================================
307 #define BBTK_DECLARE_PACKAGE(NAME) \
310 bbtk::Package::Pointer& NAME ## GetPackagePointer(); \
311 BBTK_PACKAGE_EXPORT \
312 void BBTK_CDECL NAME ## DeletePackage (); \
313 BBTK_PACKAGE_EXPORT bbtk::Package::Pointer \
314 BBTK_CDECL NAME ## GetPackage (); \
315 BBTK_PACKAGE_EXPORT const std::string& \
316 BBTK_CDECL NAME ## GetPackageBBTKVersion (); \
318 //====================================================================
320 //====================================================================
321 #define BBTK_IMPLEMENT_PACKAGE(NAME,AUTHOR,DESCRIPTION,VERSION) \
324 bbtk::Package::Pointer& NAME ## GetPackagePointer() \
326 static bbtk::Package::Pointer u; \
329 BBTK_PACKAGE_EXPORT \
330 void BBTK_CDECL NAME ## DeletePackage () \
332 NAME ## GetPackagePointer().reset(); \
334 BBTK_PACKAGE_EXPORT \
335 bbtk::Package::Pointer \
336 BBTK_CDECL NAME ## GetPackage() \
338 if (!NAME ## GetPackagePointer()) \
339 NAME ## GetPackagePointer() = \
340 bbtk::Package::New(#NAME, \
344 BBTK_STRINGIFY_SYMBOL(BBTK_VERSION) \
346 bbtk::Object::InsertInPackageList( NAME ## GetPackagePointer() ); \
347 return NAME ## GetPackagePointer(); \
349 BBTK_PACKAGE_EXPORT const std::string& \
350 BBTK_CDECL NAME ## GetPackageBBTKVersion () \
351 { return bbtk::GetVersion(); } \
352 class NAME ## PackageAutodestructor \
355 NAME ## PackageAutodestructor() {} \
356 ~NAME ## PackageAutodestructor() \
358 if (NAME ## GetPackagePointer().use_count()>0) \
360 bbtk::Package::WeakPointer p = NAME ## GetPackagePointer(); \
361 bbtk::Package::Release(p); \
365 NAME ## PackageAutodestructor NAME ## PackageAutodestructorInstance; \
367 //====================================================================
369 //====================================================================
370 #define BBTK_ADD_BLACK_BOX_TO_PACKAGE(NAME,CLASS) \
371 bool bbDummy##NAME##CLASS = NAME ## GetPackage () \
372 ->RegisterBlackBox(CLASS ## Descriptor::Instance());
373 //====================================================================
375 //====================================================================
376 #define BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(NAME,CLASS,TEMPLATE_PARAM) \
377 bool bbDummy##NAME##CLASS##TEMPLATE_PARAM = NAME ## GetPackage () \
378 ->RegisterBlackBox(CLASS ## Descriptor <TEMPLATE_PARAM>::Instance());
379 //====================================================================
381 //====================================================================
382 #define BBTK_ADD_TEMPLATE2_BLACK_BOX_TO_PACKAGE(NAME,CLASS,T1,T2) \
383 bool bbDummy##NAME##CLASS##T1##T2 = NAME ## GetPackage () \
384 ->RegisterBlackBox(CLASS ## Descriptor <T1,T2>::Instance());
385 //====================================================================