Program: bbtk
Module: $RCSfile: bbtkPackage.cxx,v $
Language: C++
- Date: $Date: 2008/04/08 06:59:30 $
- Version: $Revision: 1.11 $
+ Date: $Date: 2008/04/22 06:59:31 $
+ Version: $Revision: 1.14 $
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& version,
const std::string& BBTKVersion)
:
+ mDynamicLibraryHandler(0),
mName(name),
mAuthor(author),
mDescription(description),
- mVersion(version),
- mBBTKVersion(BBTKVersion)
+ mVersion(version)
{
+ 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;
// std::cout << " url=["<<url<<"]"<<std::endl;
// std::cout << "relurl=["<<relurl<<"]"<<std::endl;
- bbtkDebugMessage("Kernel",7,"Package::Package(\""<<name<<"\")"<<bbtkendl);
+ bbtkDebugMessage("object",2,"<== Package::Package('"<<name<<"',...) OK"
+ <<bbtkendl);
+
}
//==========================================================================
/// Dtor
Package::~Package()
{
- bbtkDebugMessageInc("Kernel",7,"Package::~Package(\""<<mName<<"\")"<<bbtkendl);
- BlackBoxMapType::const_iterator i;
- for (i=mBlackBoxMap.begin();
- i!=mBlackBoxMap.end();
- ++i)
- {
- delete i->second;
- }
- // Adaptors are also stored in the black box map : hence already deleted
+ 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())
+ {
+ 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<<"')"<<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<<"')"<<bbtkendl);
/*
- AdaptorMapType::const_iterator j;
- for (j=mAdaptorMap.begin();
- j!=mAdaptorMap.end();
- ++j)
+ if (!pack.expired())
{
- delete j->second;
+ 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);
}
- */
- bbtkDebugDecTab("Kernel",7);
+ 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)(GetProcAdress(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)(GetProcAdress(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)(GetProcAdress(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("Kernel",8,"Package<"<<GetName()<<">::NewBlackBox(\""<<type<<"\",\""<<name<<"\")"<<bbtkendl);
if (i == mBlackBoxMap.end())
{
bbtkDebugDecTab("Kernel",8);
- return 0;
+ return BlackBox::Pointer();
}
- BlackBox* bb =i->second->CreateInstance(name);
+ 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(const DataInfo& typein,
+ BlackBox::Pointer Package::NewAdaptor(const DataInfo& typein,
const DataInfo& typeout,
const std::string& name) const
{
if (i == mAdaptorMap.end())
{
bbtkDebugDecTab("Kernel",8);
- return 0;
+ return BlackBox::Pointer();
}
- BlackBox* bb =i->second->CreateInstance(name);
+ 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* Package::NewWidgetAdaptor(const DataInfo& typein,
+ BlackBox::Pointer Package::NewWidgetAdaptor(const DataInfo& typein,
const DataInfo& typeout,
const std::string& name) const
{
<<name<<"\")"<<bbtkendl);
AdaptorKey key(typein,typeout,
- BlackBoxDescriptor::DEFAULT_WIDGET_ADAPTOR);
+ BlackBoxDescriptor::DEFAULT_GUI);
AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
if (i == mAdaptorMap.end())
{
bbtkDebugDecTab("Kernel",8);
- return 0;
+ return BlackBox::Pointer();
}
- BlackBox* bb =i->second->CreateInstance(name);
+ 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
">::FindWidgetAdaptor("
<<typein<<","
<<typeout<<")"<<bbtkendl);
-
- AdaptorKey key(typein,typeout,
- BlackBoxDescriptor::DEFAULT_WIDGET_ADAPTOR);
+
+ 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->GetTypeName();
+ adaptor = i->second.lock()->GetTypeName();
bbtkDebugDecTab("Kernel",8);
return true;
bbtkDebugDecTab("Kernel",8);
return false;
}
- adaptor = i->second->GetTypeName();
+ 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("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->GetKind() == BlackBoxDescriptor::DEFAULT_ADAPTOR) ||
- (d->GetKind() == BlackBoxDescriptor::DEFAULT_WIDGET_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();
DataInfo infoin(typein,d->GetInputDescriptor("In")->GetNature());
DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
- bbtkDebugMessage("Kernel",8,"LG Adaptor "<<infoin<<" to "<<infoout
- <<" - kind="<<d->GetKind()<<std::endl);
-
+ 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 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 = mAdaptorMap.find(key);
+ AdaptorMapType::const_iterator i;
+ i = mAdaptorMap.find(key);
if (i == mAdaptorMap.end())
{
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 widget adaptor but there is already a default adaptor registered (<"
+ <<i->second.lock()->GetTypeName()<<">)");
+ }
}
}
+
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("Kernel",8,"Package<"<<GetName()<<">::UnRegisterBlackBox(\""<<name<<"\")"<<std::endl);
- // Looking into the bb map
- BlackBoxMapType::iterator i = mBlackBoxMap.find(name);
- if (i == mBlackBoxMap.end())
- {
- bbtkDebugDecTab("Kernel",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("Kernel",8);
+ bbtkMessage("Debug",1,"****** Checking Package "<<(void*)this
+ <<" ["<<GetName()<<"] ... OK"<<std::endl);
}
- //==========================================================================
+ //===================================================================
+
//==========================================================================
/// Changes the name of a black box type
}
//==========================================================================
- /*
-
- //==========================================================================
- /// Registers an adaptor descriptor in the package
- bool Package::RegisterAdaptor(BlackBoxDescriptor* d)
- {
- bbtkDebugMessage("Kernel",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;
- }
- //==========================================================================
- */
//==========================================================================
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";
}
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;
+ //==========================================================================
}