]> Creatis software - bbtk.git/blob - kernel/src/bbtkPackage.h
96e3bfc2bdba355fa6f1e9105d35c351786a2097
[bbtk.git] / kernel / src / bbtkPackage.h
1 /*=========================================================================                                                                               
2   Program:   bbtk
3   Module:    $RCSfile: bbtkPackage.h,v $
4   Language:  C++
5   Date:      $Date: 2012/11/14 07:12:00 $
6   Version:   $Revision: 1.17 $
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           bool ifBoxExist( std::string boxType );
258
259           
260   private:
261     /// Default ctor is private : use the static New method
262     //    Package() {}
263     /// A Package cannot be copy constructed
264     //    Package(const Package&) {}
265     /// Ctor is private : use the static New method
266     Package(const std::string& name,
267             const std::string& author,
268             const std::string& description,
269             const std::string& version);
270     /// Does unload a package (no test)
271     static void UnLoad(Package::WeakPointer p);
272
273     /// The dynamic library handler of the package if it was loaded from a dl
274     DynamicLibraryHandler mDynamicLibraryHandler;
275     /// The pointer on the delete function of the package 
276     /// in case it was loaded from a dynamic library
277     DLDeletePackageFunction mDLDeletePackageFunction;
278
279
280     /// The name of the package
281     std::string mName;
282     /// The author of the package
283     std::string mAuthor;
284     /// The categories of the package
285     std::string mCategory;    
286     /// The description of the package
287     std::string mDescription;
288     /// The version of the package
289     std::string mVersion;
290     /// URL of the documentation of the Package (absolute path)
291     std::string mDocURL;
292     /// URL of the documentation of the Package 
293     /// (path relative to bbtk doc root)
294     std::string mDocRelativeURL;
295
296     /// The map of black boxes descriptors
297     DescriptorMapType mDescriptorMap;
298
299     /// The map of adaptors descriptors
300     AdaptorMapType mAdaptorMap;
301
302
303     /// The set of factories which contain the package 
304     FactorySet mFactorySet;
305
306     /// The set of released dynamically loaded packages 
307     /// to be unloaded explicitely calling 
308     /// UnLoadReleasedDynamicallyLoadedPackages
309     static std::set<Package::WeakPointer> 
310     mReleasedDynamicallyLoadedPackages;
311   };
312   // EO class Package
313   //====================================================================
314
315
316 //====================================================================
317 #if defined(_WIN32)
318   #define BBTK_PACKAGE_EXPORT __declspec( dllexport )
319 #else
320   #define BBTK_PACKAGE_EXPORT
321 #endif // defined(_WIN32) 
322 //====================================================================
323
324 #define BBTK_GET_PACKAGE_FUNCTION_NAME GetPackage
325 #define BBTK_DEL_PACKAGE_FUNCTION_NAME DeletePackage
326 #define BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME GetPackageBBTKVersion
327   
328
329
330 //====================================================================
331 #define BBTK_DECLARE_PACKAGE(NAME)                                      \
332   extern "C"                                                            \
333   {                                                                     \
334     bbtk::Package::Pointer& NAME ## GetPackagePointer();                \
335     BBTK_PACKAGE_EXPORT                                                 \
336     void BBTK_CDECL NAME ## DeletePackage ();           \
337     BBTK_PACKAGE_EXPORT bbtk::Package::Pointer                          \
338     BBTK_CDECL NAME ## GetPackage ();           \
339     BBTK_PACKAGE_EXPORT const std::string&                              \
340     BBTK_CDECL NAME ## GetPackageBBTKVersion ();        \
341   }
342 //==================================================================== 
343
344 //==================================================================== 
345 #define BBTK_IMPLEMENT_PACKAGE(NAME,AUTHOR,DESCRIPTION,VERSION)         \
346   extern "C"                                                            \
347   {                                                                     \
348     bbtk::Package::Pointer& NAME ## GetPackagePointer()                 \
349     {                                                                   \
350       static bbtk::Package::Pointer u;                                  \
351       return u;                                                         \
352     }                                                                   \
353     BBTK_PACKAGE_EXPORT                                                 \
354     void BBTK_CDECL NAME ## DeletePackage ()                            \
355     {                                                                   \
356       NAME ## GetPackagePointer().reset();                              \
357     }                                                                   \
358     BBTK_PACKAGE_EXPORT                                                 \
359     bbtk::Package::Pointer                                              \
360     BBTK_CDECL NAME ## GetPackage()             \
361     {                                                                   \
362         if (!NAME ## GetPackagePointer())               {                       \
363           NAME ## GetPackagePointer() =                                 \
364               bbtk::Package::New(#NAME,                                 \
365                              AUTHOR,                                    \
366                              DESCRIPTION,                               \
367                              VERSION    \
368                              );                                         \
369            bbtk::Object::InsertInPackageList( NAME ## GetPackagePointer() );  \
370          }                                              \
371       return NAME ## GetPackagePointer();                               \
372     }                                                                   \
373     BBTK_PACKAGE_EXPORT const std::string&                              \
374     BBTK_CDECL NAME ## GetPackageBBTKVersion ()                                                                                 \
375     { static const std::string v(BBTK_STRINGIFY_SYMBOL(BBTK_VERSION));     return v; }  \
376     class NAME ## PackageAutodestructor                                 \
377     {                                                                   \
378     public:                                                             \
379       NAME ## PackageAutodestructor() {}                                \
380       ~NAME ## PackageAutodestructor()                                  \
381       {                                                                 \
382         if (NAME ## GetPackagePointer().use_count()>0)                  \
383           {                                                             \
384             bbtk::Package::WeakPointer p = NAME ## GetPackagePointer(); \
385             bbtk::Package::Release(p);                                  \
386           }                                                             \
387       }                                                                 \
388     };                                                                  \
389     NAME ## PackageAutodestructor NAME ## PackageAutodestructorInstance; \
390   }
391 //====================================================================  
392
393 //====================================================================
394 #define BBTK_ADD_BLACK_BOX_TO_PACKAGE(NAME,CLASS)                       \
395   bool bbDummy##NAME##CLASS = NAME ## GetPackage ()     \
396     ->Register(CLASS ## Descriptor::Instance());
397   //====================================================================
398   
399   //====================================================================
400 #define BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(NAME,CLASS,TEMPLATE_PARAM) \
401   bool bbDummy##NAME##CLASS##TEMPLATE_PARAM = NAME ## GetPackage ()     \
402     ->Register(CLASS ## Descriptor <TEMPLATE_PARAM>::Instance());
403   //====================================================================
404   
405   //====================================================================
406 #define BBTK_ADD_TEMPLATE2_BLACK_BOX_TO_PACKAGE(NAME,CLASS,T1,T2)       \
407   bool bbDummy##NAME##CLASS##T1##T2 = NAME ## GetPackage ()             \
408     ->Register(CLASS ## Descriptor <T1,T2>::Instance()); 
409   //====================================================================
410   
411
412 }// namespace bbtk
413
414
415
416 #endif
417