]> Creatis software - bbtk.git/blob - kernel/src/bbtkPackage.h
.
[bbtk.git] / kernel / src / bbtkPackage.h
1 /*=========================================================================                                                                               
2   Program:   bbtk
3   Module:    $RCSfile: bbtkPackage.h,v $
4   Language:  C++
5   Date:      $Date: 2009/05/28 08:26:59 $
6   Version:   $Revision: 1.14 $
7 =========================================================================*/
8
9 /* ---------------------------------------------------------------------
10
11 * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
12 * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
13 *
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.
20 *
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
25 *  liability. 
26 *
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 * ------------------------------------------------------------------------ */                                                                         
30
31 /**
32  * \file
33  * \brief Class bbtk::Package : registers black boxes descriptors and is able to create instances of the black boxes registered.
34  */
35 /**
36  * \class bbtk::Package
37  * \brief registers black boxes descriptors and is able to create instances of the black boxes registered.
38  */
39
40 #ifndef __bbtkPackage_h__
41 #define __bbtkPackage_h__
42
43 #include "bbtkBlackBox.h"
44 #include "bbtkDynamicLibraryHandling.h"
45
46 namespace bbtk
47 {
48
49   class Factory;
50   BBTK_FORWARD_DECLARE_POINTER(Factory);
51
52   class BBTK_EXPORT Package : public Object
53   {
54     BBTK_OBJECT_INTERFACE(Package);
55     typedef Object Superclass;
56   public:
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);
66
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
73
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);
83
84     /// UnLoads released packages that were loaded dynamically
85     /// see UnLoadDynamicLibrary and ReleaseBlackBoxDescriptor
86     static void UnLoadReleasedDynamicallyLoadedPackages();
87
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);
95     /// "Releases" a black box descriptor
96     /// Signals the package that it can free the given descriptor
97     /// if it is no more used and frees and put it the the 
98     /// ReleasedDynamicallyLoadedPackages if it is dyn loaded 
99     /// and no more used (released)
100     /// Note : Any non-weak pointer on the package must have been freed
101     static void ReleaseBlackBoxDescriptor(Package::WeakPointer p,
102                                           BlackBoxDescriptor::WeakPointer d);
103     
104     
105     typedef Package::Pointer (*DLGetPackageFunction)();
106     typedef void (*DLDeletePackageFunction)();
107     typedef const std::string& (*DLGetPackageBBTKVersionFunction)();
108
109     /// Opens a dynamic library which contains a bbtk package
110     /// Returns the handler 
111     /// Load the package management symbols from the lib
112     /// returns false if a problem occured hence can be used 
113     /// to test that a dyn lib is a valid bbtk package lib
114     /// NB : The BBTK version exported from the library 
115     ///      is tested against the current bbtk version
116     static DynamicLibraryHandler OpenDynamicLibrary
117     ( const std::string& dynamic_library_path,
118       const std::string& package_name,
119       DLGetPackageFunction&,
120       DLDeletePackageFunction&);
121
122  
123     /// Returns the name of the package
124     const std::string& GetName() const { return mName; }
125
126     /// Returns the author of the package
127     const std::string& GetAuthor() const { return mAuthor; }
128
129     /// Returns the category of the package
130     const std::string& GetCategory() const { return mCategory; }
131
132     /// Returns the description of the package
133     const std::string& GetDescription() const { return mDescription; }
134
135     /// Returns the version of the package
136     const std::string& GetVersion() const { return mVersion; }
137
138         bool ContainsBlackBox(const std::string& boxname) const;
139
140  
141     BlackBox::Pointer NewBlackBox(const std::string& type,
142                              const std::string& name) const;
143   
144     BlackBox::Pointer NewAdaptor(const DataInfo& typein,
145                          const DataInfo& typeout,
146                          const std::string& name) const;
147     
148     BlackBox::Pointer NewWidgetAdaptor(const DataInfo& typein,
149                               const DataInfo& typeout,
150                               const std::string& name) const;
151     bool FindAdaptor(const DataInfo& typein,
152                            const DataInfo& typeout,
153                            std::string& adaptor) const;
154     bool FindWidgetAdaptor(const DataInfo& typein,
155                            const DataInfo& typeout,
156                            std::string& adaptor) const;
157
158     bool RegisterBlackBox(BlackBoxDescriptor::Pointer); 
159
160     void PrintBlackBoxes(bool description = false, 
161                          bool adaptors = false) const;
162     void PrintAdaptors(bool description = false) const;
163     void HelpBlackBox(const std::string& name, bool full=true) const;
164     
165     void CreateHtmlPage(const std::string& filename,
166                         const std::string& caller = "?",
167                         const std::string& source = "?",
168                         const std::string& custom_header = "",
169                         const std::string& custom_title = "",
170                         int detail = 1, 
171                         int level = 0,
172                         bool relative_link = false ) const;
173
174     void  SetDocURL(std::string url){ mDocURL=url; }
175     const std::string& GetDocURL() const { return mDocURL; }
176     
177     void  SetDocRelativeURL(std::string url){ mDocRelativeURL=url; }
178     const std::string& GetDocRelativeURL() const { return mDocRelativeURL; }
179
180
181     unsigned int GetNumberOfBlackBoxes() const { return mBlackBoxMap.size(); }
182     
183     /// Changes the name of a black box type
184     void ChangeBlackBoxName( const std::string& oldname, 
185                              const std::string& newname );
186     /// The type of map of descriptors
187     typedef std::map< std::string, BlackBoxDescriptor::Pointer> 
188     BlackBoxMapType;
189     const BlackBoxMapType& GetBlackBoxMap() const { return mBlackBoxMap; }
190     BlackBoxMapType& GetBlackBoxMap() { return mBlackBoxMap; }
191
192     /// The type of key in the map of adaptor descriptors
193     class AdaptorKey 
194     {
195     public:
196       AdaptorKey( const DataInfo& typein, const DataInfo& typeout, 
197                   BlackBoxDescriptor::Kind kind ) 
198         : mTypeIn(typein), mTypeOut(typeout), mKind(kind) {}
199       
200       bool operator< ( const AdaptorKey& k ) const
201       {
202         return ( ( mKind < k.mKind ) ||
203                  ( ( mKind == k.mKind ) &&
204                    ( ( mTypeIn < k.mTypeIn ) ||
205                      ( ( mTypeIn == k.mTypeIn ) && 
206                        ( mTypeOut < k.mTypeOut ) ) ) ) );
207       }
208       
209       bool operator== ( const AdaptorKey& k ) const
210       {
211         return ( ( mKind == k.mKind ) && 
212                  ( mTypeIn == k.mTypeIn ) && 
213                  ( mTypeOut == k.mTypeOut ) );
214       }
215       DataInfo mTypeIn;
216       DataInfo mTypeOut; 
217       BlackBoxDescriptor::Kind mKind;
218     };
219     
220     /// The type of map of adaptor descriptors
221     typedef std::map< AdaptorKey, BlackBoxDescriptor::WeakPointer> AdaptorMapType;
222
223  
224    const AdaptorMapType& GetAdaptorMap() const { return mAdaptorMap; }
225
226     
227     // Factories management
228     /// Adds the factory to the set of factories which use the package
229     void AddFactory(FactoryPointer f) { mFactorySet.insert(f); }
230     /// Removes the factory from the set of factories which use the package
231     void RemoveFactory(FactoryPointer f) { mFactorySet.erase(f); }
232
233     
234     typedef std::set<FactoryWeakPointer> FactorySet;
235     /// Gets the set of factories which use the package
236     FactorySet& GetFactorySet() { return mFactorySet; }
237     /// Gets the set of factories which use the package (const)
238     const FactorySet& GetFactorySet() const { return mFactorySet; }
239     
240     void CheckBoxes() const;
241
242   private:
243     /// Default ctor is private : use the static New method
244     //    Package() {}
245     /// A Package cannot be copy constructed
246     //    Package(const Package&) {}
247     /// Ctor is private : use the static New method
248     Package(const std::string& name,
249             const std::string& author,
250             const std::string& description,
251             const std::string& version);
252     /// Does unload a package (no test)
253     static void UnLoad(Package::WeakPointer p);
254
255     /// The dynamic library handler of the package if it was loaded from a dl
256     DynamicLibraryHandler mDynamicLibraryHandler;
257     /// The pointer on the delete function of the package 
258     /// in case it was loaded from a dynamic library
259     DLDeletePackageFunction mDLDeletePackageFunction;
260
261
262     /// The name of the package
263     std::string mName;
264     /// The author of the package
265     std::string mAuthor;
266     /// The categories of the package
267     std::string mCategory;    
268     /// The description of the package
269     std::string mDescription;
270     /// The version of the package
271     std::string mVersion;
272     /// URL of the documentation of the Package (absolute path)
273     std::string mDocURL;
274     /// URL of the documentation of the Package 
275     /// (path relative to bbtk doc root)
276     std::string mDocRelativeURL;
277
278     /// The map of black boxes descriptors
279     BlackBoxMapType mBlackBoxMap;
280
281     /// The map of adaptors descriptors
282     AdaptorMapType mAdaptorMap;
283
284
285     /// The set of factories which contain the package 
286     FactorySet mFactorySet;
287
288     /// The set of released dynamically loaded packages 
289     /// to be unloaded explicitely calling 
290     /// UnLoadReleasedDynamicallyLoadedPackages
291     static std::set<Package::WeakPointer> 
292     mReleasedDynamicallyLoadedPackages;
293   };
294   // EO class Package
295   //====================================================================
296
297
298 //====================================================================
299 #if defined(_WIN32)
300   #define BBTK_PACKAGE_EXPORT __declspec( dllexport )
301 #else
302   #define BBTK_PACKAGE_EXPORT
303 #endif // defined(_WIN32) 
304 //====================================================================
305
306 #define BBTK_GET_PACKAGE_FUNCTION_NAME GetPackage
307 #define BBTK_DEL_PACKAGE_FUNCTION_NAME DeletePackage
308 #define BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME GetPackageBBTKVersion
309   
310
311
312 //====================================================================
313 #define BBTK_DECLARE_PACKAGE(NAME)                                      \
314   extern "C"                                                            \
315   {                                                                     \
316     bbtk::Package::Pointer& NAME ## GetPackagePointer();                \
317     BBTK_PACKAGE_EXPORT                                                 \
318     void BBTK_CDECL NAME ## DeletePackage ();           \
319     BBTK_PACKAGE_EXPORT bbtk::Package::Pointer                          \
320     BBTK_CDECL NAME ## GetPackage ();           \
321     BBTK_PACKAGE_EXPORT const std::string&                              \
322     BBTK_CDECL NAME ## GetPackageBBTKVersion ();        \
323   }
324 //==================================================================== 
325
326 //==================================================================== 
327 #define BBTK_IMPLEMENT_PACKAGE(NAME,AUTHOR,DESCRIPTION,VERSION)         \
328   extern "C"                                                            \
329   {                                                                     \
330     bbtk::Package::Pointer& NAME ## GetPackagePointer()                 \
331     {                                                                   \
332       static bbtk::Package::Pointer u;                                  \
333       return u;                                                         \
334     }                                                                   \
335     BBTK_PACKAGE_EXPORT                                                 \
336     void BBTK_CDECL NAME ## DeletePackage ()                            \
337     {                                                                   \
338       NAME ## GetPackagePointer().reset();                              \
339     }                                                                   \
340     BBTK_PACKAGE_EXPORT                                                 \
341     bbtk::Package::Pointer                                              \
342     BBTK_CDECL NAME ## GetPackage()             \
343     {                                                                   \
344         if (!NAME ## GetPackagePointer())               {                       \
345           NAME ## GetPackagePointer() =                                 \
346               bbtk::Package::New(#NAME,                                 \
347                              AUTHOR,                                    \
348                              DESCRIPTION,                               \
349                              VERSION    \
350                              );                                         \
351            bbtk::Object::InsertInPackageList( NAME ## GetPackagePointer() );  \
352          }                                              \
353       return NAME ## GetPackagePointer();                               \
354     }                                                                   \
355     BBTK_PACKAGE_EXPORT const std::string&                              \
356     BBTK_CDECL NAME ## GetPackageBBTKVersion ()                         \
357     { return bbtk::GetVersion(); }                                      \
358     class NAME ## PackageAutodestructor                                 \
359     {                                                                   \
360     public:                                                             \
361       NAME ## PackageAutodestructor() {}                                \
362       ~NAME ## PackageAutodestructor()                                  \
363       {                                                                 \
364         if (NAME ## GetPackagePointer().use_count()>0)                  \
365           {                                                             \
366             bbtk::Package::WeakPointer p = NAME ## GetPackagePointer(); \
367             bbtk::Package::Release(p);                                  \
368           }                                                             \
369       }                                                                 \
370     };                                                                  \
371     NAME ## PackageAutodestructor NAME ## PackageAutodestructorInstance; \
372   }
373 //====================================================================  
374
375 //====================================================================
376 #define BBTK_ADD_BLACK_BOX_TO_PACKAGE(NAME,CLASS)                       \
377   bool bbDummy##NAME##CLASS = NAME ## GetPackage ()     \
378     ->RegisterBlackBox(CLASS ## Descriptor::Instance());
379   //====================================================================
380   
381   //====================================================================
382 #define BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(NAME,CLASS,TEMPLATE_PARAM) \
383   bool bbDummy##NAME##CLASS##TEMPLATE_PARAM = NAME ## GetPackage ()     \
384     ->RegisterBlackBox(CLASS ## Descriptor <TEMPLATE_PARAM>::Instance());
385   //====================================================================
386   
387   //====================================================================
388 #define BBTK_ADD_TEMPLATE2_BLACK_BOX_TO_PACKAGE(NAME,CLASS,T1,T2)       \
389   bool bbDummy##NAME##CLASS##T1##T2 = NAME ## GetPackage ()             \
390     ->RegisterBlackBox(CLASS ## Descriptor <T1,T2>::Instance()); 
391   //====================================================================
392   
393
394 }// namespace bbtk
395
396
397
398 #endif
399