]> Creatis software - bbtk.git/blob - kernel/src/bbtkPackage.h
*** empty log message ***
[bbtk.git] / kernel / src / bbtkPackage.h
1 /*=========================================================================                                                                               
2   Program:   bbtk
3   Module:    $RCSfile: bbtkPackage.h,v $
4   Language:  C++
5   Date:      $Date: 2008/10/17 08:18:14 $
6   Version:   $Revision: 1.11 $
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                        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);
67
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);
77
78     /// UnLoads released packages that were loaded dynamically
79     /// see UnLoadDynamicLibrary and ReleaseBlackBoxDescriptor
80     static void UnLoadReleasedDynamicallyLoadedPackages();
81
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);
96     
97     
98     typedef Package::Pointer (*DLGetPackageFunction)();
99     typedef void (*DLDeletePackageFunction)();
100     typedef const std::string& (*DLGetPackageBBTKVersionFunction)();
101
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&);
114
115  
116     /// Returns the name of the package
117     const std::string& GetName() const { return mName; }
118
119     /// Returns the author of the package
120     const std::string& GetAuthor() const { return mAuthor; }
121
122     /// Returns the category of the package
123     const std::string& GetCategory() const { return mCategory; }
124
125     /// Returns the description of the package
126     const std::string& GetDescription() const { return mDescription; }
127
128     /// Returns the version of the package
129     const std::string& GetVersion() const { return mVersion; }
130
131     bool ContainsBlackBox(const std::string& boxname) const;
132
133  
134     BlackBox::Pointer NewBlackBox(const std::string& type,
135                              const std::string& name) const;
136   
137     BlackBox::Pointer NewAdaptor(const DataInfo& typein,
138                          const DataInfo& typeout,
139                          const std::string& name) const;
140     
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;
150
151     bool RegisterBlackBox(BlackBoxDescriptor::Pointer); 
152
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;
157     
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 = "",
163                         int detail = 1, 
164                         int level = 0,
165                         bool relative_link = false ) const;
166
167     void  SetDocURL(std::string url){ mDocURL=url; }
168     const std::string& GetDocURL() const { return mDocURL; }
169     
170     void  SetDocRelativeURL(std::string url){ mDocRelativeURL=url; }
171     const std::string& GetDocRelativeURL() const { return mDocRelativeURL; }
172
173
174     unsigned int GetNumberOfBlackBoxes() const { return mBlackBoxMap.size(); }
175     
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> 
181     BlackBoxMapType;
182     const BlackBoxMapType& GetBlackBoxMap() const { return mBlackBoxMap; }
183     BlackBoxMapType& GetBlackBoxMap() { return mBlackBoxMap; }
184
185     /// The type of key in the map of adaptor descriptors
186     class AdaptorKey 
187     {
188     public:
189       AdaptorKey( const DataInfo& typein, const DataInfo& typeout, 
190                   BlackBoxDescriptor::Kind kind ) 
191         : mTypeIn(typein), mTypeOut(typeout), mKind(kind) {}
192       
193       bool operator< ( const AdaptorKey& k ) const
194       {
195         return ( ( mKind < k.mKind ) ||
196                  ( ( mKind == k.mKind ) &&
197                    ( ( mTypeIn < k.mTypeIn ) ||
198                      ( ( mTypeIn == k.mTypeIn ) && 
199                        ( mTypeOut < k.mTypeOut ) ) ) ) );
200       }
201       
202       bool operator== ( const AdaptorKey& k ) const
203       {
204         return ( ( mKind == k.mKind ) && 
205                  ( mTypeIn == k.mTypeIn ) && 
206                  ( mTypeOut == k.mTypeOut ) );
207       }
208       DataInfo mTypeIn;
209       DataInfo mTypeOut; 
210       BlackBoxDescriptor::Kind mKind;
211     };
212     
213     /// The type of map of adaptor descriptors
214     typedef std::map< AdaptorKey, BlackBoxDescriptor::WeakPointer> AdaptorMapType;
215
216  
217    const AdaptorMapType& GetAdaptorMap() const { return mAdaptorMap; }
218
219     
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); }
225
226     
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; }
232     
233     void CheckBoxes() const;
234
235   private:
236     /// Default ctor is private : use the static New method
237     //    Package() {}
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);
248
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;
254
255
256     /// The name of the package
257     std::string mName;
258     /// The author of the package
259     std::string mAuthor;
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)
267     std::string mDocURL;
268     /// URL of the documentation of the Package 
269     /// (path relative to bbtk doc root)
270     std::string mDocRelativeURL;
271
272     /// The map of black boxes descriptors
273     BlackBoxMapType mBlackBoxMap;
274
275     /// The map of adaptors descriptors
276     AdaptorMapType mAdaptorMap;
277
278
279     /// The set of factories which contain the package 
280     FactorySet mFactorySet;
281
282     /// The set of released dynamically loaded packages 
283     /// to be unloaded explicitely calling 
284     /// UnLoadReleasedDynamicallyLoadedPackages
285     static std::set<Package::WeakPointer> 
286     mReleasedDynamicallyLoadedPackages;
287   };
288   // EO class Package
289   //====================================================================
290
291
292 //====================================================================
293 #if defined(_WIN32)
294   #define BBTK_PACKAGE_EXPORT __declspec( dllexport )
295 #else
296   #define BBTK_PACKAGE_EXPORT
297 #endif // defined(_WIN32) 
298 //====================================================================
299
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
303   
304
305
306 //====================================================================
307 #define BBTK_DECLARE_PACKAGE(NAME)                                      \
308   extern "C"                                                            \
309   {                                                                     \
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 ();        \
317   }
318 //==================================================================== 
319
320 //==================================================================== 
321 #define BBTK_IMPLEMENT_PACKAGE(NAME,AUTHOR,DESCRIPTION,VERSION)         \
322   extern "C"                                                            \
323   {                                                                     \
324     bbtk::Package::Pointer& NAME ## GetPackagePointer()                 \
325     {                                                                   \
326       static bbtk::Package::Pointer u;                                  \
327       return u;                                                         \
328     }                                                                   \
329     BBTK_PACKAGE_EXPORT                                                 \
330     void BBTK_CDECL NAME ## DeletePackage ()                            \
331     {                                                                   \
332       NAME ## GetPackagePointer().reset();                              \
333     }                                                                   \
334     BBTK_PACKAGE_EXPORT                                                 \
335     bbtk::Package::Pointer                                              \
336     BBTK_CDECL NAME ## GetPackage()             \
337     {                                                                   \
338       if (!NAME ## GetPackagePointer())                                 \
339         NAME ## GetPackagePointer() =                                   \
340           bbtk::Package::New(#NAME,                                     \
341                              AUTHOR,                                    \
342                              DESCRIPTION,                               \
343                              VERSION,                                   \
344                              BBTK_STRINGIFY_SYMBOL(BBTK_VERSION)        \
345                              );                                         \
346       bbtk::Object::InsertInPackageList( NAME ## GetPackagePointer() ); \
347       return NAME ## GetPackagePointer();                               \
348     }                                                                   \
349     BBTK_PACKAGE_EXPORT const std::string&                              \
350     BBTK_CDECL NAME ## GetPackageBBTKVersion ()                         \
351     { return bbtk::GetVersion(); }                                      \
352     class NAME ## PackageAutodestructor                                 \
353     {                                                                   \
354     public:                                                             \
355       NAME ## PackageAutodestructor() {}                                \
356       ~NAME ## PackageAutodestructor()                                  \
357       {                                                                 \
358         if (NAME ## GetPackagePointer().use_count()>0)                  \
359           {                                                             \
360             bbtk::Package::WeakPointer p = NAME ## GetPackagePointer(); \
361             bbtk::Package::Release(p);                                  \
362           }                                                             \
363       }                                                                 \
364     };                                                                  \
365     NAME ## PackageAutodestructor NAME ## PackageAutodestructorInstance; \
366   }
367 //====================================================================  
368
369 //====================================================================
370 #define BBTK_ADD_BLACK_BOX_TO_PACKAGE(NAME,CLASS)                       \
371   bool bbDummy##NAME##CLASS = NAME ## GetPackage ()     \
372     ->RegisterBlackBox(CLASS ## Descriptor::Instance());
373   //====================================================================
374   
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   //====================================================================
380   
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   //====================================================================
386   
387
388 }// namespace bbtk
389
390
391
392 #endif
393