]> 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: 2009/06/08 14:50:04 $
6   Version:   $Revision: 1.15 $
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
96
97     /// Registers the BlackBoxDescriptor in the Package
98     bool Register(BlackBoxDescriptor::Pointer); 
99
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);
108     
109     
110     typedef Package::Pointer (*DLGetPackageFunction)();
111     typedef void (*DLDeletePackageFunction)();
112     typedef const std::string& (*DLGetPackageBBTKVersionFunction)();
113
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&);
126
127  
128     /// Returns the name of the package
129     const std::string& GetName() const { return mName; }
130
131     /// Returns the author of the package
132     const std::string& GetAuthor() const { return mAuthor; }
133
134     /// Returns the category of the package
135     const std::string& GetCategory() const { return mCategory; }
136
137     /// Returns the description of the package
138     const std::string& GetDescription() const { return mDescription; }
139
140     /// Returns the version of the package
141     const std::string& GetVersion() const { return mVersion; }
142
143     /// Returns true iff the package contains a BlackBoxDescriptor
144     /// with the name provided
145     bool ContainsDescriptor(const std::string& name) const;
146
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;
150     
151     /// Creates a new adaptor BlackBox for the given input and output types 
152     /// with name name
153     BlackBox::Pointer NewAdaptor(const DataInfo& typein,
154                                  const DataInfo& typeout,
155                                  const std::string& name) const;
156     
157     /// Creates a new widget adaptor BlackBox 
158     /// for the given input and output types 
159     /// with name name
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;
169
170
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;
178     
179
180
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 = "",
186                         int detail = 1, 
187                         int level = 0,
188                         bool relative_link = false ) const;
189
190     void  SetDocURL(std::string url){ mDocURL=url; }
191     const std::string& GetDocURL() const { return mDocURL; }
192     
193     void  SetDocRelativeURL(std::string url){ mDocRelativeURL=url; }
194     const std::string& GetDocRelativeURL() const { return mDocRelativeURL; }
195
196
197     unsigned int GetNumberOfDescriptors() const { return mDescriptorMap.size(); }
198     
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> 
204     DescriptorMapType;
205     const DescriptorMapType& GetDescriptorMap() const { return mDescriptorMap; }
206     DescriptorMapType& GetDescriptorMap() { return mDescriptorMap; }
207
208     /// The type of key in the map of adaptor descriptors
209     class AdaptorKey 
210     {
211     public:
212       AdaptorKey( const DataInfo& typein, const DataInfo& typeout, 
213                   BlackBoxDescriptor::Kind kind ) 
214         : mTypeIn(typein), mTypeOut(typeout), mKind(kind) {}
215       
216       bool operator< ( const AdaptorKey& k ) const
217       {
218         return ( ( mKind < k.mKind ) ||
219                  ( ( mKind == k.mKind ) &&
220                    ( ( mTypeIn < k.mTypeIn ) ||
221                      ( ( mTypeIn == k.mTypeIn ) && 
222                        ( mTypeOut < k.mTypeOut ) ) ) ) );
223       }
224       
225       bool operator== ( const AdaptorKey& k ) const
226       {
227         return ( ( mKind == k.mKind ) && 
228                  ( mTypeIn == k.mTypeIn ) && 
229                  ( mTypeOut == k.mTypeOut ) );
230       }
231       DataInfo mTypeIn;
232       DataInfo mTypeOut; 
233       BlackBoxDescriptor::Kind mKind;
234     };
235     
236     /// The type of map of adaptor descriptors
237     typedef std::map< AdaptorKey, BlackBoxDescriptor::WeakPointer> AdaptorMapType;
238
239  
240    const AdaptorMapType& GetAdaptorMap() const { return mAdaptorMap; }
241
242     
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); }
248
249     
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; }
255     
256     void Check() const;
257
258   private:
259     /// Default ctor is private : use the static New method
260     //    Package() {}
261     /// A Package cannot be copy constructed
262     //    Package(const Package&) {}
263     /// Ctor is private : use the static New method
264     Package(const std::string& name,
265             const std::string& author,
266             const std::string& description,
267             const std::string& version);
268     /// Does unload a package (no test)
269     static void UnLoad(Package::WeakPointer p);
270
271     /// The dynamic library handler of the package if it was loaded from a dl
272     DynamicLibraryHandler mDynamicLibraryHandler;
273     /// The pointer on the delete function of the package 
274     /// in case it was loaded from a dynamic library
275     DLDeletePackageFunction mDLDeletePackageFunction;
276
277
278     /// The name of the package
279     std::string mName;
280     /// The author of the package
281     std::string mAuthor;
282     /// The categories of the package
283     std::string mCategory;    
284     /// The description of the package
285     std::string mDescription;
286     /// The version of the package
287     std::string mVersion;
288     /// URL of the documentation of the Package (absolute path)
289     std::string mDocURL;
290     /// URL of the documentation of the Package 
291     /// (path relative to bbtk doc root)
292     std::string mDocRelativeURL;
293
294     /// The map of black boxes descriptors
295     DescriptorMapType mDescriptorMap;
296
297     /// The map of adaptors descriptors
298     AdaptorMapType mAdaptorMap;
299
300
301     /// The set of factories which contain the package 
302     FactorySet mFactorySet;
303
304     /// The set of released dynamically loaded packages 
305     /// to be unloaded explicitely calling 
306     /// UnLoadReleasedDynamicallyLoadedPackages
307     static std::set<Package::WeakPointer> 
308     mReleasedDynamicallyLoadedPackages;
309   };
310   // EO class Package
311   //====================================================================
312
313
314 //====================================================================
315 #if defined(_WIN32)
316   #define BBTK_PACKAGE_EXPORT __declspec( dllexport )
317 #else
318   #define BBTK_PACKAGE_EXPORT
319 #endif // defined(_WIN32) 
320 //====================================================================
321
322 #define BBTK_GET_PACKAGE_FUNCTION_NAME GetPackage
323 #define BBTK_DEL_PACKAGE_FUNCTION_NAME DeletePackage
324 #define BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME GetPackageBBTKVersion
325   
326
327
328 //====================================================================
329 #define BBTK_DECLARE_PACKAGE(NAME)                                      \
330   extern "C"                                                            \
331   {                                                                     \
332     bbtk::Package::Pointer& NAME ## GetPackagePointer();                \
333     BBTK_PACKAGE_EXPORT                                                 \
334     void BBTK_CDECL NAME ## DeletePackage ();           \
335     BBTK_PACKAGE_EXPORT bbtk::Package::Pointer                          \
336     BBTK_CDECL NAME ## GetPackage ();           \
337     BBTK_PACKAGE_EXPORT const std::string&                              \
338     BBTK_CDECL NAME ## GetPackageBBTKVersion ();        \
339   }
340 //==================================================================== 
341
342 //==================================================================== 
343 #define BBTK_IMPLEMENT_PACKAGE(NAME,AUTHOR,DESCRIPTION,VERSION)         \
344   extern "C"                                                            \
345   {                                                                     \
346     bbtk::Package::Pointer& NAME ## GetPackagePointer()                 \
347     {                                                                   \
348       static bbtk::Package::Pointer u;                                  \
349       return u;                                                         \
350     }                                                                   \
351     BBTK_PACKAGE_EXPORT                                                 \
352     void BBTK_CDECL NAME ## DeletePackage ()                            \
353     {                                                                   \
354       NAME ## GetPackagePointer().reset();                              \
355     }                                                                   \
356     BBTK_PACKAGE_EXPORT                                                 \
357     bbtk::Package::Pointer                                              \
358     BBTK_CDECL NAME ## GetPackage()             \
359     {                                                                   \
360         if (!NAME ## GetPackagePointer())               {                       \
361           NAME ## GetPackagePointer() =                                 \
362               bbtk::Package::New(#NAME,                                 \
363                              AUTHOR,                                    \
364                              DESCRIPTION,                               \
365                              VERSION    \
366                              );                                         \
367            bbtk::Object::InsertInPackageList( NAME ## GetPackagePointer() );  \
368          }                                              \
369       return NAME ## GetPackagePointer();                               \
370     }                                                                   \
371     BBTK_PACKAGE_EXPORT const std::string&                              \
372     BBTK_CDECL NAME ## GetPackageBBTKVersion ()                         \
373     { return bbtk::GetVersion(); }                                      \
374     class NAME ## PackageAutodestructor                                 \
375     {                                                                   \
376     public:                                                             \
377       NAME ## PackageAutodestructor() {}                                \
378       ~NAME ## PackageAutodestructor()                                  \
379       {                                                                 \
380         if (NAME ## GetPackagePointer().use_count()>0)                  \
381           {                                                             \
382             bbtk::Package::WeakPointer p = NAME ## GetPackagePointer(); \
383             bbtk::Package::Release(p);                                  \
384           }                                                             \
385       }                                                                 \
386     };                                                                  \
387     NAME ## PackageAutodestructor NAME ## PackageAutodestructorInstance; \
388   }
389 //====================================================================  
390
391 //====================================================================
392 #define BBTK_ADD_BLACK_BOX_TO_PACKAGE(NAME,CLASS)                       \
393   bool bbDummy##NAME##CLASS = NAME ## GetPackage ()     \
394     ->Register(CLASS ## Descriptor::Instance());
395   //====================================================================
396   
397   //====================================================================
398 #define BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(NAME,CLASS,TEMPLATE_PARAM) \
399   bool bbDummy##NAME##CLASS##TEMPLATE_PARAM = NAME ## GetPackage ()     \
400     ->Register(CLASS ## Descriptor <TEMPLATE_PARAM>::Instance());
401   //====================================================================
402   
403   //====================================================================
404 #define BBTK_ADD_TEMPLATE2_BLACK_BOX_TO_PACKAGE(NAME,CLASS,T1,T2)       \
405   bool bbDummy##NAME##CLASS##T1##T2 = NAME ## GetPackage ()             \
406     ->Register(CLASS ## Descriptor <T1,T2>::Instance()); 
407   //====================================================================
408   
409
410 }// namespace bbtk
411
412
413
414 #endif
415