]> 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/01/13 08:45:27 $
6   Version:   $Revision: 1.12 $
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     /// UnLoads the package dynamic library 
68     /// (if any and if the package is released)
69     /// If doit == false then does not do it but just 
70     /// put the package in the list of ReleasedDynamicallyLoadedPackages.
71     /// This is because we cannot close the dl from inside a 
72     /// package member method or the program crashes.
73     /// The actual dl close must be done by an external user 
74     /// calling UnLoadReleasedDynamicallyLoadedPackages
75     static void UnLoadDynamicLibrary(Package::WeakPointer p, bool doit = true);
76
77     /// UnLoads released packages that were loaded dynamically
78     /// see UnLoadDynamicLibrary and ReleaseBlackBoxDescriptor
79     static void UnLoadReleasedDynamicallyLoadedPackages();
80
81     /// "Releases" the package
82     /// Signals the package that it can free its descriptors 
83     /// if they are no more used and frees and unloads the package 
84     /// if it is no more used (released)
85     /// Note : Any non-weak pointer on the package must have been freed
86     static void Release(Package::WeakPointer p);
87     /// "Releases" a black box descriptor
88     /// Signals the package that it can free the given descriptor
89     /// if it is no more used and frees and put it the the 
90     /// ReleasedDynamicallyLoadedPackages if it is dyn loaded 
91     /// and no more used (released)
92     /// Note : Any non-weak pointer on the package must have been freed
93     static void ReleaseBlackBoxDescriptor(Package::WeakPointer p,
94                                           BlackBoxDescriptor::WeakPointer d);
95     
96     
97     typedef Package::Pointer (*DLGetPackageFunction)();
98     typedef void (*DLDeletePackageFunction)();
99     typedef const std::string& (*DLGetPackageBBTKVersionFunction)();
100
101     /// Opens a dynamic library which contains a bbtk package
102     /// Returns the handler 
103     /// Load the package management symbols from the lib
104     /// returns false if a problem occured hence can be used 
105     /// to test that a dyn lib is a valid bbtk package lib
106     /// NB : The BBTK version exported from the library 
107     ///      is tested against the current bbtk version
108     static DynamicLibraryHandler OpenDynamicLibrary
109     ( const std::string& dynamic_library_path,
110       const std::string& package_name,
111       DLGetPackageFunction&,
112       DLDeletePackageFunction&);
113
114  
115     /// Returns the name of the package
116     const std::string& GetName() const { return mName; }
117
118     /// Returns the author of the package
119     const std::string& GetAuthor() const { return mAuthor; }
120
121     /// Returns the category of the package
122     const std::string& GetCategory() const { return mCategory; }
123
124     /// Returns the description of the package
125     const std::string& GetDescription() const { return mDescription; }
126
127     /// Returns the version of the package
128     const std::string& GetVersion() const { return mVersion; }
129
130         bool ContainsBlackBox(const std::string& boxname) const;
131
132  
133     BlackBox::Pointer NewBlackBox(const std::string& type,
134                              const std::string& name) const;
135   
136     BlackBox::Pointer NewAdaptor(const DataInfo& typein,
137                          const DataInfo& typeout,
138                          const std::string& name) const;
139     
140     BlackBox::Pointer NewWidgetAdaptor(const DataInfo& typein,
141                               const DataInfo& typeout,
142                               const std::string& name) const;
143     bool FindAdaptor(const DataInfo& typein,
144                            const DataInfo& typeout,
145                            std::string& adaptor) const;
146     bool FindWidgetAdaptor(const DataInfo& typein,
147                            const DataInfo& typeout,
148                            std::string& adaptor) const;
149
150     bool RegisterBlackBox(BlackBoxDescriptor::Pointer); 
151
152     void PrintBlackBoxes(bool description = false, 
153                          bool adaptors = false) const;
154     void PrintAdaptors(bool description = false) const;
155     void HelpBlackBox(const std::string& name, bool full=true) const;
156     
157     void CreateHtmlPage(const std::string& filename,
158                         const std::string& caller = "?",
159                         const std::string& source = "?",
160                         const std::string& custom_header = "",
161                         const std::string& custom_title = "",
162                         int detail = 1, 
163                         int level = 0,
164                         bool relative_link = false ) const;
165
166     void  SetDocURL(std::string url){ mDocURL=url; }
167     const std::string& GetDocURL() const { return mDocURL; }
168     
169     void  SetDocRelativeURL(std::string url){ mDocRelativeURL=url; }
170     const std::string& GetDocRelativeURL() const { return mDocRelativeURL; }
171
172
173     unsigned int GetNumberOfBlackBoxes() const { return mBlackBoxMap.size(); }
174     
175     /// Changes the name of a black box type
176     void ChangeBlackBoxName( const std::string& oldname, 
177                              const std::string& newname );
178     /// The type of map of descriptors
179     typedef std::map< std::string, BlackBoxDescriptor::Pointer> 
180     BlackBoxMapType;
181     const BlackBoxMapType& GetBlackBoxMap() const { return mBlackBoxMap; }
182     BlackBoxMapType& GetBlackBoxMap() { return mBlackBoxMap; }
183
184     /// The type of key in the map of adaptor descriptors
185     class AdaptorKey 
186     {
187     public:
188       AdaptorKey( const DataInfo& typein, const DataInfo& typeout, 
189                   BlackBoxDescriptor::Kind kind ) 
190         : mTypeIn(typein), mTypeOut(typeout), mKind(kind) {}
191       
192       bool operator< ( const AdaptorKey& k ) const
193       {
194         return ( ( mKind < k.mKind ) ||
195                  ( ( mKind == k.mKind ) &&
196                    ( ( mTypeIn < k.mTypeIn ) ||
197                      ( ( mTypeIn == k.mTypeIn ) && 
198                        ( mTypeOut < k.mTypeOut ) ) ) ) );
199       }
200       
201       bool operator== ( const AdaptorKey& k ) const
202       {
203         return ( ( mKind == k.mKind ) && 
204                  ( mTypeIn == k.mTypeIn ) && 
205                  ( mTypeOut == k.mTypeOut ) );
206       }
207       DataInfo mTypeIn;
208       DataInfo mTypeOut; 
209       BlackBoxDescriptor::Kind mKind;
210     };
211     
212     /// The type of map of adaptor descriptors
213     typedef std::map< AdaptorKey, BlackBoxDescriptor::WeakPointer> AdaptorMapType;
214
215  
216    const AdaptorMapType& GetAdaptorMap() const { return mAdaptorMap; }
217
218     
219     // Factories management
220     /// Adds the factory to the set of factories which use the package
221     void AddFactory(FactoryPointer f) { mFactorySet.insert(f); }
222     /// Removes the factory from the set of factories which use the package
223     void RemoveFactory(FactoryPointer f) { mFactorySet.erase(f); }
224
225     
226     typedef std::set<FactoryWeakPointer> FactorySet;
227     /// Gets the set of factories which use the package
228     FactorySet& GetFactorySet() { return mFactorySet; }
229     /// Gets the set of factories which use the package (const)
230     const FactorySet& GetFactorySet() const { return mFactorySet; }
231     
232     void CheckBoxes() const;
233
234   private:
235     /// Default ctor is private : use the static New method
236     //    Package() {}
237     /// A Package cannot be copy constructed
238     //    Package(const Package&) {}
239     /// Ctor is private : use the static New method
240     Package(const std::string& name,
241             const std::string& author,
242             const std::string& description,
243             const std::string& version);
244     /// Does unload a package (no test)
245     static void UnLoad(Package::WeakPointer p);
246
247     /// The dynamic library handler of the package if it was loaded from a dl
248     DynamicLibraryHandler mDynamicLibraryHandler;
249     /// The pointer on the delete function of the package 
250     /// in case it was loaded from a dynamic library
251     DLDeletePackageFunction mDLDeletePackageFunction;
252
253
254     /// The name of the package
255     std::string mName;
256     /// The author of the package
257     std::string mAuthor;
258     /// The categories of the package
259     std::string mCategory;    
260     /// The description of the package
261     std::string mDescription;
262     /// The version of the package
263     std::string mVersion;
264     /// URL of the documentation of the Package (absolute path)
265     std::string mDocURL;
266     /// URL of the documentation of the Package 
267     /// (path relative to bbtk doc root)
268     std::string mDocRelativeURL;
269
270     /// The map of black boxes descriptors
271     BlackBoxMapType mBlackBoxMap;
272
273     /// The map of adaptors descriptors
274     AdaptorMapType mAdaptorMap;
275
276
277     /// The set of factories which contain the package 
278     FactorySet mFactorySet;
279
280     /// The set of released dynamically loaded packages 
281     /// to be unloaded explicitely calling 
282     /// UnLoadReleasedDynamicallyLoadedPackages
283     static std::set<Package::WeakPointer> 
284     mReleasedDynamicallyLoadedPackages;
285   };
286   // EO class Package
287   //====================================================================
288
289
290 //====================================================================
291 #if defined(_WIN32)
292   #define BBTK_PACKAGE_EXPORT __declspec( dllexport )
293 #else
294   #define BBTK_PACKAGE_EXPORT
295 #endif // defined(_WIN32) 
296 //====================================================================
297
298 #define BBTK_GET_PACKAGE_FUNCTION_NAME GetPackage
299 #define BBTK_DEL_PACKAGE_FUNCTION_NAME DeletePackage
300 #define BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME GetPackageBBTKVersion
301   
302
303
304 //====================================================================
305 #define BBTK_DECLARE_PACKAGE(NAME)                                      \
306   extern "C"                                                            \
307   {                                                                     \
308     bbtk::Package::Pointer& NAME ## GetPackagePointer();                \
309     BBTK_PACKAGE_EXPORT                                                 \
310     void BBTK_CDECL NAME ## DeletePackage ();           \
311     BBTK_PACKAGE_EXPORT bbtk::Package::Pointer                          \
312     BBTK_CDECL NAME ## GetPackage ();           \
313     BBTK_PACKAGE_EXPORT const std::string&                              \
314     BBTK_CDECL NAME ## GetPackageBBTKVersion ();        \
315   }
316 //==================================================================== 
317
318 //==================================================================== 
319 #define BBTK_IMPLEMENT_PACKAGE(NAME,AUTHOR,DESCRIPTION,VERSION)         \
320   extern "C"                                                            \
321   {                                                                     \
322     bbtk::Package::Pointer& NAME ## GetPackagePointer()                 \
323     {                                                                   \
324       static bbtk::Package::Pointer u;                                  \
325       return u;                                                         \
326     }                                                                   \
327     BBTK_PACKAGE_EXPORT                                                 \
328     void BBTK_CDECL NAME ## DeletePackage ()                            \
329     {                                                                   \
330       NAME ## GetPackagePointer().reset();                              \
331     }                                                                   \
332     BBTK_PACKAGE_EXPORT                                                 \
333     bbtk::Package::Pointer                                              \
334     BBTK_CDECL NAME ## GetPackage()             \
335     {                                                                   \
336       if (!NAME ## GetPackagePointer())                                 \
337         NAME ## GetPackagePointer() =                                   \
338           bbtk::Package::New(#NAME,                                     \
339                              AUTHOR,                                    \
340                              DESCRIPTION,                               \
341                              VERSION    \
342                              );                                         \
343       bbtk::Object::InsertInPackageList( NAME ## GetPackagePointer() ); \
344       return NAME ## GetPackagePointer();                               \
345     }                                                                   \
346     BBTK_PACKAGE_EXPORT const std::string&                              \
347     BBTK_CDECL NAME ## GetPackageBBTKVersion ()                         \
348     { return bbtk::GetVersion(); }                                      \
349     class NAME ## PackageAutodestructor                                 \
350     {                                                                   \
351     public:                                                             \
352       NAME ## PackageAutodestructor() {}                                \
353       ~NAME ## PackageAutodestructor()                                  \
354       {                                                                 \
355         if (NAME ## GetPackagePointer().use_count()>0)                  \
356           {                                                             \
357             bbtk::Package::WeakPointer p = NAME ## GetPackagePointer(); \
358             bbtk::Package::Release(p);                                  \
359           }                                                             \
360       }                                                                 \
361     };                                                                  \
362     NAME ## PackageAutodestructor NAME ## PackageAutodestructorInstance; \
363   }
364 //====================================================================  
365
366 //====================================================================
367 #define BBTK_ADD_BLACK_BOX_TO_PACKAGE(NAME,CLASS)                       \
368   bool bbDummy##NAME##CLASS = NAME ## GetPackage ()     \
369     ->RegisterBlackBox(CLASS ## Descriptor::Instance());
370   //====================================================================
371   
372   //====================================================================
373 #define BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(NAME,CLASS,TEMPLATE_PARAM) \
374   bool bbDummy##NAME##CLASS##TEMPLATE_PARAM = NAME ## GetPackage ()     \
375     ->RegisterBlackBox(CLASS ## Descriptor <TEMPLATE_PARAM>::Instance());
376   //====================================================================
377   
378   //====================================================================
379 #define BBTK_ADD_TEMPLATE2_BLACK_BOX_TO_PACKAGE(NAME,CLASS,T1,T2)       \
380   bool bbDummy##NAME##CLASS##T1##T2 = NAME ## GetPackage ()             \
381     ->RegisterBlackBox(CLASS ## Descriptor <T1,T2>::Instance()); 
382   //====================================================================
383   
384
385 }// namespace bbtk
386
387
388
389 #endif
390