2 # ---------------------------------------------------------------------
4 # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
6 # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
7 # Previous Authors : Laurent Guigues, Jean-Pierre Roux
8 # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
10 # This software is governed by the CeCILL-B license under French law and
11 # abiding by the rules of distribution of free software. You can use,
12 # modify and/ or redistribute the software under the terms of the CeCILL-B
13 # license as circulated by CEA, CNRS and INRIA at the following URL
14 # http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
15 # or in the file LICENSE.txt.
17 # As a counterpart to the access to the source code and rights to copy,
18 # modify and redistribute granted by the license, users are provided only
19 # with a limited warranty and the software's author, the holder of the
20 # economic rights, and the successive licensors have only limited
23 # The fact that you are presently reading this means that you have had
24 # knowledge of the CeCILL-B license and that you accept its terms.
25 # ------------------------------------------------------------------------ */
29 /*=========================================================================
31 Module: $RCSfile: bbtkPackage.cxx,v $
33 Date: $Date: 2012/11/16 08:49:01 $
34 Version: $Revision: 1.37 $
35 =========================================================================*/
41 *\brief Class bbtk::Package : registers black boxes descriptors and is able to create instances of the black boxes registered.
43 #include "bbtkPackage.h"
44 #include "bbtkComplexBlackBoxDescriptor.h"
45 #include "bbtkMessageManager.h"
46 #include "bbtkConfigurationFile.h"
49 #include "bbtkUtilities.h"
56 //==========================================================================
57 /// Creates a new package
58 Package::Pointer Package::New(const std::string& name,
59 const std::string& author,
60 const std::string& description,
61 const std::string& version)
63 bbtkDebugMessage("object",1,"##> Package::New('"<<name<<"',...)"
65 Package::Pointer p = MakePointer(new Package(name,
69 bbtkDebugMessage("object",2,"<## Package::New('"<<name<<"',...)"
73 //==========================================================================
75 //==========================================================================
76 /// Ctor with the name of the package
77 Package::Package(const std::string& name,
78 const std::string& author,
79 const std::string& description,
80 const std::string& version)
82 mDynamicLibraryHandler(0),
85 mDescription(description),
89 bbtkDebugMessage("object",2,"==> Package('"<<name<<"',...)"
92 std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
93 char c = default_doc_dir.c_str()[strlen(default_doc_dir.c_str())-1];
94 std::string url = default_doc_dir;
95 if (c != '/' && c !='\\') url = url + "/";
96 url = url + "temp_dir/" + name + "/index.html";
99 SetDocRelativeURL("Relative url not set");
102 std::string relurl(BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH));
103 relurl += "/packages/"+name+"/bbdoc/index.html";
104 std::string url = ConfigurationFile::GetInstance().Get_url()
107 SetDocRelativeURL(relurl);
110 // std::cout << " url=["<<url<<"]"<<std::endl;
111 // std::cout << "relurl=["<<relurl<<"]"<<std::endl;
112 bbtkDebugMessage("object",2,"<== Package::Package('"<<name<<"',...) OK"
116 //==========================================================================
120 //==========================================================================
124 bbtkDebugMessage("object",2,"==> ~Package(\""<<mName<<"\")"<<bbtkendl);
126 //==========================================================================
129 //==========================================================================
130 void PackageReleaseBlackBoxDescriptorInternal(Package::WeakPointer pack,
131 const std::string& descname)
133 // Try to release descriptor
134 std::string packname = pack.lock()->GetName();
136 bbtkDebugMessage("package",5,"--- Releasing descriptor '"
137 <<packname<<"::"<<descname<<"'"<<bbtkendl);
140 Package::DescriptorMapType::iterator desc =
141 pack.lock()->GetDescriptorMap().find(descname);
142 if (desc == pack.lock()->GetDescriptorMap().end())
144 bbtkDebugMessage("package",5,
145 " Descriptor has already been released"
149 // bbtkDebugMessage("package",3,
150 // " Trying unreferencing it ... "<<std::endl);
151 BlackBoxDescriptor::WeakPointer pdesc = desc->second;
152 desc->second.reset();
153 // if it is dead : remove it
156 bbtkDebugMessage("package",2," ==> '"<<packname<<"::"<<descname<<"' Descriptor expired"<<bbtkendl);
159 bbtkDebugMessage("package",2,
160 " ... and caused its package death"
164 desc = pack.lock()->GetDescriptorMap().find(descname);
165 if (desc != pack.lock()->GetDescriptorMap().end()) pack.lock()->GetDescriptorMap().erase(desc);
166 } else { //pdesc.expired
167 bbtkDebugMessage("package",5," ... Descriptor still alive ("
168 <<pdesc.use_count()<<" refs)"
170 pack.lock()->GetDescriptorMap()[descname] = pdesc.lock();
173 //==========================================================================
176 //==========================================================================
178 void Package::Release(Package::WeakPointer pack)
180 std::string packname = pack.lock()->mName;
181 bbtkDebugMessage("package",1,"==> Package::Release('"<<
182 packname<<"')"<<bbtkendl);
184 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
185 long ndesc = pack.lock()->GetDescriptorMap().size();
186 long nrefs = pack.use_count();
188 bbtkDebugMessage("package",5," "<<nrefs<<" refs / "
189 <<ndesc<<" descr / dyn="
192 // A package is "free" from any external reference iff :
193 // i) It is not dynamically loaded and nrefs == ndesc
194 // (each desc references its package) or
195 // ii) It is dynamically loaded and nrefs == ndesc + 1
196 // (A dynamic library holds a static pointer on the package it contains
197 // which is allocated when the PACKAGENAMEGetPackage() func is called,
198 // and descallocated (reset) by PACKAGENAMEDeletePackage())
199 if (nrefs == ndesc + dyn)
201 bbtkDebugMessage("package",5,
202 " -> No more external ref : checking descriptors"
204 // We must take care that removing refs on descriptors
205 // can lead to their deletion which can in turn unref
206 // internal boxes which can release their descriptors hence
207 // call Package::ReleaseBlackBoxDescriptor
208 // As a consequence during descriptors release :
209 // 1) The map can change dynamically : we cannot iterate over it
210 // as any iterator can become invalid
211 // 2) The package can auto-destruct : we must test its existence
212 // after each release
213 // We must also take care of not locking the package pointer
214 // or any ref count check in Package::ReleaseBlackBoxDescriptor
217 // The list of descriptors names at start
218 std::vector<std::string> descnamelist;
219 DescriptorMapType::iterator i;
220 for (i=pack.lock()->mDescriptorMap.begin();
221 i!= pack.lock()->mDescriptorMap.end();
223 descnamelist.push_back(i->first);
225 // Iterator over the initial names
226 std::vector<std::string>::iterator descname;
227 for (descname=descnamelist.begin();
228 descname!=descnamelist.end();
231 // Is package still alive ?
234 bbtkDebugMessage("package",1,"--- Package::Release('"<<
236 <<"') : package expired during release : bailing out"<<bbtkendl);
241 BlackBoxDescriptor::Pointer desc = pack.lock()->mDescriptorMap[*descname];
242 if ( (dyn==0) || (boost::dynamic_pointer_cast<ComplexBlackBoxDescriptor>(desc)) )
244 PackageReleaseBlackBoxDescriptorInternal(pack,*descname);
247 PackageReleaseBlackBoxDescriptorInternal(pack,*descname);
253 UnLoadDynamicLibrary(pack);
254 // Unload orphan dl packages
255 Package::UnLoadReleasedDynamicallyLoadedPackages();
259 #ifdef BBTK_COMPILE_DEBUG_MESSAGES
261 bbtkDebugMessage("package",2,"<== Package::Release('"<<
262 packname<<"')"<<bbtkendl);
266 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
267 long ndesc = pack.lock()->GetDescriptorMap().size();
268 long nrefs = pack.use_count();
270 bbtkDebugMessage("package",1," ... Package still alive ("
272 <<ndesc<<" descr / dyn="
273 <<dyn<<")"<<std::endl);
277 bbtkDebugMessage("package",1," ... Package has been released"
282 //==========================================================================
284 //==========================================================================
285 /// "Releases" the package
286 /// Signals the package that it can free the given descriptor
287 /// if they are no more used and free itself if it is no
289 /// Note : Any non-weak pointer on the package must have been freed
290 void Package::ReleaseBlackBoxDescriptor(Package::WeakPointer pack,
291 BlackBoxDescriptor::WeakPointer descr)
293 std::string packname = pack.lock()->mName;
294 std::string dname = descr.lock()->GetTypeName();
295 bbtkDebugMessage("package",3,"==> Package::ReleaseBlackBoxDescriptor('"<<
296 packname<<"','"<<dname<<"') : refs="
297 <<descr.use_count()<<bbtkendl);
299 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
300 long ndesc = pack.lock()->GetDescriptorMap().size();
301 long nrefs = pack.use_count();
303 bbtkDebugMessage("package",5," "<<nrefs<<" refs / "
304 <<ndesc<<" descr / dynamically loaded = "
307 // A package is "free" from any external reference iff :
308 // i) It is not dynamically loaded and nrefs == ndesc
309 // (each desc references its package) or
310 // ii) It is dynamically loaded and nrefs == ndesc + 1
311 // (A dynamic library holds a static pointer on the package it contains
312 // which is allocated when the PACKAGENAMEGetPackage() func is called,
313 // and descallocated (reset) by PACKAGENAMEDeletePackage())
314 if (nrefs == ndesc + dyn)
319 PackageReleaseBlackBoxDescriptorInternal(pack,dname);
321 PackageReleaseBlackBoxDescriptorInternal(pack,dname);
325 // If the package is released and dynamically loaded
326 // then put it in the static list mReleasedDynamicallyLoadedPackages
327 UnLoadDynamicLibrary(pack,false);
329 bbtkDebugMessage("package",4,"<== Package::ReleaseBlackBoxDescriptor('"<<
330 packname<<"','"<<dname<<"'): refs="
331 <<descr.use_count()<<bbtkendl);
335 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
336 long ndesc = pack.lock()->GetDescriptorMap().size();
337 long nrefs = pack.use_count();
339 bbtkDebugMessage("package",3," ... Package still alive ("
341 <<ndesc<<" descr / dyn="
342 <<dyn<<")"<<std::endl);
346 bbtkDebugMessage("package",3," ... Package has been released"
351 //==========================================================================
353 //==========================================================================
354 /// Opens a dynamic library which contains a bbtk package
355 /// Returns the handler
356 /// Load the package management symbols from the lib
357 /// returns false if a problem occured hence can be used
358 /// to test that a dyn lib is a valid bbtk package lib
359 /// NB : The BBTK version exported from the library
360 /// is tested against the current bbtk version
361 DynamicLibraryHandler Package::OpenDynamicLibrary( const std::string& libname,const std::string& package_name,
362 DLGetPackageFunction& getpack, DLDeletePackageFunction& delpack)
365 printf("EED Package::OpenDynamicLibrary %s %s \n", libname.c_str(), package_name.c_str() );
367 bbtkDebugMessage("package",3,"==> Package::OpenDynamicLibrary("
368 <<libname<<")"<<std::endl);
369 #if defined(__GNUC__)
373 handler = dlopen(libname.c_str(), BBTK_RTLD_TIME | BBTK_RTLD_SCOPE );
374 // handler = dlopen(libname.c_str(), RTLD_LAZY | RTLD_LOCAL );
378 bbtkMessage("package",0,
379 "BBTK ..ERROR.. loading could not open shared library [" <<libname<<"] : "
380 <<dlerror() << std::endl);
384 bbtkDebugMessage("package",3,"* Shared lib ["<<libname<<"] open"<<std::endl);
386 // Loads the Package bbtk version function
387 std::string getvername(package_name);
388 getvername += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME);
389 DLGetPackageBBTKVersionFunction getbbtkversion = (DLGetPackageBBTKVersionFunction)(dlsym(handler,getvername.c_str()));
392 bbtkDebugMessage("package",3,"***"<<std::endl);
393 bbtkMessage("package",0,
394 "BBTK ..ERROR.. loading shared library ["<<libname
395 <<"] is not a valid bbtk package."
396 <<" Symbol ["<<getvername<<"] :"<<dlerror()<< std::endl);
401 bbtkDebugMessage("package",3,"* Symbol ["<<getvername
402 <<"] found"<<std::endl);
405 if (getbbtkversion() != bbtk::GetVersion())
407 bbtkMessage("package",0,
408 "BBTK ..ERROR.. loading: "<<package_name
409 <<" - Shared library ["<<libname
410 <<"] was build with bbtk version "
412 <<" but the current program runs with version "
413 <<bbtk::GetVersion()<<" : cannot load it. You have to recompile your BBTK-Package."<<std::endl);
419 bbtkDebugMessage("package",3,"* Package bbtk version '"<<getbbtkversion()<<"' matches"<<std::endl);
420 // Loads the Package get function
421 std::string getpackname(package_name);
422 getpackname += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_FUNCTION_NAME);
423 getpack = (DLGetPackageFunction)(dlsym(handler, getpackname.c_str()));
426 bbtkMessage("package",0,
427 "BBTK ..ERROR.. loading shared library ["<<libname
428 <<"] is not a valid bbtk package."
429 <<" Symbol ["<<getpackname<<"] :"<<dlerror()<< std::endl);
434 bbtkDebugMessage("package",3,"* Symbol ["<<getpackname<<"] found"<<std::endl);
435 // Loads the Package delete function
437 std::string delpackname(package_name);
438 delpackname += BBTK_STRINGIFY_SYMBOL(BBTK_DEL_PACKAGE_FUNCTION_NAME);
439 delpack = (DLDeletePackageFunction)(dlsym(handler, delpackname.c_str()));
442 bbtkMessage("package",0,
443 "BBTK ..ERROR.. loading shared library ["<<libname
444 <<"] is not a valid bbtk package."
445 <<" Symbol ["<<delpackname<<"] :"<<dlerror()<< std::endl);
449 bbtkDebugMessage("package",3,"* Symbol ["<<delpackname<<"] found"<<std::endl);
450 #elif defined(_WIN32)
456 handler = LoadLibrary(libname.c_str());
459 bbtkMessage("package",0,
460 "BBTK ..ERROR.. could not open shared library [" <<libname<<"]"
462 DWORD dwErrorCode = 0;
463 dwErrorCode = GetLastError();
464 bbtkMessage("package",2,
465 "Windows Error: [" << dwErrorCode <<"]"
471 // Loads the Package bbtk version function
472 std::string getvername(package_name);
473 getvername += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME);
474 DLGetPackageBBTKVersionFunction getbbtkversion = (DLGetPackageBBTKVersionFunction)(GetProcAddress(handler, getvername.c_str()));
478 FreeLibrary(handler);
479 bbtkMessage("package",0,
480 "BBTK ..ERROR.. loading shared library ["<<libname
481 <<"] is not a valid bbtk package."
482 <<" Symbol ["<<getbbtkversion<<"] not found"<< std::endl);
487 if (getbbtkversion() != bbtk::GetVersion())
489 FreeLibrary(handler);
490 bbtkMessage("package",0,
491 "BBTK ..ERROR.. loading: "<<package_name
492 <<" - Shared library ["<<libname
493 <<"] was build with bbtk version "
495 <<" but the current program runs with version "
496 <<bbtk::GetVersion()<<" : cannot load it. You have to recompile your BBTK-Package."<<std::endl);
500 // Loads the Package get function
501 std::string getpackname(package_name);
502 getpackname += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_FUNCTION_NAME);
503 getpack = (DLGetPackageFunction)(GetProcAddress(handler, getpackname.c_str()));
506 FreeLibrary(handler);
507 bbtkMessage("package",0,
508 "BBTK ..ERROR.. loading shared library ["<<libname
509 <<"] is not a valid bbtk package."
510 <<" Symbol ["<<getpackname<<"] not found"<< std::endl);
514 // Loads the Package delete function
515 std::string delpackname(package_name);
516 delpackname += BBTK_STRINGIFY_SYMBOL(BBTK_DEL_PACKAGE_FUNCTION_NAME);
517 delpack = (DLDeletePackageFunction)(GetProcAddress(handler, delpackname.c_str()));
520 FreeLibrary(handler);
521 bbtkMessage("package",0,
522 "BBTK ..ERROR.. loading shared library ["<<libname
523 <<"] is not a valid bbtk package."
524 <<" Symbol ["<<delpackname<<"] not found"<< std::endl);
529 bbtkError("neither __GNUC__ nor _WIN32 ?!? How did you compile ?");
534 //==========================================================================
536 //==========================================================================
537 /// Loads a package from a dynamic library
538 Package::Pointer Package::CreateFromDynamicLibrary(const std::string& libname,
539 const std::string& pkgname,
540 const std::string& path)
542 bbtkDebugMessage("package",1,"==> Package::CreateFromDynamicLibrary("
543 <<libname<<")"<<std::endl);
545 DLGetPackageFunction gf;
546 DLDeletePackageFunction df;
547 DynamicLibraryHandler h = Package::OpenDynamicLibrary(libname,
550 if (h==0) return Package::Pointer();
551 Package::Pointer p = gf();
552 p->mDynamicLibraryHandler = h;
553 p->mDLDeletePackageFunction = df;
555 std::string separator =
556 ConfigurationFile::GetInstance().Get_file_separator ();
557 //BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
558 std::string docreldoc =
559 separator + "bbdoc" + separator + pkgname + separator + "index.html";
561 ".." + separator + ".." + docreldoc;
562 std::string doc = path + separator + ".." + separator
563 + BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
567 p->SetDocRelativeURL(reldoc);
569 bbtkDebugMessage("package",2,"<== Package::CreateFromDynamicLibrary("
570 <<libname<<") .. OK"<<std::endl);
573 //==========================================================================
578 //==========================================================================
579 /// UnLoads the package dynamic library (if any)
580 void Package::UnLoadDynamicLibrary(Package::WeakPointer pack, bool doit)
582 if (pack.expired() || (!pack.lock()->mDynamicLibraryHandler))
585 std::string packname = pack.lock()->GetName();
586 bbtkDebugMessage("package",5,"==> Package::UnLoadDynamicLibrary('"
590 if (!pack.lock()->GetDescriptorMap().empty())
593 bbtkDebugMessage("package",5," Package not empty ... abort"
597 bbtkGlobalError("Package::UnLoadDynamicLibrary('"<<packname<<") : "
598 <<"DescriptorMap not empty "
599 <<BBTK_INTERNAL_ERROR_MESSAGE);
603 if (pack.use_count()!=1)
605 bbtkGlobalError("Package::UnLoadDynamicLibrary('"<<packname<<") : "
606 <<"empty dl package with external refs"
607 <<BBTK_INTERNAL_ERROR_MESSAGE);
613 bbtkDebugMessage("package",5,"==> dynamic library for package '"
614 <<packname<<"' closed"
619 mReleasedDynamicallyLoadedPackages.insert(pack);
620 bbtkDebugMessage("package",1,"==> package '"<<packname
621 <<"' put in the 'to unload' list"
625 bbtkDebugMessage("package",5,"<== Package::UnLoadDynamicLibrary('"
629 //==========================================================================
631 //==========================================================================
632 /// UnLoads released packages that were loaded dynamically
633 /// see UnLoadDynamicLibrary and ReleaseBlackBoxDescriptor
634 void Package::UnLoadReleasedDynamicallyLoadedPackages()
636 bbtkDebugMessage("package",5,"==> Package::UnLoadReleasedDynamicallyLoadedPackages()"<<std::endl);
638 std::set<Package::WeakPointer>::iterator i;
641 if(mReleasedDynamicallyLoadedPackages.size()>0){
642 for (i=mReleasedDynamicallyLoadedPackages.begin();
643 i!=mReleasedDynamicallyLoadedPackages.end();
646 if (!i->expired()) UnLoad(*i);
650 bbtkDebugMessage("package",5,"<== Package::UnLoadReleasedDynamicallyLoadedPackages()"<<std::endl);
652 //==========================================================================
654 //==========================================================================
655 void Package::UnLoad(Package::WeakPointer pack)
657 std::string packname = pack.lock()->GetName();
658 bbtkDebugMessage("package",6,"==> Package::UnLoad("<<packname<<")"<<std::endl);
660 Package* p = pack.lock().get();
662 DynamicLibraryHandler h = p->mDynamicLibraryHandler;
664 // deletes the package
665 p->mDLDeletePackageFunction();
667 // closes the dl handler
668 #if defined(__GNUC__)
671 printf("EED Package::UnLoad ERROR %s\n", packname.c_str() );
672 bbtkWarning("Failed to close dynamic library for package '"<<packname
676 #elif defined(_WIN32)
680 bbtkDebugMessage("package",1,"==> dynamic library for package '"
681 <<packname<<"' closed"
683 bbtkDebugMessage("package",6," ... dynamic library unloaded"<<std::endl);
685 //==========================================================================
687 bool Package::ifBoxExist( std::string type)
690 DescriptorMapType::const_iterator i = mDescriptorMap.find(type);
691 if (i != mDescriptorMap.end())
698 //==========================================================================
699 /// Creates an instance of a black box of type <type> with name <name>
700 BlackBox::Pointer Package::NewBlackBox(const std::string& type,
701 const std::string& name) const
703 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<">::NewBlackBox(\""<<type<<"\",\""<<name<<"\")"<<bbtkendl);
705 DescriptorMapType::const_iterator i = mDescriptorMap.find(type);
706 if (i == mDescriptorMap.end())
708 bbtkDebugDecTab("kernel",8);
709 return BlackBox::Pointer();
711 BlackBox::Pointer bb =i->second->NewBlackBox(name);
712 bbtkDebugDecTab("kernel",8);
716 //==========================================================================
720 //==========================================================================
721 /// Creates an instance of an adaptor of input type <typein> and
722 /// output type <typeout> with name <name>
723 BlackBox::Pointer Package::NewAdaptor(const DataInfo& typein,
724 const DataInfo& typeout,
725 const std::string& name) const
727 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
731 <<name<<"\")"<<bbtkendl);
733 AdaptorKey key(typein,typeout,
734 BlackBoxDescriptor::DEFAULT_ADAPTOR);
735 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
736 if (i == mAdaptorMap.end())
738 bbtkDebugDecTab("kernel",8);
739 return BlackBox::Pointer();
741 BlackBox::Pointer bb =i->second.lock()->NewBlackBox(name);
742 bbtkDebugDecTab("kernel",8);
746 //==========================================================================
748 //==========================================================================
749 /// Creates an instance of an adaptor of input type <typein> and
750 /// output type <typeout> with name <name>
751 BlackBox::Pointer Package::NewWidgetAdaptor(const DataInfo& typein,
752 const DataInfo& typeout,
753 const std::string& name) const
755 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
756 ">::NewWidgetAdaptor("
759 <<name<<"\")"<<bbtkendl);
761 AdaptorKey key(typein,typeout,
762 BlackBoxDescriptor::DEFAULT_GUI);
763 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
764 if (i == mAdaptorMap.end())
766 bbtkDebugDecTab("kernel",8);
767 return BlackBox::Pointer();
769 BlackBox::Pointer bb =i->second.lock()->NewBlackBox(name);
770 bbtkDebugDecTab("kernel",8);
774 //==========================================================================
778 //==========================================================================
779 /// Returns true is the package contains
780 /// an adaptor of input type <typein> and
781 /// output type <typeout>
782 /// If successfull then adaptor contains the black box type name
783 bool Package::FindWidgetAdaptor(const DataInfo& typein,
784 const DataInfo& typeout,
785 std::string& adaptor) const
787 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
788 ">::FindWidgetAdaptor("
790 <<typeout<<")"<<bbtkendl);
792 AdaptorKey key(/*typein*/
793 DataInfo(typeid(void),""),
795 BlackBoxDescriptor::DEFAULT_GUI);
796 // First try to find a single widget adaptor
797 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
798 if (i == mAdaptorMap.end())
800 bbtkDebugDecTab("kernel",8);
803 adaptor = i->second.lock()->GetTypeName();
804 bbtkDebugDecTab("kernel",8);
808 //==========================================================================
812 //==========================================================================
813 /// Returns true is the package contains
814 /// an adaptor of input type <typein> and
815 /// output type <typeout>
816 /// If successfull then adaptor contains the black box type name
817 bool Package::FindAdaptor(const DataInfo& typein,
818 const DataInfo& typeout,
819 std::string& adaptor) const
821 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
824 <<typeout<<")"<<bbtkendl);
826 AdaptorKey key(typein,typeout,
827 BlackBoxDescriptor::DEFAULT_ADAPTOR);
828 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
829 if (i == mAdaptorMap.end())
831 bbtkDebugDecTab("kernel",8);
834 adaptor = i->second.lock()->GetTypeName();
835 bbtkDebugDecTab("kernel",8);
839 //==========================================================================
842 //==========================================================================
843 /// Registers a black box descriptor in the package
844 bool Package::Register(BlackBoxDescriptor::Pointer d)
846 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<">::Register(\""<<d->GetTypeName()<<"\")"<<std::endl);
848 DescriptorMapType::iterator i = mDescriptorMap.find(d->GetTypeName());
849 if (i!=mDescriptorMap.end())
851 bbtkWarning("Package<"<<GetName()<<"> : Trying to register box type <"
852 <<d->GetTypeName()<<"> which is already in the package");
856 mDescriptorMap[d->GetTypeName()] = d;
858 d->SetPackage(GetThisPointer<Package>());
860 // If it is a default adaptor, also register it in the adaptors map
861 if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_ADAPTOR )
863 bbtkDebugMessage("kernel",8,"Package<"<<GetName()<<">::Register(\""<<d->GetTypeName()<<"\") : The box is an adaptor, inserting it in adaptors map ..."<<std::endl);
865 TypeInfo typein = d->GetInputDescriptor("In")->GetTypeInfo();
866 TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
867 DataInfo infoin(typein,d->GetInputDescriptor("In")->GetNature());
868 DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
869 AdaptorKey key(infoin,infoout,d->GetKind());
871 AdaptorMapType::const_iterator i;
872 i = mAdaptorMap.find(key);
873 if (i == mAdaptorMap.end())
875 mAdaptorMap[key] = d;
877 // If already an adaptor registered : error
880 if (i->second.lock()->GetTypeName() != d->GetTypeName())
882 bbtkError("Package <"<<GetName()<<
883 "> : trying to register black box <"
885 <<"> as default adaptor but there is already a default adaptor registered (<"
886 <<i->second.lock()->GetTypeName()<<">)");
890 // If it is a default adaptor, also register it in the adaptors map
891 else if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_GUI)
893 bbtkDebugMessage("kernel",8,"Package<"<<GetName()<<">::Register(\""<<d->GetTypeName()<<"\") : The box is a widget adaptor, inserting it in adaptors map ..."<<std::endl);
895 TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
896 DataInfo infoin(typeid(void),"");
897 DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
898 AdaptorKey key(infoin,infoout,d->GetKind());
900 AdaptorMapType::const_iterator i;
901 i = mAdaptorMap.find(key);
902 if (i == mAdaptorMap.end())
904 mAdaptorMap[key] = d;
906 // If already an adaptor registered : error
909 if (i->second.lock()->GetTypeName() != d->GetTypeName())
911 bbtkError("Package <"<<GetName()<<
912 "> : trying to register black box <"
914 <<"> as default widget adaptor but there is already a default adaptor registered (<"
915 <<i->second.lock()->GetTypeName()<<">)");
921 bbtkDebugDecTab("kernel",8);
925 //==========================================================================
927 //===================================================================
928 void Package::Check() const
930 bbtkMessage("debug",1,"****** Checking Package "<<(void*)this
931 <<" ["<<GetName()<<"]"<<std::endl);
932 DescriptorMapType::const_iterator i;
933 for (i=mDescriptorMap.begin();
934 i!=mDescriptorMap.end();
937 i->second->Check(true);
939 bbtkMessage("debug",1,"****** Checking Package "<<(void*)this
940 <<" ["<<GetName()<<"] ... OK"<<std::endl);
942 //===================================================================
945 //==========================================================================
946 /// Changes the name of a black box type
947 void Package::ChangeDescriptorName( const std::string& oldname, const std::string& newname )
949 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()
950 <<">::ChangeDescriptorName(\""<<oldname
951 <<"\",\""<<newname<<"\")"<<std::endl);
952 // Looking into the bb map
953 DescriptorMapType::iterator i = mDescriptorMap.find(oldname);
954 if (i == mDescriptorMap.end())
956 bbtkDebugDecTab("kernel",8);
957 bbtkError("ChangeDescriptorName : The package <"<<GetName()<<"> does not contains the black box <"<<oldname<<">");
960 i->second->SetTypeName(newname);
961 mDescriptorMap[newname] = i->second;
962 mDescriptorMap.erase(i);
964 bbtkDebugDecTab("kernel",8);
966 //==========================================================================
970 //==========================================================================
971 void Package::PrintHelpListDescriptors(bool description, bool adaptors) const
973 unsigned int lmax = 0;
974 std::vector<std::string> names;
975 std::vector<std::string> kinds;
976 std::vector<std::string> descrs;
978 DescriptorMapType::const_iterator i;
979 for (i=mDescriptorMap.begin();
980 i!=mDescriptorMap.end();
984 ( i->second->GetKind() == BlackBoxDescriptor::STANDARD) )
986 std::string name(" ");
987 name += i->second->GetTypeName();
988 names.push_back(name);
991 if ( i->second->GetKind() == BlackBoxDescriptor::ADAPTOR )
993 kind = std::string("[A]");
995 else if ( i->second->GetKind() ==
996 BlackBoxDescriptor::DEFAULT_ADAPTOR )
998 kind = std::string("[DA]");
1000 kinds.push_back(kind);
1002 unsigned int l = name.size()+kind.size();
1003 if (l>lmax) lmax = l;
1009 descr += i->second->GetDescription();
1011 descrs.push_back(descr);
1017 offs.append(lmax+3,' ');
1018 std::vector<std::string>::iterator ni,ci,di;
1019 for (ni = names.begin(), ci = kinds.begin(), di = descrs.begin();
1020 ni != names.end(); ++ni, ++ci, ++di)
1023 space.append(lmax - ni->size() - ci->size(),' ');
1024 bbtkMessage("help",1,*ni << space << *ci );
1026 unsigned int dmax = 75 - lmax;
1027 // while (d.size() > dmax )
1030 bbtkMessage("help",1,d.substr(0,dmax) << "..." << std::endl);
1032 bbtkMessage("help",1,d << std::endl);
1033 // d = d.substr(dmax,d.size());
1038 //==========================================================================
1040 //==========================================================================
1041 /// Displays the list of adaptors of the package
1042 void Package::PrintHelpListAdaptors(bool description) const
1044 DescriptorMapType::const_iterator i;
1045 for (i=mDescriptorMap.begin();
1046 i!=mDescriptorMap.end();
1049 if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD )
1051 bbtkMessage("help",1,
1052 " "<<i->second->GetTypeName());
1053 if ( i->second->GetKind() ==
1054 BlackBoxDescriptor::DEFAULT_ADAPTOR )
1056 bbtkMessage("help",1,
1061 bbtkMessage("help",1,
1062 " : "<<i->second->GetDescription());
1065 bbtkMessage("help",1,std::endl);
1069 AdaptorMapType::const_iterator i;
1070 for (i=mAdaptorMap.begin();
1071 i!=mAdaptorMap.end();
1074 bbtkMessage("help",1,
1075 " "<<i->second->GetTypeName());
1078 bbtkMessage("help",1,
1079 " : "<<i->second->GetDescription());
1082 bbtkMessage("help",1,std::endl);
1086 //==========================================================================
1088 //==========================================================================
1089 /// Prints help on a black box descriptor
1090 void Package::PrintHelpDescriptor(const std::string& name, bool full) const
1092 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()
1093 <<">::PrintHelpDescriptor(\""
1094 <<name<<"\")"<<bbtkendl);
1096 DescriptorMapType::const_iterator i = mDescriptorMap.find(name);
1097 if (i == mDescriptorMap.end())
1099 bbtkDebugDecTab("kernel",8);
1100 bbtkError("The package <"<<GetName()<<"> does not contains the black box <"<<name<<">");
1102 // bbtkMessage("help",1,"["<<GetName()<<"] ");
1103 i->second->GetHelp(full);
1104 bbtkDebugDecTab("kernel",8);
1107 //==========================================================================
1110 //==========================================================================
1111 /// Returns true iff the package contains the box of name boxname
1112 bool Package::ContainsDescriptor(const std::string& name) const
1114 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()
1115 <<">::ContainsDescriptor(\""
1116 <<name<<"\")"<<bbtkendl);
1118 DescriptorMapType::const_iterator i = mDescriptorMap.find(name);
1119 if (i == mDescriptorMap.end())
1121 bbtkDebugDecTab("kernel",8);
1124 bbtkDebugDecTab("kernel",8);
1127 //==========================================================================
1131 //==========================================================================
1132 void Package::CreateHtmlPage(const std::string& filename,
1133 const std::string& caller,
1134 const std::string& source,
1135 const std::string& custom_header,
1136 const std::string& custom_title,
1139 bool relative_link ) const
1141 bbtkDebugMessageInc("kernel",9,"Package<"<<GetName()<<">::CreateHtmlPage(\""
1142 <<filename<<"\")"<<bbtkendl);
1144 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1133"<<std::endl;
1146 //---------------------
1149 s.open(filename.c_str());
1152 bbtkError("Package "<<GetName()<<" : CreateHtmlPage : could not open file '"<<filename<<"'");
1155 //----------------------
1157 std::string title = "BBTK Package "+GetName()+" "+GetVersion();
1159 if (custom_title.length() != 0) title = custom_title;
1161 s << "<html lang=\"en\">\n";
1163 s << "<title>" << title << "</title>\n";
1164 s << "<meta http-equiv=\"Content-Type\" content=\"text/html\">\n";
1165 s << "<meta name=\"description\" content=\""<<title<<"\">\n";
1166 s << "<meta name=\"generator\" content=\"\">\n";
1167 s << "<link title=\"Top\" rel=\"top\" href=\"#Top\">\n";
1168 //<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
1169 s << "<meta http-equiv=\"Content-Style-Type\" content=\"text/css\"><style type=\"text/css\"><!--\n";
1170 s << "pre.display { font-family:inherit }\n";
1171 s << "pre.format { font-family:inherit }\n";
1172 s << "pre.smalldisplay { font-family:inherit; font-size:smaller }\n";
1173 s << "pre.smallformat { font-family:inherit; font-size:smaller }\n";
1174 s << "pre.smallexample { font-size:smaller }\n";
1175 s << "pre.smalllisp { font-size:smaller }\n";
1176 s << "span.sc { font-variant:small-caps }\n";
1177 s << "span.roman { font-family:serif; font-weight:normal; } \n";
1178 s << "span.sansserif { font-family:sans-serif; font-weight:normal; }\n";
1179 s << "--></style>\n";
1181 //----------------------
1183 //----------------------
1186 s << "<a name=\"Top\"></a>\n";
1188 //----------------------
1190 if ( custom_header.length() != 0)
1192 if ( custom_header != "none" )
1195 in.open(custom_header.c_str());
1198 bbtkError("Could not open file \""<<custom_header<<"\"");
1203 in.getline(buffer,512);
1204 std::string line(buffer);
1211 s << "<object data=\"" << custom_header
1212 << "\" type = \"text/html\"\"style=\"width: 1200px; height: 400px;\"> Warning: "
1213 << custom_header <<" could not be embedded.</object>\n";
1222 s << "<h1 class=\"settitle\">"<<title<<"</h1>\n";
1223 s << "<p><TABLE cellspacing=0 cellpadding=3>\n";
1224 s << "<TR><TD style='vertical-align: top;'><b> Description </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1225 << GetDescription() << "</TD></TR>\n";
1226 s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1227 << GetAuthor() << "</TD></TR>\n";
1228 s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1229 << GetCategory() << "</TD></TR>\n";
1230 s << "<TR><TD style='vertical-align: top;'><b> Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1231 << GetVersion() << "</TD></TR>\n";
1232 s << "<TR><TD style='vertical-align: top;'><b> bbtk Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1233 << bbtk::GetVersion() << "</TD></TR>\n";
1236 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1225"<<std::endl;
1237 //-------------------
1238 // Table of contents
1240 // s << "<div class=\"contents\">\n";
1241 s << "<p><b> Black Boxes : </b>\n";
1244 s << "<p><TABLE cellspacing=0 cellpadding=3>\n";
1246 DescriptorMapType::const_iterator i;
1247 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1236"<<std::endl;
1248 for (i=mDescriptorMap.begin(); i!=mDescriptorMap.end(); ++i) {
1249 if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD)
1252 std::string name = i->second->GetTypeName();
1253 Utilities::html_format(name);
1254 std::string descr = i->second->GetDescription();
1255 //Utilities::html_format(descr);
1256 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1246"<<std::endl;
1258 s << "<TD style='vertical-align: top;'>";
1259 s << " <a name=\"toc_"<<name
1260 <<"\" href=\"#"<<name<<"\">"
1263 s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
1272 //-------------------
1274 if (mAdaptorMap.size()>0)
1276 // s << "<div class=\"contents\">\n";
1277 s << "<p><b> Adaptors : </b>\n";
1279 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1268"<<std::endl;
1280 // DescriptorMapType::const_iterator i;
1281 s << "<p><TABLE cellspacing=0 cellpadding=3>\n";
1282 for (i=mDescriptorMap.begin(); i!=mDescriptorMap.end();++i)
1284 if ( i->second->GetKind() == BlackBoxDescriptor::STANDARD)
1287 std::string name = i->second->GetTypeName();
1288 Utilities::html_format(name);
1289 std::string descr = i->second->GetDescription();
1292 s << "<TD style='vertical-align: top;'>";
1293 s << " <a name=\"toc_"<<name
1294 <<"\" href=\"#"<<name<<"\">"
1297 s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
1307 // s << "<div class=\"node\">\n";
1309 // s << "<p><hr>\n";
1310 // s << "<a name=\"Top\"></a>\n";
1311 // s << "Top: <a rel=\"top\" accesskey=\"t\" href=\"#Top\">Top</a>\n";
1312 // s << "Previous: <a rel="previous" accesskey="p" href="#dir">(dir)</a>,
1313 // s << "Up: <a rel="up" accesskey="u" href="#dir">(dir)</a>
1317 //----------------------
1320 //-------------------
1321 // Computes output directory from filename to pass it to
1322 // BlackBoxDescriptor::InsertHtmlHelp
1325 std::string::size_type slash_position = filename.find_last_of("/\\");
1328 if (slash_position != std::string::npos) {
1329 if (slash_position == 0)
1331 dir = filename.substr(0,slash_position);
1334 for (i=mDescriptorMap.begin();
1335 i!=mDescriptorMap.end();
1338 i->second->InsertHtmlHelp(s,detail,level,dir,relative_link);
1341 //----------------------
1346 ptm = gmtime ( &rawtime );
1349 s << "Automatically generated by <b>"<<caller<<"</b> "//from <b>"
1352 << ptm->tm_mday << "/" << ptm->tm_mon << "/" << ptm->tm_year+1900
1353 << " - " << ptm->tm_hour << ":" << ptm->tm_min << " GMT\n";
1354 s << "</body></html>\n";
1356 //----------------------
1359 bbtkDebugDecTab("kernel",9);
1361 //==========================================================================
1363 //==========================================================================
1364 std::string Package::GetObjectName() const
1366 return std::string("Package '")+mName+std::string("'");
1368 //==========================================================================
1370 //==========================================================================
1371 std::string Package::GetObjectInfo() const
1373 std::stringstream i;
1374 i << " - "<<mDescriptorMap.size() << " boxes" << std::endl;
1375 if (mDynamicLibraryHandler)
1377 i<< " - Loaded from dynamic library"<<std::endl;
1381 //==========================================================================
1384 //==========================================================================
1385 size_t Package::GetObjectSize() const
1387 size_t s = Superclass::GetObjectSize();
1388 s += Package::GetObjectInternalSize();
1391 //==========================================================================
1392 //==========================================================================
1393 size_t Package::GetObjectInternalSize() const
1395 size_t s = sizeof(Package);
1398 //==========================================================================
1399 //==========================================================================
1400 size_t Package::GetObjectRecursiveSize() const
1402 size_t s = Superclass::GetObjectRecursiveSize();
1403 s += Package::GetObjectInternalSize();
1405 DescriptorMapType::const_iterator i;
1406 for (i = mDescriptorMap.begin(); i!=mDescriptorMap.end(); ++i )
1408 s += i->second->GetObjectRecursiveSize();
1412 //==========================================================================
1413 void Package::GetBoxesInside(NodeTreeC& tree, int cont)
1415 DescriptorMapType::const_iterator i;
1416 std::cout<<"*********a********"<<std::endl;
1417 for (i=mDescriptorMap.begin(); i!=mDescriptorMap.end(); ++i)
1419 i->second->GetBoxesInside(tree, cont);
1420 std::cout<<"*****************"<<std::endl;
1423 //==========================================================================
1424 //==========================================================================
1425 std::set<Package::WeakPointer>
1426 Package::mReleasedDynamicallyLoadedPackages;
1427 //==========================================================================