+/*
+ # ---------------------------------------------------------------------
+ #
+ # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
+ # pour la SantÈ)
+ # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
+ # Previous Authors : Laurent Guigues, Jean-Pierre Roux
+ # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
+ #
+ # This software is governed by the CeCILL-B license under French law and
+ # abiding by the rules of distribution of free software. You can use,
+ # modify and/ or redistribute the software under the terms of the CeCILL-B
+ # license as circulated by CEA, CNRS and INRIA at the following URL
+ # http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+ # or in the file LICENSE.txt.
+ #
+ # As a counterpart to the access to the source code and rights to copy,
+ # modify and redistribute granted by the license, users are provided only
+ # with a limited warranty and the software's author, the holder of the
+ # economic rights, and the successive licensors have only limited
+ # liability.
+ #
+ # The fact that you are presently reading this means that you have had
+ # knowledge of the CeCILL-B license and that you accept its terms.
+ # ------------------------------------------------------------------------ */
+
+
/*=========================================================================
-
Program: bbtk
Module: $RCSfile: bbtkPackage.h,v $
Language: C++
- Date: $Date: 2008/03/07 08:40:14 $
- Version: $Revision: 1.5 $
-
- Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
- l'Image). All rights reserved. See doc/license.txt or
- http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the above copyright notices for more information.
-
+ Date: $Date: 2012/11/16 08:49:01 $
+ Version: $Revision: 1.18 $
=========================================================================*/
+
+
+
/**
* \file
* \brief Class bbtk::Package : registers black boxes descriptors and is able to create instances of the black boxes registered.
#define __bbtkPackage_h__
#include "bbtkBlackBox.h"
+#include "bbtkDynamicLibraryHandling.h"
+#include "bbtkUtilities.h"
+#include <vector>
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);
+ /// Creates a package from a dynamic library
+ static Pointer CreateFromDynamicLibrary(const std::string& libname,
+ const std::string& pkgname,
+ const std::string& path);
+
+ void GetBoxesInside(NodeTreeC& tree, int cont);
+ /// NOTE : All the static methods below for package destruction
+ /// are not member because they can cause the package death
+ /// and thus close the dynamic library from which it has been loaded.
+ /// If the dynamic lib which provides a function is closed while
+ /// in the function: imagine the crash !
+ /// The principal method is Release
+
+ /// 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
+ /// then 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);
+
+
+ /// Registers the BlackBoxDescriptor in the Package
+ bool Register(BlackBoxDescriptor::Pointer);
+
+ /// "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; }
/// 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; }
+ /// Returns true iff the package contains a BlackBoxDescriptor
+ /// with the name provided
+ bool ContainsDescriptor(const std::string& name) const;
- bool ContainsBlackBox(const std::string& boxname) const;
-
-
- BlackBox* NewBlackBox(const std::string& type,
+ /// Creates a new BlackBox of given type with name name
+ BlackBox::Pointer NewBlackBox(const std::string& type,
const std::string& name) const;
-
- BlackBox* NewAdaptor(TypeInfo typein,
- TypeInfo typeout,
- const std::string& name) const;
-
- bool RegisterBlackBox(BlackBoxDescriptor*);
- void UnRegisterBlackBox(const std::string& name);
+
+ /// Creates a new adaptor BlackBox for the given input and output types
+ /// with name name
+ BlackBox::Pointer NewAdaptor(const DataInfo& typein,
+ const DataInfo& typeout,
+ const std::string& name) const;
+
+ /// Creates a new widget adaptor BlackBox
+ /// for the given input and output types
+ /// with name name
+ BlackBox::Pointer NewWidgetAdaptor(const DataInfo& typein,
+ const DataInfo& typeout,
+ const std::string& name) const;
+ bool FindAdaptor(const DataInfo& typein,
+ const DataInfo& typeout,
+ std::string& adaptor) const;
+ bool FindWidgetAdaptor(const DataInfo& typein,
+ const DataInfo& typeout,
+ std::string& adaptor) const;
+
+
+ /// Displays the list of black box descriptors of the package
+ void PrintHelpListDescriptors(bool description = false,
+ bool adaptors = false) const;
+ /// Displays the list of adaptors of the package
+ void PrintHelpListAdaptors(bool description = false) const;
+ /// Prints help on a particular Descriptor
+ void PrintHelpDescriptor(const std::string& name, bool full=true) const;
+
- // bool RegisterAdaptor(BlackBoxDescriptor*);
- void PrintBlackBoxes(bool description = false,
- bool adaptors = false) const;
- void PrintAdaptors(bool description = false) const;
- void HelpBlackBox(const std::string& name, bool full=true) const;
-
void CreateHtmlPage(const std::string& filename,
const std::string& caller = "?",
const std::string& source = "?",
const std::string& GetDocRelativeURL() const { return mDocRelativeURL; }
- unsigned int GetNumberOfBlackBoxes() const { return mBlackBoxMap.size(); }
+ unsigned int GetNumberOfDescriptors() const { return mDescriptorMap.size(); }
- /// Changes the name of a black box type
- void ChangeBlackBoxName( const std::string& oldname,
- const std::string& newname );
+ /// Changes the name of a descriptor
+ void ChangeDescriptorName( const std::string& oldname,
+ const std::string& newname );
/// The type of map of descriptors
- typedef std::map< std::string, BlackBoxDescriptor*> BlackBoxMapType;
- const BlackBoxMapType& GetBlackBoxMap() const { return mBlackBoxMap; }
- BlackBoxMapType& GetBlackBoxMap() { return mBlackBoxMap; }
+ typedef std::map< std::string, BlackBoxDescriptor::Pointer>
+ DescriptorMapType;
+ const DescriptorMapType& GetDescriptorMap() const { return mDescriptorMap; }
+ DescriptorMapType& GetDescriptorMap() { return mDescriptorMap; }
+
+ /// The type of key in the map of adaptor descriptors
+ class AdaptorKey
+ {
+ public:
+ AdaptorKey( const DataInfo& typein, const DataInfo& typeout,
+ BlackBoxDescriptor::Kind kind )
+ : mTypeIn(typein), mTypeOut(typeout), mKind(kind) {}
+
+ bool operator< ( const AdaptorKey& k ) const
+ {
+ return ( ( mKind < k.mKind ) ||
+ ( ( mKind == k.mKind ) &&
+ ( ( mTypeIn < k.mTypeIn ) ||
+ ( ( mTypeIn == k.mTypeIn ) &&
+ ( mTypeOut < k.mTypeOut ) ) ) ) );
+ }
+
+ bool operator== ( const AdaptorKey& k ) const
+ {
+ return ( ( mKind == k.mKind ) &&
+ ( mTypeIn == k.mTypeIn ) &&
+ ( mTypeOut == k.mTypeOut ) );
+ }
+ DataInfo mTypeIn;
+ DataInfo mTypeOut;
+ BlackBoxDescriptor::Kind mKind;
+ };
+
+ /// The type of map of adaptor descriptors
+ 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 Check() const;
+ bool ifBoxExist( std::string boxType );
+
+
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);
+ /// 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;
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
/// (path relative to bbtk doc root)
std::string mDocRelativeURL;
-
/// The map of black boxes descriptors
- BlackBoxMapType mBlackBoxMap;
-
- /// The type of key in the map of adaptor descriptors
- class AdaptorKey
- {
- public:
- AdaptorKey( TypeInfo typein, TypeInfo typeout)
- : mTypeIn(typein.name()), mTypeOut(typeout.name()) {}
-
- bool operator< ( const AdaptorKey& k ) const
- {
- // return ( ( mTypeIn.before(k.mTypeIn) ) ||
- // ( ( mTypeIn == k.mTypeIn ) &&
- // ( mTypeOut.before(k.mTypeOut) ) ) );
- return ( ( mTypeIn < k.mTypeIn ) ||
- ( ( mTypeIn == k.mTypeIn ) &&
- ( mTypeOut < k.mTypeOut ) ) );
- }
-
- private:
- // TypeInfo mTypeIn;
- // TypeInfo mTypeOut;
- std::string mTypeIn;
- std::string mTypeOut;
- };
-
- /// The type of map of adaptor descriptors
- typedef std::map< AdaptorKey, BlackBoxDescriptor*> AdaptorMapType;
+ DescriptorMapType mDescriptorMap;
/// 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
//====================================================================
#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 (); \
}
//====================================================================
#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) \
- ); \
+ if (!NAME ## GetPackagePointer()) { \
+ NAME ## GetPackagePointer() = \
+ bbtk::Package::New(#NAME, \
+ AUTHOR, \
+ DESCRIPTION, \
+ VERSION \
+ ); \
+ bbtk::Object::InsertInPackageList( NAME ## GetPackagePointer() ); \
+ } \
return NAME ## GetPackagePointer(); \
} \
+ BBTK_PACKAGE_EXPORT const std::string& \
+ BBTK_CDECL NAME ## GetPackageBBTKVersion () \
+ { static const std::string v(BBTK_STRINGIFY_SYMBOL(BBTK_VERSION)); return v; } \
+ class NAME ## PackageAutodestructor \
+ { \
+ public: \
+ NAME ## PackageAutodestructor() {} \
+ ~NAME ## PackageAutodestructor() \
+ { \
+ if (NAME ## GetPackagePointer().use_count()>0) \
+ { \
+ bbtk::Package::WeakPointer p = NAME ## GetPackagePointer(); \
+ bbtk::Package::Release(p); \
+ } \
+ } \
+ }; \
+ NAME ## PackageAutodestructor NAME ## PackageAutodestructorInstance; \
}
//====================================================================
//====================================================================
#define BBTK_ADD_BLACK_BOX_TO_PACKAGE(NAME,CLASS) \
- bool bbDummy##NAME##CLASS = NAME ## GetPackage()->RegisterBlackBox(CLASS::bbDescriptor());
+ bool bbDummy##NAME##CLASS = NAME ## GetPackage () \
+ ->Register(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 () \
+ ->Register(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 () \
+ ->Register(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