]> Creatis software - bbtk.git/blobdiff - kernel/src/bbtkPackage.h
=== MAJOR RELEASE ====
[bbtk.git] / kernel / src / bbtkPackage.h
index 4c0b70534cf890d37f22f4f0a43c7b73bcfc3372..089dbee65498918ab3c7c829d20a754d994c6b84 100644 (file)
@@ -3,8 +3,8 @@
   Program:   bbtk
   Module:    $RCSfile: bbtkPackage.h,v $
   Language:  C++
-  Date:      $Date: 2008/04/09 11:16:57 $
-  Version:   $Revision: 1.7 $
+  Date:      $Date: 2008/04/18 12:59:15 $
+  Version:   $Revision: 1.8 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See doc/license.txt or
 #define __bbtkPackage_h__
 
 #include "bbtkBlackBox.h"
+#include "bbtkDynamicLibraryHandling.h"
 
 namespace bbtk
 {
 
-  class BBTK_EXPORT Package
+  class Factory;
+  BBTK_FORWARD_DECLARE_POINTER(Factory);
+
+  class BBTK_EXPORT Package : public Object
   {
+    BBTK_OBJECT_INTERFACE(Package);
+    typedef Object Superclass;
   public:
-    Package(const std::string& name,
-           const std::string& author,
-           const std::string& description,
-           const std::string& version,
-           const std::string& BBTKVersion);
-    ~Package();
+    /// Creates a new package
+    static Pointer New(const std::string& name,
+                      const std::string& author,
+                      const std::string& description,
+                      const std::string& version,
+                      const std::string& BBTKVersion);
+    /// Creates a package from a dynamic library
+    static Pointer CreateFromDynamicLibrary(const std::string& libname,
+                                           const std::string& pkgname,
+                                           const std::string& path);
+
+    /// UnLoads the package dynamic library 
+    /// (if any and if the package is released)
+    /// If doit == false then does not do it but just 
+    /// put the package in the list of ReleasedDynamicallyLoadedPackages.
+    /// This is because we cannot close the dl from inside a 
+    /// package member method or the program crashes.
+    /// The actual dl close must be done by an external user 
+    /// calling UnLoadReleasedDynamicallyLoadedPackages
+    static void UnLoadDynamicLibrary(Package::WeakPointer p, bool doit = true);
+
+    /// UnLoads released packages that were loaded dynamically
+    /// see UnLoadDynamicLibrary and ReleaseBlackBoxDescriptor
+    static void UnLoadReleasedDynamicallyLoadedPackages();
+
+    /// "Releases" the package
+    /// Signals the package that it can free its descriptors 
+    /// if they are no more used and frees and unloads the package 
+    /// if it is no more used (released)
+    /// Note : Any non-weak pointer on the package must have been freed
+    static void Release(Package::WeakPointer p);
+    /// "Releases" a black box descriptor
+    /// Signals the package that it can free the given descriptor
+    /// if it is no more used and frees and put it the the 
+    /// ReleasedDynamicallyLoadedPackages if it is dyn loaded 
+    /// and no more used (released)
+    /// Note : Any non-weak pointer on the package must have been freed
+    static void ReleaseBlackBoxDescriptor(Package::WeakPointer p,
+                                         BlackBoxDescriptor::WeakPointer d);
+    
+    
+    typedef Package::Pointer (*DLGetPackageFunction)();
+    typedef void (*DLDeletePackageFunction)();
+    typedef const std::string& (*DLGetPackageBBTKVersionFunction)();
+
+    /// Opens a dynamic library which contains a bbtk package
+    /// Returns the handler 
+    /// Load the package management symbols from the lib
+    /// returns false if a problem occured hence can be used 
+    /// to test that a dyn lib is a valid bbtk package lib
+    /// NB : The BBTK version exported from the library 
+    ///      is tested against the current bbtk version
+    static DynamicLibraryHandler OpenDynamicLibrary
+    ( const std::string& dynamic_library_path,
+      const std::string& package_name,
+      DLGetPackageFunction&,
+      DLDeletePackageFunction&);
+
     /// Returns the name of the package
     const std::string& GetName() const { return mName; }
 
@@ -56,20 +115,17 @@ namespace bbtk
     /// Returns the version of the package
     const std::string& GetVersion() const { return mVersion; }
 
-    /// Returns the version of bbtk used to build the package
-    const std::string& GetBBTKVersion() const { return mBBTKVersion; }
-
     bool ContainsBlackBox(const std::string& boxname) const;
 
  
-    BlackBox* NewBlackBox(const std::string& type,
+    BlackBox::Pointer NewBlackBox(const std::string& type,
                             const std::string& name) const;
   
-    BlackBox* NewAdaptor(const DataInfo& typein,
+    BlackBox::Pointer NewAdaptor(const DataInfo& typein,
                         const DataInfo& typeout,
                         const std::string& name) const;
     
-   BlackBox* NewWidgetAdaptor(const DataInfo& typein,
+    BlackBox::Pointer NewWidgetAdaptor(const DataInfo& typein,
                              const DataInfo& typeout,
                              const std::string& name) const;
     bool FindAdaptor(const DataInfo& typein,
@@ -79,10 +135,7 @@ namespace bbtk
                           const DataInfo& typeout,
                           std::string& adaptor) const;
 
-    bool RegisterBlackBox(BlackBoxDescriptor*); 
-    void UnRegisterBlackBox(const std::string& name); 
-
-    //   bool RegisterAdaptor(BlackBoxDescriptor*); 
+    bool RegisterBlackBox(BlackBoxDescriptor::Pointer); 
 
     void PrintBlackBoxes(bool description = false, 
                         bool adaptors = false) const;
@@ -111,7 +164,8 @@ namespace bbtk
     void ChangeBlackBoxName( const std::string& oldname, 
                             const std::string& newname );
     /// The type of map of descriptors
-    typedef std::map< std::string, BlackBoxDescriptor*> BlackBoxMapType;
+    typedef std::map< std::string, BlackBoxDescriptor::Pointer> 
+    BlackBoxMapType;
     const BlackBoxMapType& GetBlackBoxMap() const { return mBlackBoxMap; }
     BlackBoxMapType& GetBlackBoxMap() { return mBlackBoxMap; }
 
@@ -144,26 +198,47 @@ namespace bbtk
     };
     
     /// The type of map of adaptor descriptors
-    typedef std::map< AdaptorKey, BlackBoxDescriptor*> AdaptorMapType;
+    typedef std::map< AdaptorKey, BlackBoxDescriptor::WeakPointer> AdaptorMapType;
 
  
    const AdaptorMapType& GetAdaptorMap() const { return mAdaptorMap; }
 
-
+    
     // Factories management
     /// Adds the factory to the set of factories which use the package
-    void AddFactory(Factory* f) { mFactorySet.insert(f); }
+    void AddFactory(FactoryPointer f) { mFactorySet.insert(f); }
     /// Removes the factory from the set of factories which use the package
-    void RemoveFactory(Factory* f) { mFactorySet.erase(f); }
+    void RemoveFactory(FactoryPointer f) { mFactorySet.erase(f); }
 
+    
+    typedef std::set<FactoryWeakPointer> FactorySet;
     /// Gets the set of factories which use the package
-    std::set<Factory*>& GetFactorySet() { return mFactorySet; }
+    FactorySet& GetFactorySet() { return mFactorySet; }
     /// Gets the set of factories which use the package (const)
-    const std::set<Factory*>& GetFactorySet() const { return mFactorySet; }
+    const FactorySet& GetFactorySet() const { return mFactorySet; }
     
     void CheckBoxes() const;
 
   private:
+    /// Default ctor is private : use the static New method
+    //    Package() {}
+    /// A Package cannot be copy constructed
+    //    Package(const Package&) {}
+    /// Ctor is private : use the static New method
+    Package(const std::string& name,
+           const std::string& author,
+           const std::string& description,
+           const std::string& version,
+           const std::string& BBTKVersion);
+    /// Does unload a package (no test)
+    static void UnLoad(Package::WeakPointer p);
+
+    /// The dynamic library handler of the package if it was loaded from a dl
+    DynamicLibraryHandler mDynamicLibraryHandler;
+    /// The pointer on the delete function of the package 
+    /// in case it was loaded from a dynamic library
+    DLDeletePackageFunction mDLDeletePackageFunction;
+
 
     /// The name of the package
     std::string mName;
@@ -175,8 +250,6 @@ namespace bbtk
     std::string mDescription;
     /// The version of the package
     std::string mVersion;
-    /// The version of the library bbtk used to build the package
-    std::string mBBTKVersion;
     /// URL of the documentation of the Package (absolute path)
     std::string mDocURL;
     /// URL of the documentation of the Package 
@@ -186,18 +259,18 @@ namespace bbtk
     /// The map of black boxes descriptors
     BlackBoxMapType mBlackBoxMap;
 
-
-  public:
-
-
-  private:
     /// The map of adaptors descriptors
     AdaptorMapType mAdaptorMap;
 
 
     /// The set of factories which contain the package 
-    std::set<Factory*> mFactorySet;
-    
+    FactorySet mFactorySet;
+
+    /// The set of released dynamically loaded packages 
+    /// to be unloaded explicitely calling 
+    /// UnLoadReleasedDynamicallyLoadedPackages
+    static std::set<Package::WeakPointer> 
+    mReleasedDynamicallyLoadedPackages;
   };
   // EO class Package
   //====================================================================
@@ -211,13 +284,23 @@ namespace bbtk
 #endif // defined(_WIN32) 
 //====================================================================
 
+#define BBTK_GET_PACKAGE_FUNCTION_NAME GetPackage
+#define BBTK_DEL_PACKAGE_FUNCTION_NAME DeletePackage
+#define BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME GetPackageBBTKVersion
+  
+
+
 //====================================================================
 #define BBTK_DECLARE_PACKAGE(NAME)                                     \
   extern "C"                                                           \
   {                                                                    \
-    bbtk::Package*& NAME ## GetPackagePointer();                       \
-    BBTK_PACKAGE_EXPORT void BBTK_CDECL NAME ## DeletePackage();       \
-    BBTK_PACKAGE_EXPORT bbtk::Package* BBTK_CDECL NAME ## GetPackage();        \
+    bbtk::Package::Pointer& NAME ## GetPackagePointer();               \
+    BBTK_PACKAGE_EXPORT                                                        \
+    void BBTK_CDECL NAME ## DeletePackage ();          \
+    BBTK_PACKAGE_EXPORT        bbtk::Package::Pointer                          \
+    BBTK_CDECL NAME ## GetPackage ();          \
+    BBTK_PACKAGE_EXPORT const std::string&                             \
+    BBTK_CDECL NAME ## GetPackageBBTKVersion ();       \
   }
 //==================================================================== 
 
@@ -225,64 +308,54 @@ namespace bbtk
 #define BBTK_IMPLEMENT_PACKAGE(NAME,AUTHOR,DESCRIPTION,VERSION)                \
   extern "C"                                                           \
   {                                                                    \
-    bbtk::Package*& NAME ## GetPackagePointer()                                \
+    bbtk::Package::Pointer& NAME ## GetPackagePointer()                        \
     {                                                                  \
-      static bbtk::Package* u = 0;                                     \
+      static bbtk::Package::Pointer u;                                 \
       return u;                                                                \
     }                                                                  \
-    BBTK_PACKAGE_EXPORT void BBTK_CDECL NAME ## DeletePackage()                \
+    BBTK_PACKAGE_EXPORT                                                        \
+    void BBTK_CDECL NAME ## DeletePackage ()                           \
     {                                                                  \
-      if (NAME ## GetPackagePointer())                                 \
-       delete NAME ## GetPackagePointer();                             \
-      NAME ## GetPackagePointer() = 0;                                 \
+      NAME ## GetPackagePointer().reset();                             \
     }                                                                  \
-    BBTK_PACKAGE_EXPORT bbtk::Package* BBTK_CDECL NAME ## GetPackage() \
+    BBTK_PACKAGE_EXPORT                                                        \
+    bbtk::Package::Pointer                                             \
+    BBTK_CDECL NAME ## GetPackage()            \
     {                                                                  \
       if (!NAME ## GetPackagePointer())                                        \
        NAME ## GetPackagePointer() =                                   \
-         new bbtk::Package(#NAME,                                      \
-                           AUTHOR,     \
-                           DESCRIPTION, \
-                           VERSION,    \
-                           BBTK_STRINGIFY_SYMBOL(BBTK_VERSION)         \
-                           );                                          \
+         bbtk::Package::New(#NAME,                                     \
+                            AUTHOR,                                    \
+                            DESCRIPTION,                               \
+                            VERSION,                                   \
+                            BBTK_STRINGIFY_SYMBOL(BBTK_VERSION)        \
+                            );                                         \
       return NAME ## GetPackagePointer();                              \
     }                                                                  \
+    BBTK_PACKAGE_EXPORT const std::string&                             \
+    BBTK_CDECL NAME ## GetPackageBBTKVersion ()        \
+    { return bbtk::GetVersion(); }                                     \
   }
 //====================================================================  
 
 //====================================================================
 #define BBTK_ADD_BLACK_BOX_TO_PACKAGE(NAME,CLASS)                      \
-  bool bbDummy##NAME##CLASS = NAME ## GetPackage()->RegisterBlackBox(CLASS::bbDescriptor());
+  bool bbDummy##NAME##CLASS = NAME ## GetPackage ()    \
+    ->RegisterBlackBox(CLASS ## Descriptor::Instance());
   //====================================================================
   
-//====================================================================
+  //====================================================================
 #define BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(NAME,CLASS,TEMPLATE_PARAM) \
-  bool bbDummy##NAME##CLASS##TEMPLATE_PARAM = NAME ## GetPackage()->RegisterBlackBox(CLASS<TEMPLATE_PARAM>::bbDescriptor());
+  bool bbDummy##NAME##CLASS##TEMPLATE_PARAM = NAME ## GetPackage ()    \
+    ->RegisterBlackBox(CLASS ## Descriptor <TEMPLATE_PARAM>::Instance());
+  //====================================================================
+  
   //====================================================================
-
-//====================================================================
 #define BBTK_ADD_TEMPLATE2_BLACK_BOX_TO_PACKAGE(NAME,CLASS,T1,T2)      \
-  bool bbDummy##NAME##CLASS##T1##T2 = NAME ## GetPackage()->RegisterBlackBox(CLASS<T1,T2>::bbDescriptor()); 
+  bool bbDummy##NAME##CLASS##T1##T2 = NAME ## GetPackage ()            \
+    ->RegisterBlackBox(CLASS ## Descriptor <T1,T2>::Instance()); 
   //====================================================================
   
-//====================================================================
-//#define BBTK_ADD_ADAPTOR_TO_PACKAGE(NAME,CLASS)                      \
-//  bool bbDummy##NAME##CLASS = NAME ## GetPackage()->RegisterBlackBox(CLASS::bbDescriptor()); \
-//  bool bbDummyAdaptor##NAME##CLASS = NAME ## GetPackage()->RegisterAdaptor(CLASS::bbDescriptor());
-//====================================================================
-
-//====================================================================
-//#define BBTK_ADD_TEMPLATE_ADAPTOR_TO_PACKAGE(NAME,CLASS,TEMPLATE_PARAM) \
-//  bool bbDummy##NAME##CLASS##TEMPLATE_PARAM = NAME ## GetPackage()->RegisterBlackBox(CLASS<TEMPLATE_PARAM>::bbDescriptor()); \
-//  bool bbDummyAdaptor##NAME##CLASS##TEMPLATE_PARAM = NAME ## GetPackage()->RegisterAdaptor(CLASS<TEMPLATE_PARAM>::bbDescriptor());
-//====================================================================
-
-//====================================================================
-//#define BBTK_ADD_TEMPLATE2_ADAPTOR_TO_PACKAGE(NAME,CLASS,T1,T2)      \
-//  bool bbDummy##NAME##CLASS##T1##T2 = NAME ## GetPackage()->RegisterBlackBox(CLASS<T1,T2>::bbDescriptor()); \
-//    bool bbDummyAdaptor##NAME##CLASS##T1##T2 = NAME ## GetPackage()->RegisterAdaptor(CLASS<T1,T2>::bbDescriptor());
-  //====================================================================
 
 }// namespace bbtk