Program: bbtk
Module: $RCSfile: bbtkPackage.cxx,v $
Language: C++
- Date: $Date: 2008/01/22 15:02:00 $
- Version: $Revision: 1.1 $
+ Date: $Date: 2008/05/06 13:45:12 $
+ Version: $Revision: 1.17 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See doc/license.txt or
namespace bbtk
{
+
+
+
+ //==========================================================================
+ /// Creates a new package
+ Package::Pointer Package::New(const std::string& name,
+ const std::string& author,
+ const std::string& description,
+ const std::string& version,
+ const std::string& BBTKVersion)
+ {
+ bbtkDebugMessage("object",1,"##> Package::New('"<<name<<"',...)"
+ <<bbtkendl);
+ Package::Pointer p = MakePointer(new Package(name,
+ author,
+ description,
+ version,
+ BBTKVersion));
+ bbtkDebugMessage("object",2,"<## Package::New('"<<name<<"',...)"
+ <<bbtkendl);
+ return p;
+ }
+ //==========================================================================
+
//==========================================================================
/// Ctor with the name of the package
Package::Package(const std::string& name,
const std::string& description,
const std::string& version,
const std::string& BBTKVersion)
- : mName(name),
- mAuthor(author),
- mDescription(description),
- mVersion(version),
- mBBTKVersion(BBTKVersion)
+ :
+ mDynamicLibraryHandler(0),
+ mName(name),
+ mAuthor(author),
+ mDescription(description),
+ mVersion(version)
{
- std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_doc_tmp();
+ bbtkDebugMessage("object",2,"==> Package::Package('"<<name<<"',...)"
+ <<bbtkendl);
+ std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
char c = default_doc_dir.c_str()[strlen(default_doc_dir.c_str())-1];
std::string url = default_doc_dir;
if (c != '/' && c !='\\') url = url + "/";
- url = url + "doc_tmp/" + name + "/index.html";
+ url = url + "temp_dir/" + name + "/index.html";
SetDocURL(url);
SetDocRelativeURL("Relative url not set");
// std::cout << " url=["<<url<<"]"<<std::endl;
// std::cout << "relurl=["<<relurl<<"]"<<std::endl;
- bbtkDebugMessage("Core",7,"Package::Package(\""<<name<<"\")"<<bbtkendl);
+ bbtkDebugMessage("object",2,"<== Package::Package('"<<name<<"',...) OK"
+ <<bbtkendl);
+
}
//==========================================================================
/// Dtor
Package::~Package()
{
- bbtkDebugMessageInc("Core",7,"Package::~Package(\""<<mName<<"\")"<<bbtkendl);
- BlackBoxMapType::const_iterator i;
- for (i=mBlackBoxMap.begin();
- i!=mBlackBoxMap.end();
- ++i)
+ bbtkDebugMessage("object",2,"==> Package::~Package(\""<<mName<<"\")"<<bbtkendl);
+ bbtkDebugMessage("object",2,"<== Package::~Package(\""<<mName<<"\")"<<bbtkendl);
+ }
+ //==========================================================================
+
+
+ //==========================================================================
+ void PackageReleaseBlackBoxDescriptorInternal(Package::WeakPointer pack,
+ const std::string& descname)
+ {
+ // Try to release descriptor
+ bbtkDebugMessage("package",3,"--- Trying to release descriptor '"
+ <<descname<<"'"<<bbtkendl);
+ std::string packname = pack.lock()->GetName();
+
+ Package::BlackBoxMapType::iterator desc =
+ pack.lock()->GetBlackBoxMap().find(descname);
+ if (desc == pack.lock()->GetBlackBoxMap().end())
{
- delete i->second;
- }
- // Adaptors are also stored in the black box map : hence already deleted
+ bbtkDebugMessage("package",3,
+ " Descriptor has already been released"
+ <<bbtkendl);
+ return;
+ }
+ // bbtkDebugMessage("package",3,
+ // " Trying unreferencing it ... "<<std::endl);
+ BlackBoxDescriptor::WeakPointer pdesc = desc->second;
+ desc->second.reset();
+ // if it is dead : remove it
+ if (pdesc.expired())
+ {
+ bbtkDebugMessage("package",2," '"<<packname<<"::"<<descname<<"' Descriptor expired"<<bbtkendl);
+ if (pack.expired())
+ {
+ bbtkDebugMessage("package",2,
+ " ... and caused its package death"
+ <<bbtkendl);
+ return;
+ }
+ desc = pack.lock()->GetBlackBoxMap().find(descname);
+ if (desc != pack.lock()->GetBlackBoxMap().end())
+ pack.lock()->GetBlackBoxMap().erase(desc);
+ }
+ else
+ {
+ bbtkDebugMessage("package",3," ... Descriptor still alive ("
+ <<pdesc.use_count()<<" refs)"
+ <<bbtkendl);
+ pack.lock()->GetBlackBoxMap()[descname] = pdesc.lock();
+ }
+ }
+ //==========================================================================
+
+
+ //==========================================================================
+ /// Release
+ void Package::Release(Package::WeakPointer pack)
+ {
+ std::string packname = pack.lock()->mName;
+ bbtkDebugMessage("package",1,"==> Package::Release('"<<
+ packname<<"')"<<bbtkendl);
+
+ long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
+ long ndesc = pack.lock()->GetBlackBoxMap().size();
+ long nrefs = pack.use_count();
+
+ bbtkDebugMessage("package",2," "<<nrefs<<" refs / "
+ <<ndesc<<" descr / dyn="
+ <<dyn<<std::endl);
+
+ // A package is "free" from any external reference iff :
+ // i) It is not dynamically loaded and nrefs == ndesc
+ // (each desc references its package) or
+ // ii) It is dynamically loaded and nrefs == ndesc + 1
+ // (A dynamic library holds a static pointer on the package it contains
+ // which is allocated when the PACKAGENAMEGetPackage() func is called,
+ // and descallocated (reset) by PACKAGENAMEDeletePackage())
+ if (nrefs == ndesc + dyn)
+ {
+ bbtkDebugMessage("package",2,
+ " -> No more external ref : checking descriptors"
+ <<bbtkendl);
+ // We must take care that removing refs on descriptors
+ // can lead to their deletion which can in turn unref
+ // internal boxes which can release their descriptors hence
+ // call Package::ReleaseBlackBoxDescriptor
+ // As a consequence during descriptors release :
+ // 1) The map can change dynamically : we cannot iterate over it
+ // as any iterator can become invalid
+ // 2) The package can auto-destruct : we must test its existence
+ // after each release
+ // We must also take care of not locking the package pointer
+ // or any ref count check in Package::ReleaseBlackBoxDescriptor
+ // would be wrong
+
+ // The list of descriptors names at start
+ std::vector<std::string> descnamelist;
+ BlackBoxMapType::iterator i;
+ for (i=pack.lock()->mBlackBoxMap.begin();
+ i!= pack.lock()->mBlackBoxMap.end();
+ ++i)
+ descnamelist.push_back(i->first);
+
+ // Iterator over the initial names
+ std::vector<std::string>::iterator descname;
+ for (descname=descnamelist.begin();
+ descname!=descnamelist.end();
+ ++descname)
+ {
+ // Is package still alive ?
+ if (pack.expired())
+ {
+ bbtkDebugMessage("package",2,"--- Package::Release('"<<
+ packname
+ <<"') : package expired during release : bailing out"<<bbtkendl);
+ break;
+ }
+
+ PackageReleaseBlackBoxDescriptorInternal(pack,*descname);
+
+ }
+
+ //
+ UnLoadDynamicLibrary(pack);
+ // Unload orphan dl packages
+ Package::UnLoadReleasedDynamicallyLoadedPackages();
+
+
+
+
+ }
+
+ bbtkDebugMessage("package",1,"<== Package::Release('"<<
+ packname<<"')"<<bbtkendl);
+ if (!pack.expired())
+ {
+ long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
+ long ndesc = pack.lock()->GetBlackBoxMap().size();
+ long nrefs = pack.use_count();
+
+ bbtkDebugMessage("package",1," ... Package still alive ("
+ <<nrefs<<" refs / "
+ <<ndesc<<" descr / dyn="
+ <<dyn<<")"<<std::endl);
+ }
+ else
+ {
+ bbtkDebugMessage("package",1," ... Package has been released"
+ <<std::endl);
+ }
+ }
+ //==========================================================================
+
+ //==========================================================================
+ /// "Releases" the package
+ /// Signals the package that it can free the given descriptor
+ /// if they are no more used and free itself if it is no
+ /// more used
+ /// Note : Any non-weak pointer on the package must have been freed
+ void Package::ReleaseBlackBoxDescriptor(Package::WeakPointer pack,
+ BlackBoxDescriptor::WeakPointer descr)
+ {
+ std::string packname = pack.lock()->mName;
+ std::string dname = descr.lock()->GetTypeName();
+ bbtkDebugMessage("package",3,"==> Package::ReleaseBlackBoxDescriptor('"<<
+ packname<<"','"<<dname<<"') : refs="
+ <<descr.use_count()<<bbtkendl);
+
+ long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
+ long ndesc = pack.lock()->GetBlackBoxMap().size();
+ long nrefs = pack.use_count();
+
+ bbtkDebugMessage("package",3," "<<nrefs<<" refs / "
+ <<ndesc<<" descr / dynamically loaded = "
+ <<dyn<<std::endl);
+
+ // A package is "free" from any external reference iff :
+ // i) It is not dynamically loaded and nrefs == ndesc
+ // (each desc references its package) or
+ // ii) It is dynamically loaded and nrefs == ndesc + 1
+ // (A dynamic library holds a static pointer on the package it contains
+ // which is allocated when the PACKAGENAMEGetPackage() func is called,
+ // and descallocated (reset) by PACKAGENAMEDeletePackage())
+ if (nrefs == ndesc + dyn)
+ {
+ PackageReleaseBlackBoxDescriptorInternal(pack,dname);
+ }
+
+ // If the package is released and dynamically loaded
+ // then put it in the static list mReleasedDynamicallyLoadedPackages
+ UnLoadDynamicLibrary(pack,false);
+
+ bbtkDebugMessage("package",3,"<== Package::ReleaseBlackBoxDescriptor('"<<
+ packname<<"','"<<dname<<"'): refs="
+ <<descr.use_count()<<bbtkendl);
/*
- AdaptorMapType::const_iterator j;
- for (j=mAdaptorMap.begin();
- j!=mAdaptorMap.end();
- ++j)
+ if (!pack.expired())
{
- delete j->second;
- }
- */
- bbtkDebugDecTab("Core",7);
+ long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
+ long ndesc = pack.lock()->GetBlackBoxMap().size();
+ long nrefs = pack.use_count();
+
+ bbtkDebugMessage("package",3," ... Package still alive ("
+ <<nrefs<<" refs / "
+ <<ndesc<<" descr / dyn="
+ <<dyn<<")"<<std::endl);
+ }
+ else
+ {
+ bbtkDebugMessage("package",3," ... Package has been released"
+ <<std::endl);
+ }
+ */
}
+ //==========================================================================
+
//==========================================================================
+ /// 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
+ DynamicLibraryHandler Package::OpenDynamicLibrary
+ ( const std::string& libname,
+ const std::string& package_name,
+ DLGetPackageFunction& getpack,
+ DLDeletePackageFunction& delpack)
+ {
+ bbtkDebugMessage("package",3,"==> Package::OpenDynamicLibrary("
+ <<libname<<")"<<std::endl);
+#if defined(__GNUC__)
+ // Open shared lib
+ void *handler;
+ handler = dlopen(libname.c_str(),
+ BBTK_RTLD_TIME | BBTK_RTLD_SCOPE );
+ if (!handler)
+ {
+ bbtkMessage("package",2,
+ "Could not open shared library [" <<libname<<"] : "
+ <<dlerror() << std::endl);
+ return 0;
+ }
+ bbtkDebugMessage("package",3,"* Shared lib ["<<libname<<"] open"<<std::endl);
+
+ // Loads the Package bbtk version function
+ std::string getvername(package_name);
+ getvername +=
+ BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME);
+ DLGetPackageBBTKVersionFunction getbbtkversion
+ = (DLGetPackageBBTKVersionFunction)(dlsym(handler,getvername.c_str()));
+ if (!getbbtkversion)
+ {
+ bbtkDebugMessage("package",3,"***"<<std::endl);
+ bbtkMessage("package",2,
+ "Shared library ["<<libname
+ <<"] is not a valid bbtk package."
+ <<" Symbol ["<<getvername<<"] :"<<dlerror()<< std::endl);
+ dlclose(handler);
+ return 0;
+ }
+
+ bbtkDebugMessage("package",3,"* Symbol ["<<getvername
+ <<"] found"<<std::endl);
+ // version matches ?
+ if (getbbtkversion() != bbtk::GetVersion())
+ {
+ bbtkMessage("package",2,
+ "Shared library ["<<libname
+ <<"] was build with bbtk version "
+ <<getbbtkversion()
+ <<" but the current program runs with version "
+ <<bbtk::GetVersion()<<" : cannot load it"<<std::endl);
+ dlclose(handler);
+ return 0;
+
+ }
+
+ bbtkDebugMessage("package",3,"* Package bbtk version '"<<getbbtkversion()<<"' matches"<<std::endl);
+ // Loads the Package get function
+ std::string getpackname(package_name);
+ getpackname += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_FUNCTION_NAME);
+ getpack = (DLGetPackageFunction)(dlsym(handler, getpackname.c_str()));
+ if (!getpack)
+ {
+ bbtkMessage("package",2,
+ "Shared library ["<<libname
+ <<"] is not a valid bbtk package."
+ <<" Symbol ["<<getpackname<<"] :"<<dlerror()<< std::endl);
+ dlclose(handler);
+ return 0;
+ }
+
+ bbtkDebugMessage("package",3,"* Symbol ["<<getpackname<<"] found"<<std::endl);
+ // Loads the Package delete function
+
+ std::string delpackname(package_name);
+ delpackname += BBTK_STRINGIFY_SYMBOL(BBTK_DEL_PACKAGE_FUNCTION_NAME);
+ delpack = (DLDeletePackageFunction)(dlsym(handler, delpackname.c_str()));
+ if (!delpack)
+ {
+ bbtkMessage("package",2,
+ "Shared library ["<<libname
+ <<"] is not a valid bbtk package."
+ <<" Symbol ["<<delpackname<<"] :"<<dlerror()<< std::endl);
+ dlclose(handler);
+ return 0;
+ }
+ bbtkDebugMessage("package",3,"* Symbol ["<<delpackname<<"] found"<<std::endl);
+#elif defined(_WIN32)
+
+ HINSTANCE handler;
+
+ SetErrorMode(0);
+ // Open shared lib
+ handler = LoadLibrary(libname.c_str());
+ if (!handler)
+ {
+ bbtkMessage("package",2,
+ "Could not open shared library [" <<libname<<"]"
+ << std::endl);
+ return 0;
+ }
+
+ // Loads the Package bbtk version function
+ std::string getvername(package_name);
+ getvername +=
+ BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME);
+ DLGetPackageBBTKVersionFunction getbbtkversion
+ = (DLGetPackageBBTKVersionFunction)(GetProcAddress(handler,
+ getvername.c_str()));
+ if (!getbbtkversion)
+ {
+ FreeLibrary(handler);
+ bbtkMessage("package",2,
+ "Shared library ["<<libname
+ <<"] is not a valid bbtk package."
+ <<" Symbol ["<<getbbtkversion<<"] not found"<< std::endl);
+ return 0;
+ }
+
+ // version matches ?
+ if (getbbtkversion() != bbtk::GetVersion())
+ {
+ FreeLibrary(handler);
+ bbtkMessage("package",2,
+ "Shared library ["<<libname
+ <<"] was build with bbtk version "
+ <<getbbtkversion()
+ <<" but the current program runs with version "
+ <<bbtk::GetVersion()<<" : cannot load it"<<std::endl);
+ return 0;
+
+ }
+
+ // Loads the Package get function
+ std::string getpackname(package_name);
+ getpackname += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_FUNCTION_NAME);
+ getpack = (DLGetPackageFunction)(GetProcAddress(handler, getpackname.c_str()));
+ if (!getpack)
+ {
+ FreeLibrary(handler);
+ bbtkMessage("package",2,
+ "Shared library ["<<libname
+ <<"] is not a valid bbtk package."
+ <<" Symbol ["<<getpackname<<"] not found"<< std::endl);
+ return 0;
+ }
+
+ // Loads the Package delete function
+ std::string delpackname(package_name);
+ delpackname += BBTK_STRINGIFY_SYMBOL(BBTK_DEL_PACKAGE_FUNCTION_NAME);
+ delpack = (DLDeletePackageFunction)(GetProcAddress(handler, delpackname.c_str()));
+ if (!delpack)
+ {
+ FreeLibrary(handler);
+ bbtkMessage("package",2,
+ "Shared library ["<<libname
+ <<"] is not a valid bbtk package."
+ <<" Symbol ["<<delpackname<<"] not found"<< std::endl);
+ return 0;
+ }
+
+#else
+ bbtkError("neither __GNUC__ nor _WIN32 ?!? How did you compile ?");
+#endif
+
+ return handler;
+ }
+ //==========================================================================
+
+ //==========================================================================
+ /// Loads a package from a dynamic library
+ Package::Pointer Package::CreateFromDynamicLibrary(const std::string& libname,
+ const std::string& pkgname,
+ const std::string& path)
+ {
+ bbtkDebugMessage("package",1,"==> Package::CreateFromDynamicLibrary("
+ <<libname<<")"<<std::endl);
+
+ DLGetPackageFunction gf;
+ DLDeletePackageFunction df;
+ DynamicLibraryHandler h = Package::OpenDynamicLibrary(libname,
+ pkgname,
+ gf,df);
+ if (h==0) return Package::Pointer();
+ Package::Pointer p = gf();
+ p->mDynamicLibraryHandler = h;
+ p->mDLDeletePackageFunction = df;
+
+ std::string separator =
+ ConfigurationFile::GetInstance().Get_file_separator ();
+ //BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
+ std::string docreldoc =
+ separator + "bbdoc" + separator + pkgname + separator + "index.html";
+ std::string reldoc =
+ ".." + separator + ".." + docreldoc;
+ std::string doc = path + separator + ".." + separator
+ + BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
+ + docreldoc;
+
+ p->SetDocURL(doc);
+ p->SetDocRelativeURL(reldoc);
+
+ bbtkDebugMessage("package",1,"<== Package::CreateFromDynamicLibrary("
+ <<libname<<") .. OK"<<std::endl);
+ return p;
+ }
+ //==========================================================================
+
+
+
+
+ //==========================================================================
+ /// UnLoads the package dynamic library (if any)
+ void Package::UnLoadDynamicLibrary(Package::WeakPointer pack, bool doit)
+ {
+ if (pack.expired() || (!pack.lock()->mDynamicLibraryHandler))
+ return;
+
+
+ std::string packname = pack.lock()->GetName();
+ bbtkDebugMessage("package",3,"==> Package::UnLoadDynamicLibrary('"
+ <<packname<<"')"
+ <<std::endl);
+
+ if (!pack.lock()->GetBlackBoxMap().empty())
+ {
+
+ bbtkDebugMessage("package",3," Package not empty ... abort"
+ <<std::endl);
+ return;
+ /*
+ bbtkGlobalError("Package::UnLoadDynamicLibrary('"<<packname<<") : "
+ <<"BlackBoxMap not empty "
+ <<BBTK_INTERNAL_ERROR_MESSAGE);
+ */
+
+ }
+
+ if (pack.use_count()!=1)
+ {
+ bbtkGlobalError("Package::UnLoadDynamicLibrary('"<<packname<<") : "
+ <<"empty dl package with external refs"
+ <<BBTK_INTERNAL_ERROR_MESSAGE);
+ }
+
+ if (doit)
+ {
+ UnLoad(pack);
+ bbtkDebugMessage("package",3," ... dynamic library closed"
+ <<std::endl);
+ }
+ else
+ {
+ mReleasedDynamicallyLoadedPackages.insert(pack);
+ bbtkDebugMessage("package",3,
+ " ... package put in the 'to unload' list"
+ <<std::endl);
+
+ }
+
+ bbtkDebugMessage("package",3,"<== Package::UnLoadDynamicLibrary('"
+ <<packname<<"')"
+ <<std::endl);
+
+ }
+ //==========================================================================
+
+ //==========================================================================
+ /// UnLoads released packages that were loaded dynamically
+ /// see UnLoadDynamicLibrary and ReleaseBlackBoxDescriptor
+ void Package::UnLoadReleasedDynamicallyLoadedPackages()
+ {
+ bbtkDebugMessage("package",2,"==> Package::UnLoadReleasedDynamicallyLoadedPackages()"<<std::endl);
+
+ std::set<Package::WeakPointer>::iterator i;
+ for (i=mReleasedDynamicallyLoadedPackages.begin();
+ i!=mReleasedDynamicallyLoadedPackages.end();
+ ++i)
+ {
+ if (!i->expired()) UnLoad(*i);
+ }
+ bbtkDebugMessage("package",2,"<== Package::UnLoadReleasedDynamicallyLoadedPackages()"<<std::endl);
+ }
+ //==========================================================================
+
+ //==========================================================================
+ void Package::UnLoad(Package::WeakPointer pack)
+ {
+ std::string packname = pack.lock()->GetName();
+ bbtkDebugMessage("package",2,"==> Package::UnLoad("<<packname<<")"<<std::endl);
+
+ Package* p = pack.lock().get();
+
+ DynamicLibraryHandler h = p->mDynamicLibraryHandler;
+
+ // deletes the package
+ p->mDLDeletePackageFunction();
+
+ // closes the dl handler
+#if defined(__GNUC__)
+ dlclose(h);
+#elif defined(_WIN32)
+ FreeLibrary(h);
+#endif
+
+ bbtkDebugMessage("package",2," ... dynamic library unloaded"<<std::endl);
+ }
+ //==========================================================================
//==========================================================================
/// Creates an instance of a black box of type <type> with name <name>
- BlackBox* Package::NewBlackBox(const std::string& type,
- const std::string& name) const
+ BlackBox::Pointer Package::NewBlackBox(const std::string& type,
+ const std::string& name) const
{
- bbtkDebugMessageInc("Core",8,"Package<"<<GetName()<<">::NewBlackBox(\""<<type<<"\",\""<<name<<"\")"<<bbtkendl);
+ bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::NewBlackBox(\""<<type<<"\",\""<<name<<"\")"<<bbtkendl);
BlackBoxMapType::const_iterator i = mBlackBoxMap.find(type);
if (i == mBlackBoxMap.end())
- {
- bbtkDebugDecTab("Core",8);
- return 0;
- }
- BlackBox* bb =i->second->CreateInstance(name);
- bbtkDebugDecTab("Core",8);
+ {
+ bbtkDebugDecTab("Kernel",8);
+ return BlackBox::Pointer();
+ }
+ BlackBox::Pointer bb =i->second->NewBlackBox(name);
+ bbtkDebugDecTab("Kernel",8);
return bb;
}
//==========================================================================
/// Creates an instance of an adaptor of input type <typein> and
/// output type <typeout> with name <name>
- BlackBox* Package::NewAdaptor(TypeInfo typein,
- TypeInfo typeout,
- const std::string& name) const
+ BlackBox::Pointer Package::NewAdaptor(const DataInfo& typein,
+ const DataInfo& typeout,
+ const std::string& name) const
{
- bbtkDebugMessageInc("Core",8,"Package<"<<GetName()<<
- ">::NewAdaptor(<"
- <<TypeName(typein)<<">,<"
- <<TypeName(typeout)<<">,\""
+ bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<
+ ">::NewAdaptor("
+ <<typein<<","
+ <<typeout<<",\""
<<name<<"\")"<<bbtkendl);
- AdaptorKey key(typein,typeout);
+ AdaptorKey key(typein,typeout,
+ BlackBoxDescriptor::DEFAULT_ADAPTOR);
AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
if (i == mAdaptorMap.end())
{
- bbtkDebugDecTab("Core",8);
- return 0;
+ bbtkDebugDecTab("Kernel",8);
+ return BlackBox::Pointer();
}
- BlackBox* bb =i->second->CreateInstance(name);
- bbtkDebugDecTab("Core",8);
+ BlackBox::Pointer bb =i->second.lock()->NewBlackBox(name);
+ bbtkDebugDecTab("Kernel",8);
return bb;
}
//==========================================================================
+ //==========================================================================
+ /// Creates an instance of an adaptor of input type <typein> and
+ /// output type <typeout> with name <name>
+ BlackBox::Pointer Package::NewWidgetAdaptor(const DataInfo& typein,
+ const DataInfo& typeout,
+ const std::string& name) const
+ {
+ bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<
+ ">::NewWidgetAdaptor("
+ <<typein<<","
+ <<typeout<<",\""
+ <<name<<"\")"<<bbtkendl);
+
+ AdaptorKey key(typein,typeout,
+ BlackBoxDescriptor::DEFAULT_GUI);
+ AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
+ if (i == mAdaptorMap.end())
+ {
+ bbtkDebugDecTab("Kernel",8);
+ return BlackBox::Pointer();
+ }
+ BlackBox::Pointer bb =i->second.lock()->NewBlackBox(name);
+ bbtkDebugDecTab("Kernel",8);
+ return bb;
+
+ }
+ //==========================================================================
+ //==========================================================================
+ /// Returns true is the package contains
+ /// an adaptor of input type <typein> and
+ /// output type <typeout>
+ /// If successfull then adaptor contains the black box type name
+ bool Package::FindWidgetAdaptor(const DataInfo& typein,
+ const DataInfo& typeout,
+ std::string& adaptor) const
+ {
+ bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<
+ ">::FindWidgetAdaptor("
+ <<typein<<","
+ <<typeout<<")"<<bbtkendl);
+
+ AdaptorKey key(/*typein*/
+ DataInfo(typeid(void),""),
+ typeout,
+ BlackBoxDescriptor::DEFAULT_GUI);
+ // First try to find a single widget adaptor
+ AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
+ if (i == mAdaptorMap.end())
+ {
+ bbtkDebugDecTab("Kernel",8);
+ return false;
+ }
+ adaptor = i->second.lock()->GetTypeName();
+ bbtkDebugDecTab("Kernel",8);
+ return true;
+
+ }
+ //==========================================================================
+
+
+
+ //==========================================================================
+ /// Returns true is the package contains
+ /// an adaptor of input type <typein> and
+ /// output type <typeout>
+ /// If successfull then adaptor contains the black box type name
+ bool Package::FindAdaptor(const DataInfo& typein,
+ const DataInfo& typeout,
+ std::string& adaptor) const
+ {
+ bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<
+ ">::FindAdaptor("
+ <<typein<<","
+ <<typeout<<")"<<bbtkendl);
+
+ AdaptorKey key(typein,typeout,
+ BlackBoxDescriptor::DEFAULT_ADAPTOR);
+ AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
+ if (i == mAdaptorMap.end())
+ {
+ bbtkDebugDecTab("Kernel",8);
+ return false;
+ }
+ adaptor = i->second.lock()->GetTypeName();
+ bbtkDebugDecTab("Kernel",8);
+ return true;
+
+ }
+ //==========================================================================
+
+
//==========================================================================
/// Registers a black box descriptor in the package
- bool Package::RegisterBlackBox(BlackBoxDescriptor* d)
+ bool Package::RegisterBlackBox(BlackBoxDescriptor::Pointer d)
{
- bbtkDebugMessageInc("Core",8,"Package<"<<GetName()<<">::RegisterBlackBox(\""<<d->GetTypeName()<<"\")"<<std::endl);
+ bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::RegisterBlackBox(\""<<d->GetTypeName()<<"\")"<<std::endl);
+ BlackBoxMapType::iterator i = mBlackBoxMap.find(d->GetTypeName());
+ if (i!=mBlackBoxMap.end())
+ {
+ bbtkWarning("Package<"<<GetName()<<"> : Trying to register box type <"
+ <<d->GetTypeName()<<"> which is already in the package");
+ return false;
+ }
+
mBlackBoxMap[d->GetTypeName()] = d;
- d->SetPackage(this);
+ // d->Reference();
+ d->SetPackage(GetThisPointer<Package>());
// If it is a default adaptor, also register it in the adaptors map
- if ( d->GetCategory() == BlackBoxDescriptor::DEFAULT_ADAPTOR)
+ if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_ADAPTOR )
{
+ bbtkDebugMessage("Kernel",8,"Package<"<<GetName()<<">::RegisterBlackBox(\""<<d->GetTypeName()<<"\") : The box is an adaptor, inserting it in adaptors map ..."<<std::endl);
+
TypeInfo typein = d->GetInputDescriptor("In")->GetTypeInfo();
TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
- AdaptorKey key(typein,typeout);
- AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
+ DataInfo infoin(typein,d->GetInputDescriptor("In")->GetNature());
+ DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
+ AdaptorKey key(infoin,infoout,d->GetKind());
+
+ AdaptorMapType::const_iterator i;
+ i = mAdaptorMap.find(key);
if (i == mAdaptorMap.end())
{
- bbtkDebugMessage("Core",8,"The box is an adaptor, inserting it in adaptors map ..."<<std::endl);
mAdaptorMap[key] = d;
}
// If already an adaptor registered : error
else
{
- bbtkError("Package <"<<GetName()<<
- "> : trying to register black box <"
- <<d->GetTypeName()
- <<"> as default adaptor but there is already a default adaptor registered (<"
- <<i->second->GetTypeName()<<">)");
+ if (i->second.lock()->GetTypeName() != d->GetTypeName())
+ {
+ bbtkError("Package <"<<GetName()<<
+ "> : trying to register black box <"
+ <<d->GetTypeName()
+ <<"> as default adaptor but there is already a default adaptor registered (<"
+ <<i->second.lock()->GetTypeName()<<">)");
+ }
}
+ }
+ // If it is a default adaptor, also register it in the adaptors map
+ else if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_GUI)
+ {
+ bbtkDebugMessage("Kernel",8,"Package<"<<GetName()<<">::RegisterBlackBox(\""<<d->GetTypeName()<<"\") : The box is a widget adaptor, inserting it in adaptors map ..."<<std::endl);
+ TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
+ DataInfo infoin(typeid(void),"");
+ DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
+ AdaptorKey key(infoin,infoout,d->GetKind());
+ AdaptorMapType::const_iterator i;
+ i = mAdaptorMap.find(key);
+ if (i == mAdaptorMap.end())
+ {
+ mAdaptorMap[key] = d;
+ }
+ // If already an adaptor registered : error
+ else
+ {
+ if (i->second.lock()->GetTypeName() != d->GetTypeName())
+ {
+ bbtkError("Package <"<<GetName()<<
+ "> : trying to register black box <"
+ <<d->GetTypeName()
+ <<"> as default widget adaptor but there is already a default adaptor registered (<"
+ <<i->second.lock()->GetTypeName()<<">)");
+ }
+ }
}
- bbtkDebugDecTab("Core",8);
+
+ bbtkDebugDecTab("Kernel",8);
return true;
}
//==========================================================================
-
- //==========================================================================
- /// UnRegisters a black box descriptor from the package
- void Package::UnRegisterBlackBox(const std::string& name)
+ //===================================================================
+ void Package::CheckBoxes() const
{
- bbtkDebugMessageInc("Core",8,"Package<"<<GetName()<<">::UnRegisterBlackBox(\""<<name<<"\")"<<std::endl);
- // Looking into the bb map
- BlackBoxMapType::iterator i = mBlackBoxMap.find(name);
- if (i == mBlackBoxMap.end())
- {
- bbtkDebugDecTab("Core",8);
- bbtkError("UnRegister : The package <"<<GetName()<<"> does not contains the black box <"<<name<<">");
- }
- mBlackBoxMap.erase(i);
- // Is it also in the adaptors map ?
- /*
- AdaptorMapType::iterator j = mAdaptorMap.find(name);
- if (j != mAdaptorMap.end())
+ bbtkMessage("debug",1,"****** Checking Package "<<(void*)this
+ <<" ["<<GetName()<<"]"<<std::endl);
+ BlackBoxMapType::const_iterator i;
+ for (i=mBlackBoxMap.begin();
+ i!=mBlackBoxMap.end();
+ ++i)
{
- mAdaptorMap.erase(j);
+ i->second->Check(true);
}
- */
- bbtkDebugDecTab("Core",8);
+ bbtkMessage("debug",1,"****** Checking Package "<<(void*)this
+ <<" ["<<GetName()<<"] ... OK"<<std::endl);
}
- //==========================================================================
+ //===================================================================
+
//==========================================================================
/// Changes the name of a black box type
void Package::ChangeBlackBoxName( const std::string& oldname, const std::string& newname )
{
- bbtkDebugMessageInc("Core",8,"Package<"<<GetName()<<">::ChangeBlackBoxName(\""<<oldname<<"\",\""<<newname<<"\")"<<std::endl);
+ bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::ChangeBlackBoxName(\""<<oldname<<"\",\""<<newname<<"\")"<<std::endl);
// Looking into the bb map
BlackBoxMapType::iterator i = mBlackBoxMap.find(oldname);
if (i == mBlackBoxMap.end())
{
- bbtkDebugDecTab("Core",8);
- bbtkError("ChangeBlackBoxName : The package <"<<GetName()<<"> does not contains the black box <"<<oldname<<">");
+ bbtkDebugDecTab("Kernel",8);
+ bbtkError("ChangeBlackBoxName : The package <"<<GetName()<<"> does not contains the black box <"<<oldname<<">");
}
i->second->SetTypeName(newname);
mBlackBoxMap[newname] = i->second;
mBlackBoxMap.erase(i);
- bbtkDebugDecTab("Core",8);
+ bbtkDebugDecTab("Kernel",8);
}
//==========================================================================
- /*
-
- //==========================================================================
- /// Registers an adaptor descriptor in the package
- bool Package::RegisterAdaptor(BlackBoxDescriptor* d)
- {
- bbtkDebugMessage("Core",8,"Package<"<<GetName()<<">::RegisterAdaptor(\""<<d->GetTypeName()<<"\")"<<std::endl);
-
- TypeInfo typein = d->GetInputDescriptor("In")->GetTypeInfo();
- TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
- AdaptorKey key(typein,typeout);
-
- mAdaptorMap[key] = d;
- return true;
- }
- //==========================================================================
- */
//==========================================================================
{
unsigned int lmax = 0;
std::vector<std::string> names;
- std::vector<std::string> categs;
+ std::vector<std::string> kinds;
std::vector<std::string> descrs;
BlackBoxMapType::const_iterator i;
++i)
{
if ( adaptors ||
- ( i->second->GetCategory() == BlackBoxDescriptor::STANDARD) )
+ ( i->second->GetKind() == BlackBoxDescriptor::STANDARD) )
{
std::string name(" ");
name += i->second->GetTypeName();
names.push_back(name);
- std::string categ;
- if ( i->second->GetCategory() == BlackBoxDescriptor::ADAPTOR )
+ std::string kind;
+ if ( i->second->GetKind() == BlackBoxDescriptor::ADAPTOR )
{
- categ = std::string("[A]");
+ kind = std::string("[A]");
}
- else if ( i->second->GetCategory() ==
+ else if ( i->second->GetKind() ==
BlackBoxDescriptor::DEFAULT_ADAPTOR )
{
- categ = std::string("[DA]");
+ kind = std::string("[DA]");
}
- categs.push_back(categ);
+ kinds.push_back(kind);
- unsigned int l = name.size()+categ.size();
+ unsigned int l = name.size()+kind.size();
if (l>lmax) lmax = l;
std::string descr;
std::string offs;
offs.append(lmax+3,' ');
std::vector<std::string>::iterator ni,ci,di;
- for (ni = names.begin(), ci = categs.begin(), di = descrs.begin();
+ for (ni = names.begin(), ci = kinds.begin(), di = descrs.begin();
ni != names.end(); ++ni, ++ci, ++di)
{
std::string space;
else
bbtkMessage("Help",1,d << std::endl);
// d = d.substr(dmax,d.size());
- // }
+ // }
}
}
i!=mBlackBoxMap.end();
++i)
{
- if ( i->second->GetCategory() != BlackBoxDescriptor::STANDARD )
+ if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD )
{
bbtkMessage("Help",1,
" "<<i->second->GetTypeName());
- if ( i->second->GetCategory() ==
+ if ( i->second->GetKind() ==
BlackBoxDescriptor::DEFAULT_ADAPTOR )
{
bbtkMessage("Help",1,
{
bbtkMessage("Help",1,
" : "<<i->second->GetDescription());
-
+
}
bbtkMessage("Help",1,std::endl);
}
{
bbtkMessage("Help",1,
" : "<<i->second->GetDescription());
-
+
}
bbtkMessage("Help",1,std::endl);
}
/// Prints help on a black box
void Package::HelpBlackBox(const std::string& name, bool full) const
{
- bbtkDebugMessageInc("Core",8,"Package<"<<GetName()<<">::HelpBlackBox(\""
+ bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::HelpBlackBox(\""
<<name<<"\")"<<bbtkendl);
BlackBoxMapType::const_iterator i = mBlackBoxMap.find(name);
if (i == mBlackBoxMap.end())
{
- bbtkDebugDecTab("Core",8);
+ bbtkDebugDecTab("Kernel",8);
bbtkError("The package <"<<GetName()<<"> does not contains the black box <"<<name<<">");
}
// bbtkMessage("Help",1,"["<<GetName()<<"] ");
i->second->GetHelp(full);
- bbtkDebugDecTab("Core",8);
+ bbtkDebugDecTab("Kernel",8);
}
//==========================================================================
/// Returns true iff the package contains the box of name boxname
bool Package::ContainsBlackBox(const std::string& name) const
{
- bbtkDebugMessageInc("Core",8,"Package<"<<GetName()<<">::HelpBlackBox(\""
+ bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::HelpBlackBox(\""
<<name<<"\")"<<bbtkendl);
BlackBoxMapType::const_iterator i = mBlackBoxMap.find(name);
if (i == mBlackBoxMap.end())
- {
- bbtkDebugDecTab("Core",8);
- return false;
- }
- bbtkDebugDecTab("Core",8);
+ {
+ bbtkDebugDecTab("Kernel",8);
+ return false;
+ }
+ bbtkDebugDecTab("Kernel",8);
return true;
}
//==========================================================================
//==========================================================================
void Package::CreateHtmlPage(const std::string& filename,
const std::string& caller,
- const std::string& source,
+ const std::string& source,
const std::string& custom_header,
const std::string& custom_title,
int detail,
int level,
bool relative_link ) const
{
- bbtkDebugMessageInc("Core",9,"Package<"<<GetName()<<">::CreateHtmlPage(\""
+ bbtkDebugMessageInc("Kernel",9,"Package<"<<GetName()<<">::CreateHtmlPage(\""
<<filename<<"\")"<<bbtkendl);
//---------------------
std::ofstream s;
s.open(filename.c_str());
if (!s.good())
- {
- bbtkError("Package "<<GetName()<<" : CreateHtmlPage : could not open file '"<<filename<<"'");
- }
+ {
+ bbtkError("Package "<<GetName()<<" : CreateHtmlPage : could not open file '"<<filename<<"'");
+ }
//----------------------
// Html head
<< GetDescription() << "</TD></TR>\n";
s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
<< GetAuthor() << "</TD></TR>\n";
- s << "<TR><TD style='vertical-align: top;'><b> Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
+ s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
+ << GetCategory() << "</TD></TR>\n";
+ s << "<TR><TD style='vertical-align: top;'><b> Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
<< GetVersion() << "</TD></TR>\n";
s << "<TR><TD style='vertical-align: top;'><b> bbtk Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
- << GetBBTKVersion() << "</TD></TR>\n";
+ << bbtk::GetVersion() << "</TD></TR>\n";
s << "</TABLE>\n";
}
BlackBoxMapType::const_iterator i;
for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end(); ++i)
{
- if ( i->second->GetCategory() != BlackBoxDescriptor::STANDARD)
+ if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD)
continue;
std::string name = i->second->GetTypeName();
Utilities::html_format(name);
std::string descr = i->second->GetDescription();
-
+ Utilities::html_format(descr);
+
s << "<TR>";
s << "<TD style='vertical-align: top;'>";
- s << "<li><a name=\"toc_"<<name
+ s << " <a name=\"toc_"<<name
<<"\" href=\"#"<<name<<"\">"
<<name<<"</a>";
s << "</TD> ";
s << "</TABLE>\n";
- s << "</li></ul>\n";
+ s << "</ul>\n";
s << "</div>\n";
//-------------------
// s << "<div class=\"contents\">\n";
s << "<p><b> Adaptors : </b>\n";
s << "<ul>\n";
-
+
// BlackBoxMapType::const_iterator i;
s << "<p><TABLE cellspacing=0 cellpadding=3>\n";
for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end();++i)
{
- if ( i->second->GetCategory() == BlackBoxDescriptor::STANDARD)
+ if ( i->second->GetKind() == BlackBoxDescriptor::STANDARD)
continue;
-
+
std::string name = i->second->GetTypeName();
Utilities::html_format(name);
std::string descr = i->second->GetDescription();
-
+
s << "<TR>";
s << "<TD style='vertical-align: top;'>";
- s << "<li><a name=\"toc_"<<name
+ s << " <a name=\"toc_"<<name
<<"\" href=\"#"<<name<<"\">"
<<name<<"</a>";
s << "</TD> ";
s << "</TR>\n";
}
s << "</TABLE>\n";
-
- s << "</li></ul>\n";
+
+ s << "</ul>\n";
s << "</div>\n";
}
// Computes output directory from filename to pass it to
// BlackBoxDescriptor::InsertHtmlHelp
std::string dir;
- std::string::size_type slash_position =
- filename.find_last_of(ConfigurationFile::GetInstance().Get_file_separator ());
- if (slash_position != std::string::npos) {
+
+ std::string::size_type slash_position = filename.find_last_of("/\\");
+
+
+ if (slash_position != std::string::npos) {
if (slash_position == 0)
- slash_position = 1;
+ slash_position = 1;
dir = filename.substr(0,slash_position);
}
ptm = gmtime ( &rawtime );
s << "<p><hr>\n";
- s << "Automatically generated by <b>"<<caller<<"</b> from <b>"
- <<source<<"</b> on "
+ s << "Automatically generated by <b>"<<caller<<"</b> "//from <b>"
+ // <<source<<"</b>
+ <<"on "
<< ptm->tm_mday << "/" << ptm->tm_mon << "/" << ptm->tm_year+1900
<< " - " << ptm->tm_hour << ":" << ptm->tm_min << " GMT\n";
s << "</body></html>\n";
//----------------------
// End
- bbtkDebugDecTab("Core",9);
+ bbtkDebugDecTab("Kernel",9);
+ }
+ //==========================================================================
+
+ //==========================================================================
+ std::string Package::GetObjectName() const
+ {
+ return std::string("Package '")+mName+std::string("'");
+ }
+ //==========================================================================
+
+ //==========================================================================
+ std::string Package::GetObjectInfo() const
+ {
+ std::stringstream i;
+ i << " - "<<mBlackBoxMap.size() << " boxes" << std::endl;
+ if (mDynamicLibraryHandler)
+ {
+ i<< " - Loaded from dynamic library"<<std::endl;
+ }
+ return i.str();
+ }
+ //==========================================================================
+
+
+ //==========================================================================
+ size_t Package::GetObjectSize() const
+ {
+ size_t s = Superclass::GetObjectSize();
+ s += Package::GetObjectInternalSize();
+ return s;
+ }
+ //==========================================================================
+ //==========================================================================
+ size_t Package::GetObjectInternalSize() const
+ {
+ size_t s = sizeof(Package);
+ return s;
+ }
+ //==========================================================================
+ //==========================================================================
+ size_t Package::GetObjectRecursiveSize() const
+ {
+ size_t s = Superclass::GetObjectRecursiveSize();
+ s += Package::GetObjectInternalSize();
+
+ BlackBoxMapType::const_iterator i;
+ for (i = mBlackBoxMap.begin(); i!=mBlackBoxMap.end(); ++i )
+ {
+ s += i->second->GetObjectRecursiveSize();
+ }
+ return s;
}
//==========================================================================
+
+ //==========================================================================
+ std::set<Package::WeakPointer>
+ Package::mReleasedDynamicallyLoadedPackages;
+ //==========================================================================
}