]> Creatis software - bbtk.git/blob - kernel/src/bbtkPackage.h
f39dfc6d7dcb049c1cce7581a94c56a5a78fd398
[bbtk.git] / kernel / src / bbtkPackage.h
1 /*
2  # ---------------------------------------------------------------------
3  #
4  # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
5  #                        pour la SantÈ)
6  # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
7  # Previous Authors : Laurent Guigues, Jean-Pierre Roux
8  # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
9  #
10  #  This software is governed by the CeCILL-B license under French law and
11  #  abiding by the rules of distribution of free software. You can  use,
12  #  modify and/ or redistribute the software under the terms of the CeCILL-B
13  #  license as circulated by CEA, CNRS and INRIA at the following URL
14  #  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
15  #  or in the file LICENSE.txt.
16  #
17  #  As a counterpart to the access to the source code and  rights to copy,
18  #  modify and redistribute granted by the license, users are provided only
19  #  with a limited warranty  and the software's author,  the holder of the
20  #  economic rights,  and the successive licensors  have only  limited
21  #  liability.
22  #
23  #  The fact that you are presently reading this means that you have had
24  #  knowledge of the CeCILL-B license and that you accept its terms.
25  # ------------------------------------------------------------------------ */
26
27
28 /*=========================================================================
29   Program:   bbtk
30   Module:    $RCSfile: bbtkPackage.h,v $
31   Language:  C++
32   Date:      $Date: 2012/11/16 08:49:01 $
33   Version:   $Revision: 1.18 $
34 =========================================================================*/
35
36
37
38 /**
39  * \file
40  * \brief Class bbtk::Package : registers black boxes descriptors and is able to create instances of the black boxes registered.
41  */
42 /**
43  * \class bbtk::Package
44  * \brief registers black boxes descriptors and is able to create instances of the black boxes registered.
45  */
46
47 #ifndef __bbtkPackage_h__
48 #define __bbtkPackage_h__
49
50 #include "bbtkBlackBox.h"
51 #include "bbtkDynamicLibraryHandling.h"
52 #include "bbtkUtilities.h"
53 #include <vector>
54
55 namespace bbtk
56 {
57
58   class Factory;
59   BBTK_FORWARD_DECLARE_POINTER(Factory);
60
61   class BBTK_EXPORT Package : public Object
62   {
63     BBTK_OBJECT_INTERFACE(Package);
64     typedef Object Superclass;
65   public:
66     /// Creates a new package
67     static Pointer New(const std::string& name,
68                        const std::string& author,
69                        const std::string& description,
70                        const std::string& version);
71     /// Creates a package from a dynamic library
72     static Pointer CreateFromDynamicLibrary(const std::string& libname,
73                                             const std::string& pkgname,
74                                             const std::string& path);
75
76         void  GetBoxesInside(NodeTreeC& tree, std::vector<std::string>& list, int cont);
77     /// NOTE : All the static methods below for package destruction
78     /// are not member because they can cause the package death 
79     /// and thus close the dynamic library from which it has been loaded.
80     /// If the dynamic lib which provides a function is closed while 
81     /// in the function: imagine the crash !
82     /// The principal method is Release
83
84     /// UnLoads the package dynamic library 
85     /// (if any and if the package is released)
86     /// If doit == false then does not do it but just 
87     /// put the package in the list of ReleasedDynamicallyLoadedPackages.
88     /// This is because we cannot close the dl from inside a 
89     /// package member method or the program crashes.
90     /// The actual dl close must be done by an external user 
91     /// calling UnLoadReleasedDynamicallyLoadedPackages
92     static void UnLoadDynamicLibrary(Package::WeakPointer p, bool doit = true);
93
94     /// UnLoads released packages that were loaded dynamically
95     /// see UnLoadDynamicLibrary and ReleaseBlackBoxDescriptor
96     static void UnLoadReleasedDynamicallyLoadedPackages();
97
98     /// "Releases" the package
99     /// Signals the package that it can free its descriptors 
100     /// if they are no more used 
101     /// then frees and unloads the package 
102     /// if it is no more used (released)
103     /// Note : Any non-weak pointer on the package must have been freed
104     static void Release(Package::WeakPointer p);
105
106
107     /// Registers the BlackBoxDescriptor in the Package
108     bool Register(BlackBoxDescriptor::Pointer); 
109
110     /// "Releases" a black box descriptor
111     /// Signals the package that it can free the given descriptor
112     /// if it is no more used and frees and put it the the 
113     /// ReleasedDynamicallyLoadedPackages if it is dyn loaded 
114     /// and no more used (released)
115     /// Note : Any non-weak pointer on the package must have been freed
116     static void ReleaseBlackBoxDescriptor(Package::WeakPointer p,
117                                           BlackBoxDescriptor::WeakPointer d);
118     
119     
120     typedef Package::Pointer (*DLGetPackageFunction)();
121     typedef void (*DLDeletePackageFunction)();
122     typedef const std::string& (*DLGetPackageBBTKVersionFunction)();
123
124     /// Opens a dynamic library which contains a bbtk package
125     /// Returns the handler 
126     /// Load the package management symbols from the lib
127     /// returns false if a problem occured hence can be used 
128     /// to test that a dyn lib is a valid bbtk package lib
129     /// NB : The BBTK version exported from the library 
130     ///      is tested against the current bbtk version
131     static DynamicLibraryHandler OpenDynamicLibrary
132     ( const std::string& dynamic_library_path,
133       const std::string& package_name,
134       DLGetPackageFunction&,
135       DLDeletePackageFunction&);
136
137  
138     /// Returns the name of the package
139     const std::string& GetName() const { return mName; }
140
141     /// Returns the author of the package
142     const std::string& GetAuthor() const { return mAuthor; }
143
144     /// Returns the category of the package
145     const std::string& GetCategory() const { return mCategory; }
146
147     /// Returns the description of the package
148     const std::string& GetDescription() const { return mDescription; }
149
150     /// Returns the version of the package
151     const std::string& GetVersion() const { return mVersion; }
152
153     /// Returns true iff the package contains a BlackBoxDescriptor
154     /// with the name provided
155     bool ContainsDescriptor(const std::string& name) const;
156
157     /// Creates a new BlackBox of given type with name name
158     BlackBox::Pointer NewBlackBox(const std::string& type,
159                              const std::string& name) const;
160     
161     /// Creates a new adaptor BlackBox for the given input and output types 
162     /// with name name
163     BlackBox::Pointer NewAdaptor(const DataInfo& typein,
164                                  const DataInfo& typeout,
165                                  const std::string& name) const;
166     
167     /// Creates a new widget adaptor BlackBox 
168     /// for the given input and output types 
169     /// with name name
170     BlackBox::Pointer NewWidgetAdaptor(const DataInfo& typein,
171                                        const DataInfo& typeout,
172                                        const std::string& name) const;
173     bool FindAdaptor(const DataInfo& typein,
174                      const DataInfo& typeout,
175                      std::string& adaptor) const;
176     bool FindWidgetAdaptor(const DataInfo& typein,
177                            const DataInfo& typeout,
178                            std::string& adaptor) const;
179
180
181     /// Displays the list of black box descriptors of the package    
182     void PrintHelpListDescriptors(bool description = false, 
183                               bool adaptors = false) const;
184     /// Displays the list of adaptors of the package
185     void PrintHelpListAdaptors(bool description = false) const;
186     /// Prints help on a particular Descriptor
187     void PrintHelpDescriptor(const std::string& name, bool full=true) const;
188     
189
190
191     void CreateHtmlPage(const std::string& filename,
192                         const std::string& caller = "?",
193                         const std::string& source = "?",
194                         const std::string& custom_header = "",
195                         const std::string& custom_title = "",
196                         int detail = 1, 
197                         int level = 0,
198                         bool relative_link = false ) const;
199
200     void  SetDocURL(std::string url){ mDocURL=url; }
201     const std::string& GetDocURL() const { return mDocURL; }
202     
203     void  SetDocRelativeURL(std::string url){ mDocRelativeURL=url; }
204     const std::string& GetDocRelativeURL() const { return mDocRelativeURL; }
205
206
207     unsigned int GetNumberOfDescriptors() const { return mDescriptorMap.size(); }
208     
209     /// Changes the name of a descriptor
210     void ChangeDescriptorName( const std::string& oldname, 
211                                const std::string& newname );
212     /// The type of map of descriptors
213     typedef std::map< std::string, BlackBoxDescriptor::Pointer> 
214     DescriptorMapType;
215     const DescriptorMapType& GetDescriptorMap() const { return mDescriptorMap; }
216     DescriptorMapType& GetDescriptorMap() { return mDescriptorMap; }
217
218     /// The type of key in the map of adaptor descriptors
219     class AdaptorKey 
220     {
221     public:
222       AdaptorKey( const DataInfo& typein, const DataInfo& typeout, 
223                   BlackBoxDescriptor::Kind kind ) 
224         : mTypeIn(typein), mTypeOut(typeout), mKind(kind) {}
225       
226       bool operator< ( const AdaptorKey& k ) const
227       {
228         return ( ( mKind < k.mKind ) ||
229                  ( ( mKind == k.mKind ) &&
230                    ( ( mTypeIn < k.mTypeIn ) ||
231                      ( ( mTypeIn == k.mTypeIn ) && 
232                        ( mTypeOut < k.mTypeOut ) ) ) ) );
233       }
234       
235       bool operator== ( const AdaptorKey& k ) const
236       {
237         return ( ( mKind == k.mKind ) && 
238                  ( mTypeIn == k.mTypeIn ) && 
239                  ( mTypeOut == k.mTypeOut ) );
240       }
241       DataInfo mTypeIn;
242       DataInfo mTypeOut; 
243       BlackBoxDescriptor::Kind mKind;
244     };
245     
246     /// The type of map of adaptor descriptors
247     typedef std::map< AdaptorKey, BlackBoxDescriptor::WeakPointer> AdaptorMapType;
248
249  
250    const AdaptorMapType& GetAdaptorMap() const { return mAdaptorMap; }
251
252     
253     // Factories management
254     /// Adds the factory to the set of factories which use the package
255     void AddFactory(FactoryPointer f) { mFactorySet.insert(f); }
256     /// Removes the factory from the set of factories which use the package
257     void RemoveFactory(FactoryPointer f) { mFactorySet.erase(f); }
258
259     
260     typedef std::set<FactoryWeakPointer> FactorySet;
261     /// Gets the set of factories which use the package
262     FactorySet& GetFactorySet() { return mFactorySet; }
263     /// Gets the set of factories which use the package (const)
264     const FactorySet& GetFactorySet() const { return mFactorySet; }
265     
266     void Check() const;
267           bool ifBoxExist( std::string boxType );
268
269           
270   private:
271     /// Default ctor is private : use the static New method
272     //    Package() {}
273     /// A Package cannot be copy constructed
274     //    Package(const Package&) {}
275     /// Ctor is private : use the static New method
276     Package(const std::string& name,
277             const std::string& author,
278             const std::string& description,
279             const std::string& version);
280     /// Does unload a package (no test)
281     static void UnLoad(Package::WeakPointer p);
282
283     /// The dynamic library handler of the package if it was loaded from a dl
284     DynamicLibraryHandler mDynamicLibraryHandler;
285     /// The pointer on the delete function of the package 
286     /// in case it was loaded from a dynamic library
287     DLDeletePackageFunction mDLDeletePackageFunction;
288
289
290     /// The name of the package
291     std::string mName;
292     /// The author of the package
293     std::string mAuthor;
294     /// The categories of the package
295     std::string mCategory;    
296     /// The description of the package
297     std::string mDescription;
298     /// The version of the package
299     std::string mVersion;
300     /// URL of the documentation of the Package (absolute path)
301     std::string mDocURL;
302     /// URL of the documentation of the Package 
303     /// (path relative to bbtk doc root)
304     std::string mDocRelativeURL;
305
306     /// The map of black boxes descriptors
307     DescriptorMapType mDescriptorMap;
308
309     /// The map of adaptors descriptors
310     AdaptorMapType mAdaptorMap;
311
312
313     /// The set of factories which contain the package 
314     FactorySet mFactorySet;
315
316     /// The set of released dynamically loaded packages 
317     /// to be unloaded explicitely calling 
318     /// UnLoadReleasedDynamicallyLoadedPackages
319     static std::set<Package::WeakPointer> 
320     mReleasedDynamicallyLoadedPackages;
321   };
322   // EO class Package
323   //====================================================================
324
325
326 //====================================================================
327 #if defined(_WIN32)
328   #define BBTK_PACKAGE_EXPORT __declspec( dllexport )
329 #else
330   #define BBTK_PACKAGE_EXPORT
331 #endif // defined(_WIN32) 
332 //====================================================================
333
334 #define BBTK_GET_PACKAGE_FUNCTION_NAME GetPackage
335 #define BBTK_DEL_PACKAGE_FUNCTION_NAME DeletePackage
336 #define BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME GetPackageBBTKVersion
337   
338
339
340 //====================================================================
341 #define BBTK_DECLARE_PACKAGE(NAME)                                      \
342   extern "C"                                                            \
343   {                                                                     \
344     bbtk::Package::Pointer& NAME ## GetPackagePointer();                \
345     BBTK_PACKAGE_EXPORT                                                 \
346     void BBTK_CDECL NAME ## DeletePackage ();           \
347     BBTK_PACKAGE_EXPORT bbtk::Package::Pointer                          \
348     BBTK_CDECL NAME ## GetPackage ();           \
349     BBTK_PACKAGE_EXPORT const std::string&                              \
350     BBTK_CDECL NAME ## GetPackageBBTKVersion ();        \
351   }
352 //==================================================================== 
353
354 //==================================================================== 
355 #define BBTK_IMPLEMENT_PACKAGE(NAME,AUTHOR,DESCRIPTION,VERSION)         \
356   extern "C"                                                            \
357   {                                                                     \
358     bbtk::Package::Pointer& NAME ## GetPackagePointer()                 \
359     {                                                                   \
360       static bbtk::Package::Pointer u;                                  \
361       return u;                                                         \
362     }                                                                   \
363     BBTK_PACKAGE_EXPORT                                                 \
364     void BBTK_CDECL NAME ## DeletePackage ()                            \
365     {                                                                   \
366       NAME ## GetPackagePointer().reset();                              \
367     }                                                                   \
368     BBTK_PACKAGE_EXPORT                                                 \
369     bbtk::Package::Pointer                                              \
370     BBTK_CDECL NAME ## GetPackage()             \
371     {                                                                   \
372         if (!NAME ## GetPackagePointer())               {                       \
373           NAME ## GetPackagePointer() =                                 \
374               bbtk::Package::New(#NAME,                                 \
375                              AUTHOR,                                    \
376                              DESCRIPTION,                               \
377                              VERSION    \
378                              );                                         \
379            bbtk::Object::InsertInPackageList( NAME ## GetPackagePointer() );  \
380          }                                              \
381       return NAME ## GetPackagePointer();                               \
382     }                                                                   \
383     BBTK_PACKAGE_EXPORT const std::string&                              \
384     BBTK_CDECL NAME ## GetPackageBBTKVersion ()                                                                                 \
385     { static const std::string v(BBTK_STRINGIFY_SYMBOL(BBTK_VERSION));     return v; }  \
386     class NAME ## PackageAutodestructor                                 \
387     {                                                                   \
388     public:                                                             \
389       NAME ## PackageAutodestructor() {}                                \
390       ~NAME ## PackageAutodestructor()                                  \
391       {                                                                 \
392         if (NAME ## GetPackagePointer().use_count()>0)                  \
393           {                                                             \
394             bbtk::Package::WeakPointer p = NAME ## GetPackagePointer(); \
395             bbtk::Package::Release(p);                                  \
396           }                                                             \
397       }                                                                 \
398     };                                                                  \
399     NAME ## PackageAutodestructor NAME ## PackageAutodestructorInstance; \
400   }
401 //====================================================================  
402
403 //====================================================================
404 #define BBTK_ADD_BLACK_BOX_TO_PACKAGE(NAME,CLASS)                       \
405   bool bbDummy##NAME##CLASS = NAME ## GetPackage ()     \
406     ->Register(CLASS ## Descriptor::Instance());
407   //====================================================================
408   
409   //====================================================================
410 #define BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(NAME,CLASS,TEMPLATE_PARAM) \
411   bool bbDummy##NAME##CLASS##TEMPLATE_PARAM = NAME ## GetPackage ()     \
412     ->Register(CLASS ## Descriptor <TEMPLATE_PARAM>::Instance());
413   //====================================================================
414   
415   //====================================================================
416 #define BBTK_ADD_TEMPLATE2_BLACK_BOX_TO_PACKAGE(NAME,CLASS,T1,T2)       \
417   bool bbDummy##NAME##CLASS##T1##T2 = NAME ## GetPackage ()             \
418     ->Register(CLASS ## Descriptor <T1,T2>::Instance()); 
419   //====================================================================
420   
421
422 }// namespace bbtk
423
424
425
426 #endif
427