]> Creatis software - bbtk.git/blob - kernel/src/bbtkPackage.h
5dccf50a719ee49f2a5ccde064d34c375b70bb64
[bbtk.git] / kernel / src / bbtkPackage.h
1 /*=========================================================================
2                                                                                 
3   Program:   bbtk
4   Module:    $RCSfile: bbtkPackage.h,v $
5   Language:  C++
6   Date:      $Date: 2008/05/21 12:50:11 $
7   Version:   $Revision: 1.9 $
8                                                                                 
9   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10   l'Image). All rights reserved. See doc/license.txt or
11   http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
12                                                                                 
13      This software is distributed WITHOUT ANY WARRANTY; without even
14      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15      PURPOSE.  See the above copyright notices for more information.
16                                                                                 
17 =========================================================================*/
18 /**
19  * \file
20  * \brief Class bbtk::Package : registers black boxes descriptors and is able to create instances of the black boxes registered.
21  */
22 /**
23  * \class bbtk::Package
24  * \brief registers black boxes descriptors and is able to create instances of the black boxes registered.
25  */
26
27 #ifndef __bbtkPackage_h__
28 #define __bbtkPackage_h__
29
30 #include "bbtkBlackBox.h"
31 #include "bbtkDynamicLibraryHandling.h"
32
33 namespace bbtk
34 {
35
36   class Factory;
37   BBTK_FORWARD_DECLARE_POINTER(Factory);
38
39   class BBTK_EXPORT Package : public Object
40   {
41     BBTK_OBJECT_INTERFACE(Package);
42     typedef Object Superclass;
43   public:
44     /// Creates a new package
45     static Pointer New(const std::string& name,
46                        const std::string& author,
47                        const std::string& description,
48                        const std::string& version,
49                        const std::string& BBTKVersion);
50     /// Creates a package from a dynamic library
51     static Pointer CreateFromDynamicLibrary(const std::string& libname,
52                                             const std::string& pkgname,
53                                             const std::string& path);
54
55     /// UnLoads the package dynamic library 
56     /// (if any and if the package is released)
57     /// If doit == false then does not do it but just 
58     /// put the package in the list of ReleasedDynamicallyLoadedPackages.
59     /// This is because we cannot close the dl from inside a 
60     /// package member method or the program crashes.
61     /// The actual dl close must be done by an external user 
62     /// calling UnLoadReleasedDynamicallyLoadedPackages
63     static void UnLoadDynamicLibrary(Package::WeakPointer p, bool doit = true);
64
65     /// UnLoads released packages that were loaded dynamically
66     /// see UnLoadDynamicLibrary and ReleaseBlackBoxDescriptor
67     static void UnLoadReleasedDynamicallyLoadedPackages();
68
69     /// "Releases" the package
70     /// Signals the package that it can free its descriptors 
71     /// if they are no more used and frees and unloads the package 
72     /// if it is no more used (released)
73     /// Note : Any non-weak pointer on the package must have been freed
74     static void Release(Package::WeakPointer p);
75     /// "Releases" a black box descriptor
76     /// Signals the package that it can free the given descriptor
77     /// if it is no more used and frees and put it the the 
78     /// ReleasedDynamicallyLoadedPackages if it is dyn loaded 
79     /// and no more used (released)
80     /// Note : Any non-weak pointer on the package must have been freed
81     static void ReleaseBlackBoxDescriptor(Package::WeakPointer p,
82                                           BlackBoxDescriptor::WeakPointer d);
83     
84     
85     typedef Package::Pointer (*DLGetPackageFunction)();
86     typedef void (*DLDeletePackageFunction)();
87     typedef const std::string& (*DLGetPackageBBTKVersionFunction)();
88
89     /// Opens a dynamic library which contains a bbtk package
90     /// Returns the handler 
91     /// Load the package management symbols from the lib
92     /// returns false if a problem occured hence can be used 
93     /// to test that a dyn lib is a valid bbtk package lib
94     /// NB : The BBTK version exported from the library 
95     ///      is tested against the current bbtk version
96     static DynamicLibraryHandler OpenDynamicLibrary
97     ( const std::string& dynamic_library_path,
98       const std::string& package_name,
99       DLGetPackageFunction&,
100       DLDeletePackageFunction&);
101
102  
103     /// Returns the name of the package
104     const std::string& GetName() const { return mName; }
105
106     /// Returns the author of the package
107     const std::string& GetAuthor() const { return mAuthor; }
108
109     /// Returns the category of the package
110     const std::string& GetCategory() const { return mCategory; }
111
112     /// Returns the description of the package
113     const std::string& GetDescription() const { return mDescription; }
114
115     /// Returns the version of the package
116     const std::string& GetVersion() const { return mVersion; }
117
118     bool ContainsBlackBox(const std::string& boxname) const;
119
120  
121     BlackBox::Pointer NewBlackBox(const std::string& type,
122                              const std::string& name) const;
123   
124     BlackBox::Pointer NewAdaptor(const DataInfo& typein,
125                          const DataInfo& typeout,
126                          const std::string& name) const;
127     
128     BlackBox::Pointer NewWidgetAdaptor(const DataInfo& typein,
129                               const DataInfo& typeout,
130                               const std::string& name) const;
131     bool FindAdaptor(const DataInfo& typein,
132                            const DataInfo& typeout,
133                            std::string& adaptor) const;
134     bool FindWidgetAdaptor(const DataInfo& typein,
135                            const DataInfo& typeout,
136                            std::string& adaptor) const;
137
138     bool RegisterBlackBox(BlackBoxDescriptor::Pointer); 
139
140     void PrintBlackBoxes(bool description = false, 
141                          bool adaptors = false) const;
142     void PrintAdaptors(bool description = false) const;
143     void HelpBlackBox(const std::string& name, bool full=true) const;
144     
145     void CreateHtmlPage(const std::string& filename,
146                         const std::string& caller = "?",
147                         const std::string& source = "?",
148                         const std::string& custom_header = "",
149                         const std::string& custom_title = "",
150                         int detail = 1, 
151                         int level = 0,
152                         bool relative_link = false ) const;
153
154     void  SetDocURL(std::string url){ mDocURL=url; }
155     const std::string& GetDocURL() const { return mDocURL; }
156     
157     void  SetDocRelativeURL(std::string url){ mDocRelativeURL=url; }
158     const std::string& GetDocRelativeURL() const { return mDocRelativeURL; }
159
160
161     unsigned int GetNumberOfBlackBoxes() const { return mBlackBoxMap.size(); }
162     
163     /// Changes the name of a black box type
164     void ChangeBlackBoxName( const std::string& oldname, 
165                              const std::string& newname );
166     /// The type of map of descriptors
167     typedef std::map< std::string, BlackBoxDescriptor::Pointer> 
168     BlackBoxMapType;
169     const BlackBoxMapType& GetBlackBoxMap() const { return mBlackBoxMap; }
170     BlackBoxMapType& GetBlackBoxMap() { return mBlackBoxMap; }
171
172     /// The type of key in the map of adaptor descriptors
173     class AdaptorKey 
174     {
175     public:
176       AdaptorKey( const DataInfo& typein, const DataInfo& typeout, 
177                   BlackBoxDescriptor::Kind kind ) 
178         : mTypeIn(typein), mTypeOut(typeout), mKind(kind) {}
179       
180       bool operator< ( const AdaptorKey& k ) const
181       {
182         return ( ( mKind < k.mKind ) ||
183                  ( ( mKind == k.mKind ) &&
184                    ( ( mTypeIn < k.mTypeIn ) ||
185                      ( ( mTypeIn == k.mTypeIn ) && 
186                        ( mTypeOut < k.mTypeOut ) ) ) ) );
187       }
188       
189       bool operator== ( const AdaptorKey& k ) const
190       {
191         return ( ( mKind == k.mKind ) && 
192                  ( mTypeIn == k.mTypeIn ) && 
193                  ( mTypeOut == k.mTypeOut ) );
194       }
195       DataInfo mTypeIn;
196       DataInfo mTypeOut; 
197       BlackBoxDescriptor::Kind mKind;
198     };
199     
200     /// The type of map of adaptor descriptors
201     typedef std::map< AdaptorKey, BlackBoxDescriptor::WeakPointer> AdaptorMapType;
202
203  
204    const AdaptorMapType& GetAdaptorMap() const { return mAdaptorMap; }
205
206     
207     // Factories management
208     /// Adds the factory to the set of factories which use the package
209     void AddFactory(FactoryPointer f) { mFactorySet.insert(f); }
210     /// Removes the factory from the set of factories which use the package
211     void RemoveFactory(FactoryPointer f) { mFactorySet.erase(f); }
212
213     
214     typedef std::set<FactoryWeakPointer> FactorySet;
215     /// Gets the set of factories which use the package
216     FactorySet& GetFactorySet() { return mFactorySet; }
217     /// Gets the set of factories which use the package (const)
218     const FactorySet& GetFactorySet() const { return mFactorySet; }
219     
220     void CheckBoxes() const;
221
222   private:
223     /// Default ctor is private : use the static New method
224     //    Package() {}
225     /// A Package cannot be copy constructed
226     //    Package(const Package&) {}
227     /// Ctor is private : use the static New method
228     Package(const std::string& name,
229             const std::string& author,
230             const std::string& description,
231             const std::string& version,
232             const std::string& BBTKVersion);
233     /// Does unload a package (no test)
234     static void UnLoad(Package::WeakPointer p);
235
236     /// The dynamic library handler of the package if it was loaded from a dl
237     DynamicLibraryHandler mDynamicLibraryHandler;
238     /// The pointer on the delete function of the package 
239     /// in case it was loaded from a dynamic library
240     DLDeletePackageFunction mDLDeletePackageFunction;
241
242
243     /// The name of the package
244     std::string mName;
245     /// The author of the package
246     std::string mAuthor;
247     /// The categories of the package
248     std::string mCategory;    
249     /// The description of the package
250     std::string mDescription;
251     /// The version of the package
252     std::string mVersion;
253     /// URL of the documentation of the Package (absolute path)
254     std::string mDocURL;
255     /// URL of the documentation of the Package 
256     /// (path relative to bbtk doc root)
257     std::string mDocRelativeURL;
258
259     /// The map of black boxes descriptors
260     BlackBoxMapType mBlackBoxMap;
261
262     /// The map of adaptors descriptors
263     AdaptorMapType mAdaptorMap;
264
265
266     /// The set of factories which contain the package 
267     FactorySet mFactorySet;
268
269     /// The set of released dynamically loaded packages 
270     /// to be unloaded explicitely calling 
271     /// UnLoadReleasedDynamicallyLoadedPackages
272     static std::set<Package::WeakPointer> 
273     mReleasedDynamicallyLoadedPackages;
274   };
275   // EO class Package
276   //====================================================================
277
278
279 //====================================================================
280 #if defined(_WIN32)
281   #define BBTK_PACKAGE_EXPORT __declspec( dllexport )
282 #else
283   #define BBTK_PACKAGE_EXPORT
284 #endif // defined(_WIN32) 
285 //====================================================================
286
287 #define BBTK_GET_PACKAGE_FUNCTION_NAME GetPackage
288 #define BBTK_DEL_PACKAGE_FUNCTION_NAME DeletePackage
289 #define BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME GetPackageBBTKVersion
290   
291
292
293 //====================================================================
294 #define BBTK_DECLARE_PACKAGE(NAME)                                      \
295   extern "C"                                                            \
296   {                                                                     \
297     bbtk::Package::Pointer& NAME ## GetPackagePointer();                \
298     BBTK_PACKAGE_EXPORT                                                 \
299     void BBTK_CDECL NAME ## DeletePackage ();           \
300     BBTK_PACKAGE_EXPORT bbtk::Package::Pointer                          \
301     BBTK_CDECL NAME ## GetPackage ();           \
302     BBTK_PACKAGE_EXPORT const std::string&                              \
303     BBTK_CDECL NAME ## GetPackageBBTKVersion ();        \
304   }
305 //==================================================================== 
306
307 //==================================================================== 
308 #define BBTK_IMPLEMENT_PACKAGE(NAME,AUTHOR,DESCRIPTION,VERSION)         \
309   extern "C"                                                            \
310   {                                                                     \
311     bbtk::Package::Pointer& NAME ## GetPackagePointer()                 \
312     {                                                                   \
313       static bbtk::Package::Pointer u;                                  \
314       return u;                                                         \
315     }                                                                   \
316     BBTK_PACKAGE_EXPORT                                                 \
317     void BBTK_CDECL NAME ## DeletePackage ()                            \
318     {                                                                   \
319       NAME ## GetPackagePointer().reset();                              \
320     }                                                                   \
321     BBTK_PACKAGE_EXPORT                                                 \
322     bbtk::Package::Pointer                                              \
323     BBTK_CDECL NAME ## GetPackage()             \
324     {                                                                   \
325       if (!NAME ## GetPackagePointer())                                 \
326         NAME ## GetPackagePointer() =                                   \
327           bbtk::Package::New(#NAME,                                     \
328                              AUTHOR,                                    \
329                              DESCRIPTION,                               \
330                              VERSION,                                   \
331                              BBTK_STRINGIFY_SYMBOL(BBTK_VERSION)        \
332                              );                                         \
333       return NAME ## GetPackagePointer();                               \
334     }                                                                   \
335     BBTK_PACKAGE_EXPORT const std::string&                              \
336     BBTK_CDECL NAME ## GetPackageBBTKVersion ()                         \
337     { return bbtk::GetVersion(); }                                      \
338     class NAME ## PackageAutodestructor                                 \
339     {                                                                   \
340     public:                                                             \
341       NAME ## PackageAutodestructor() {}                                \
342       ~NAME ## PackageAutodestructor()                                  \
343       {                                                                 \
344         if (NAME ## GetPackagePointer().use_count()>0)                  \
345           {                                                             \
346             bbtk::Package::WeakPointer p = NAME ## GetPackagePointer(); \
347             bbtk::Package::Release(p);                                  \
348           }                                                             \
349       }                                                                 \
350     };                                                                  \
351     NAME ## PackageAutodestructor NAME ## PackageAutodestructorInstance; \
352   }
353 //====================================================================  
354
355 //====================================================================
356 #define BBTK_ADD_BLACK_BOX_TO_PACKAGE(NAME,CLASS)                       \
357   bool bbDummy##NAME##CLASS = NAME ## GetPackage ()     \
358     ->RegisterBlackBox(CLASS ## Descriptor::Instance());
359   //====================================================================
360   
361   //====================================================================
362 #define BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(NAME,CLASS,TEMPLATE_PARAM) \
363   bool bbDummy##NAME##CLASS##TEMPLATE_PARAM = NAME ## GetPackage ()     \
364     ->RegisterBlackBox(CLASS ## Descriptor <TEMPLATE_PARAM>::Instance());
365   //====================================================================
366   
367   //====================================================================
368 #define BBTK_ADD_TEMPLATE2_BLACK_BOX_TO_PACKAGE(NAME,CLASS,T1,T2)       \
369   bool bbDummy##NAME##CLASS##T1##T2 = NAME ## GetPackage ()             \
370     ->RegisterBlackBox(CLASS ## Descriptor <T1,T2>::Instance()); 
371   //====================================================================
372   
373
374 }// namespace bbtk
375
376
377
378 #endif
379