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),
88 printf("EED Package::Package Start\n");
89 bbtkDebugMessage("object",2,"==> Package('"<<name<<"',...)"
92 std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
93 printf("EED Package::Package 1\n");
94 char c = default_doc_dir.c_str()[strlen(default_doc_dir.c_str())-1];
95 std::string url = default_doc_dir;
96 if (c != '/' && c !='\\') url = url + "/";
97 url = url + "temp_dir/" + name + "/index.html";
98 printf("EED Package::Package 2\n");
101 printf("EED Package::Package 3\n");
102 SetDocRelativeURL("Relative url not set");
103 printf("EED Package::Package 4\n");
106 std::string relurl(BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH));
107 relurl += "/packages/"+name+"/bbdoc/index.html";
108 std::string url = ConfigurationFile::GetInstance().Get_url()
111 SetDocRelativeURL(relurl);
114 // std::cout << " url=["<<url<<"]"<<std::endl;
115 // std::cout << "relurl=["<<relurl<<"]"<<std::endl;
116 bbtkDebugMessage("object",2,"<== Package::Package('"<<name<<"',...) OK"
118 printf("EED Package::Package End\n");
121 //==========================================================================
125 //==========================================================================
129 bbtkDebugMessage("object",2,"==> ~Package(\""<<mName<<"\")"<<bbtkendl);
131 //==========================================================================
134 //==========================================================================
135 void PackageReleaseBlackBoxDescriptorInternal(Package::WeakPointer pack,
136 const std::string& descname)
138 // Try to release descriptor
139 std::string packname = pack.lock()->GetName();
141 bbtkDebugMessage("package",5,"--- Releasing descriptor '"
142 <<packname<<"::"<<descname<<"'"<<bbtkendl);
145 Package::DescriptorMapType::iterator desc =
146 pack.lock()->GetDescriptorMap().find(descname);
147 if (desc == pack.lock()->GetDescriptorMap().end())
149 bbtkDebugMessage("package",5,
150 " Descriptor has already been released"
154 // bbtkDebugMessage("package",3,
155 // " Trying unreferencing it ... "<<std::endl);
156 BlackBoxDescriptor::WeakPointer pdesc = desc->second;
157 desc->second.reset();
158 // if it is dead : remove it
161 bbtkDebugMessage("package",2," ==> '"<<packname<<"::"<<descname<<"' Descriptor expired"<<bbtkendl);
164 bbtkDebugMessage("package",2,
165 " ... and caused its package death"
169 desc = pack.lock()->GetDescriptorMap().find(descname);
170 if (desc != pack.lock()->GetDescriptorMap().end()) pack.lock()->GetDescriptorMap().erase(desc);
171 } else { //pdesc.expired
172 bbtkDebugMessage("package",5," ... Descriptor still alive ("
173 <<pdesc.use_count()<<" refs)"
175 pack.lock()->GetDescriptorMap()[descname] = pdesc.lock();
178 //==========================================================================
181 //==========================================================================
183 void Package::Release(Package::WeakPointer pack)
185 std::string packname = pack.lock()->mName;
186 bbtkDebugMessage("package",1,"==> Package::Release('"<<
187 packname<<"')"<<bbtkendl);
189 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
190 long ndesc = pack.lock()->GetDescriptorMap().size();
191 long nrefs = pack.use_count();
193 bbtkDebugMessage("package",5," "<<nrefs<<" refs / "
194 <<ndesc<<" descr / dyn="
197 // A package is "free" from any external reference iff :
198 // i) It is not dynamically loaded and nrefs == ndesc
199 // (each desc references its package) or
200 // ii) It is dynamically loaded and nrefs == ndesc + 1
201 // (A dynamic library holds a static pointer on the package it contains
202 // which is allocated when the PACKAGENAMEGetPackage() func is called,
203 // and descallocated (reset) by PACKAGENAMEDeletePackage())
204 if (nrefs == ndesc + dyn)
206 bbtkDebugMessage("package",5,
207 " -> No more external ref : checking descriptors"
209 // We must take care that removing refs on descriptors
210 // can lead to their deletion which can in turn unref
211 // internal boxes which can release their descriptors hence
212 // call Package::ReleaseBlackBoxDescriptor
213 // As a consequence during descriptors release :
214 // 1) The map can change dynamically : we cannot iterate over it
215 // as any iterator can become invalid
216 // 2) The package can auto-destruct : we must test its existence
217 // after each release
218 // We must also take care of not locking the package pointer
219 // or any ref count check in Package::ReleaseBlackBoxDescriptor
222 // The list of descriptors names at start
223 std::vector<std::string> descnamelist;
224 DescriptorMapType::iterator i;
225 for (i=pack.lock()->mDescriptorMap.begin();
226 i!= pack.lock()->mDescriptorMap.end();
228 descnamelist.push_back(i->first);
230 // Iterator over the initial names
231 std::vector<std::string>::iterator descname;
232 for (descname=descnamelist.begin();
233 descname!=descnamelist.end();
236 // Is package still alive ?
239 bbtkDebugMessage("package",1,"--- Package::Release('"<<
241 <<"') : package expired during release : bailing out"<<bbtkendl);
246 BlackBoxDescriptor::Pointer desc = pack.lock()->mDescriptorMap[*descname];
247 if ( (dyn==0) || (boost::dynamic_pointer_cast<ComplexBlackBoxDescriptor>(desc)) )
249 PackageReleaseBlackBoxDescriptorInternal(pack,*descname);
252 PackageReleaseBlackBoxDescriptorInternal(pack,*descname);
258 UnLoadDynamicLibrary(pack);
259 // Unload orphan dl packages
260 Package::UnLoadReleasedDynamicallyLoadedPackages();
264 #ifdef BBTK_COMPILE_DEBUG_MESSAGES
266 bbtkDebugMessage("package",2,"<== Package::Release('"<<
267 packname<<"')"<<bbtkendl);
271 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
272 long ndesc = pack.lock()->GetDescriptorMap().size();
273 long nrefs = pack.use_count();
275 bbtkDebugMessage("package",1," ... Package still alive ("
277 <<ndesc<<" descr / dyn="
278 <<dyn<<")"<<std::endl);
282 bbtkDebugMessage("package",1," ... Package has been released"
287 //==========================================================================
289 //==========================================================================
290 /// "Releases" the package
291 /// Signals the package that it can free the given descriptor
292 /// if they are no more used and free itself if it is no
294 /// Note : Any non-weak pointer on the package must have been freed
295 void Package::ReleaseBlackBoxDescriptor(Package::WeakPointer pack,
296 BlackBoxDescriptor::WeakPointer descr)
298 std::string packname = pack.lock()->mName;
299 std::string dname = descr.lock()->GetTypeName();
300 bbtkDebugMessage("package",3,"==> Package::ReleaseBlackBoxDescriptor('"<<
301 packname<<"','"<<dname<<"') : refs="
302 <<descr.use_count()<<bbtkendl);
304 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
305 long ndesc = pack.lock()->GetDescriptorMap().size();
306 long nrefs = pack.use_count();
308 bbtkDebugMessage("package",5," "<<nrefs<<" refs / "
309 <<ndesc<<" descr / dynamically loaded = "
312 // A package is "free" from any external reference iff :
313 // i) It is not dynamically loaded and nrefs == ndesc
314 // (each desc references its package) or
315 // ii) It is dynamically loaded and nrefs == ndesc + 1
316 // (A dynamic library holds a static pointer on the package it contains
317 // which is allocated when the PACKAGENAMEGetPackage() func is called,
318 // and descallocated (reset) by PACKAGENAMEDeletePackage())
319 if (nrefs == ndesc + dyn)
324 PackageReleaseBlackBoxDescriptorInternal(pack,dname);
326 PackageReleaseBlackBoxDescriptorInternal(pack,dname);
330 // If the package is released and dynamically loaded
331 // then put it in the static list mReleasedDynamicallyLoadedPackages
332 UnLoadDynamicLibrary(pack,false);
334 bbtkDebugMessage("package",4,"<== Package::ReleaseBlackBoxDescriptor('"<<
335 packname<<"','"<<dname<<"'): refs="
336 <<descr.use_count()<<bbtkendl);
340 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
341 long ndesc = pack.lock()->GetDescriptorMap().size();
342 long nrefs = pack.use_count();
344 bbtkDebugMessage("package",3," ... Package still alive ("
346 <<ndesc<<" descr / dyn="
347 <<dyn<<")"<<std::endl);
351 bbtkDebugMessage("package",3," ... Package has been released"
356 //==========================================================================
358 //==========================================================================
359 /// Opens a dynamic library which contains a bbtk package
360 /// Returns the handler
361 /// Load the package management symbols from the lib
362 /// returns false if a problem occured hence can be used
363 /// to test that a dyn lib is a valid bbtk package lib
364 /// NB : The BBTK version exported from the library
365 /// is tested against the current bbtk version
366 DynamicLibraryHandler Package::OpenDynamicLibrary( const std::string& libname,const std::string& package_name,
367 DLGetPackageFunction& getpack, DLDeletePackageFunction& delpack)
370 printf("EED Package::OpenDynamicLibrary %s %s \n", libname.c_str(), package_name.c_str() );
372 bbtkDebugMessage("package",3,"==> Package::OpenDynamicLibrary("
373 <<libname<<")"<<std::endl);
374 #if defined(__GNUC__)
378 handler = dlopen(libname.c_str(), BBTK_RTLD_TIME | BBTK_RTLD_SCOPE );
379 // handler = dlopen(libname.c_str(), RTLD_LAZY | RTLD_LOCAL );
383 bbtkMessage("package",0,
384 "BBTK ..ERROR.. loading could not open shared library [" <<libname<<"] : "
385 <<dlerror() << std::endl);
389 bbtkDebugMessage("package",3,"* Shared lib ["<<libname<<"] open"<<std::endl);
391 // Loads the Package bbtk version function
392 std::string getvername(package_name);
393 getvername += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME);
394 DLGetPackageBBTKVersionFunction getbbtkversion = (DLGetPackageBBTKVersionFunction)(dlsym(handler,getvername.c_str()));
397 bbtkDebugMessage("package",3,"***"<<std::endl);
398 bbtkMessage("package",0,
399 "BBTK ..ERROR.. loading shared library ["<<libname
400 <<"] is not a valid bbtk package."
401 <<" Symbol ["<<getvername<<"] :"<<dlerror()<< std::endl);
406 bbtkDebugMessage("package",3,"* Symbol ["<<getvername
407 <<"] found"<<std::endl);
410 if (getbbtkversion() != bbtk::GetVersion())
412 bbtkMessage("package",0,
413 "BBTK ..ERROR.. loading: "<<package_name
414 <<" - Shared library ["<<libname
415 <<"] was build with bbtk version "
417 <<" but the current program runs with version "
418 <<bbtk::GetVersion()<<" : cannot load it. You have to recompile your BBTK-Package."<<std::endl);
424 bbtkDebugMessage("package",3,"* Package bbtk version '"<<getbbtkversion()<<"' matches"<<std::endl);
425 // Loads the Package get function
426 std::string getpackname(package_name);
427 getpackname += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_FUNCTION_NAME);
428 getpack = (DLGetPackageFunction)(dlsym(handler, getpackname.c_str()));
431 bbtkMessage("package",0,
432 "BBTK ..ERROR.. loading shared library ["<<libname
433 <<"] is not a valid bbtk package."
434 <<" Symbol ["<<getpackname<<"] :"<<dlerror()<< std::endl);
439 bbtkDebugMessage("package",3,"* Symbol ["<<getpackname<<"] found"<<std::endl);
440 // Loads the Package delete function
442 std::string delpackname(package_name);
443 delpackname += BBTK_STRINGIFY_SYMBOL(BBTK_DEL_PACKAGE_FUNCTION_NAME);
444 delpack = (DLDeletePackageFunction)(dlsym(handler, delpackname.c_str()));
447 bbtkMessage("package",0,
448 "BBTK ..ERROR.. loading shared library ["<<libname
449 <<"] is not a valid bbtk package."
450 <<" Symbol ["<<delpackname<<"] :"<<dlerror()<< std::endl);
454 bbtkDebugMessage("package",3,"* Symbol ["<<delpackname<<"] found"<<std::endl);
455 #elif defined(_WIN32)
461 handler = LoadLibrary(libname.c_str());
464 bbtkMessage("package",0,
465 "BBTK ..ERROR.. could not open shared library [" <<libname<<"]"
467 DWORD dwErrorCode = 0;
468 dwErrorCode = GetLastError();
469 bbtkMessage("package",2,
470 "Windows Error: [" << dwErrorCode <<"]"
476 // Loads the Package bbtk version function
477 std::string getvername(package_name);
478 getvername += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME);
479 DLGetPackageBBTKVersionFunction getbbtkversion = (DLGetPackageBBTKVersionFunction)(GetProcAddress(handler, getvername.c_str()));
483 FreeLibrary(handler);
484 bbtkMessage("package",0,
485 "BBTK ..ERROR.. loading shared library ["<<libname
486 <<"] is not a valid bbtk package."
487 <<" Symbol ["<<getbbtkversion<<"] not found"<< std::endl);
492 if (getbbtkversion() != bbtk::GetVersion())
494 FreeLibrary(handler);
495 bbtkMessage("package",0,
496 "BBTK ..ERROR.. loading: "<<package_name
497 <<" - Shared library ["<<libname
498 <<"] was build with bbtk version "
500 <<" but the current program runs with version "
501 <<bbtk::GetVersion()<<" : cannot load it. You have to recompile your BBTK-Package."<<std::endl);
505 // Loads the Package get function
506 std::string getpackname(package_name);
507 getpackname += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_FUNCTION_NAME);
508 getpack = (DLGetPackageFunction)(GetProcAddress(handler, getpackname.c_str()));
511 FreeLibrary(handler);
512 bbtkMessage("package",0,
513 "BBTK ..ERROR.. loading shared library ["<<libname
514 <<"] is not a valid bbtk package."
515 <<" Symbol ["<<getpackname<<"] not found"<< std::endl);
519 // Loads the Package delete function
520 std::string delpackname(package_name);
521 delpackname += BBTK_STRINGIFY_SYMBOL(BBTK_DEL_PACKAGE_FUNCTION_NAME);
522 delpack = (DLDeletePackageFunction)(GetProcAddress(handler, delpackname.c_str()));
525 FreeLibrary(handler);
526 bbtkMessage("package",0,
527 "BBTK ..ERROR.. loading shared library ["<<libname
528 <<"] is not a valid bbtk package."
529 <<" Symbol ["<<delpackname<<"] not found"<< std::endl);
534 bbtkError("neither __GNUC__ nor _WIN32 ?!? How did you compile ?");
539 //==========================================================================
541 //==========================================================================
542 /// Loads a package from a dynamic library
543 Package::Pointer Package::CreateFromDynamicLibrary(const std::string& libname,
544 const std::string& pkgname,
545 const std::string& path)
547 printf("EED Package::CreateFromDynamicLibrary Start \n");
548 bbtkDebugMessage("package",1,"==> Package::CreateFromDynamicLibrary("
549 <<libname<<")"<<std::endl);
551 DLGetPackageFunction gf;
552 DLDeletePackageFunction df;
553 DynamicLibraryHandler h = Package::OpenDynamicLibrary(libname,
556 if (h==0) return Package::Pointer();
557 Package::Pointer p = gf();
558 p->mDynamicLibraryHandler = h;
559 p->mDLDeletePackageFunction = df;
561 std::string separator =
562 ConfigurationFile::GetInstance().Get_file_separator ();
563 //BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
564 std::string docreldoc =
565 separator + "bbdoc" + separator + pkgname + separator + "index.html";
567 ".." + separator + ".." + docreldoc;
568 std::string doc = path + separator + ".." + separator
569 + BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
573 p->SetDocRelativeURL(reldoc);
575 bbtkDebugMessage("package",2,"<== Package::CreateFromDynamicLibrary("
576 <<libname<<") .. OK"<<std::endl);
577 printf("EED Package::CreateFromDynamicLibrary End \n");
580 //==========================================================================
585 //==========================================================================
586 /// UnLoads the package dynamic library (if any)
587 void Package::UnLoadDynamicLibrary(Package::WeakPointer pack, bool doit)
589 if (pack.expired() || (!pack.lock()->mDynamicLibraryHandler))
592 std::string packname = pack.lock()->GetName();
593 bbtkDebugMessage("package",5,"==> Package::UnLoadDynamicLibrary('"
597 if (!pack.lock()->GetDescriptorMap().empty())
600 bbtkDebugMessage("package",5," Package not empty ... abort"
604 bbtkGlobalError("Package::UnLoadDynamicLibrary('"<<packname<<") : "
605 <<"DescriptorMap not empty "
606 <<BBTK_INTERNAL_ERROR_MESSAGE);
610 if (pack.use_count()!=1)
612 bbtkGlobalError("Package::UnLoadDynamicLibrary('"<<packname<<") : "
613 <<"empty dl package with external refs"
614 <<BBTK_INTERNAL_ERROR_MESSAGE);
620 bbtkDebugMessage("package",5,"==> dynamic library for package '"
621 <<packname<<"' closed"
626 mReleasedDynamicallyLoadedPackages.insert(pack);
627 bbtkDebugMessage("package",1,"==> package '"<<packname
628 <<"' put in the 'to unload' list"
632 bbtkDebugMessage("package",5,"<== Package::UnLoadDynamicLibrary('"
636 //==========================================================================
638 //==========================================================================
639 /// UnLoads released packages that were loaded dynamically
640 /// see UnLoadDynamicLibrary and ReleaseBlackBoxDescriptor
641 void Package::UnLoadReleasedDynamicallyLoadedPackages()
643 bbtkDebugMessage("package",5,"==> Package::UnLoadReleasedDynamicallyLoadedPackages()"<<std::endl);
645 std::set<Package::WeakPointer>::iterator i;
648 if(mReleasedDynamicallyLoadedPackages.size()>0){
649 for (i=mReleasedDynamicallyLoadedPackages.begin();
650 i!=mReleasedDynamicallyLoadedPackages.end();
653 if (!i->expired()) UnLoad(*i);
657 bbtkDebugMessage("package",5,"<== Package::UnLoadReleasedDynamicallyLoadedPackages()"<<std::endl);
659 //==========================================================================
661 //==========================================================================
662 void Package::UnLoad(Package::WeakPointer pack)
664 std::string packname = pack.lock()->GetName();
665 bbtkDebugMessage("package",6,"==> Package::UnLoad("<<packname<<")"<<std::endl);
667 Package* p = pack.lock().get();
669 DynamicLibraryHandler h = p->mDynamicLibraryHandler;
671 // deletes the package
672 p->mDLDeletePackageFunction();
674 // closes the dl handler
675 #if defined(__GNUC__)
678 printf("EED Package::UnLoad ERROR %s\n", packname.c_str() );
679 bbtkWarning("Failed to close dynamic library for package '"<<packname
683 #elif defined(_WIN32)
687 bbtkDebugMessage("package",1,"==> dynamic library for package '"
688 <<packname<<"' closed"
690 bbtkDebugMessage("package",6," ... dynamic library unloaded"<<std::endl);
692 //==========================================================================
694 bool Package::ifBoxExist( std::string type)
697 DescriptorMapType::const_iterator i = mDescriptorMap.find(type);
698 if (i != mDescriptorMap.end())
705 //==========================================================================
706 /// Creates an instance of a black box of type <type> with name <name>
707 BlackBox::Pointer Package::NewBlackBox(const std::string& type,
708 const std::string& name) const
710 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<">::NewBlackBox(\""<<type<<"\",\""<<name<<"\")"<<bbtkendl);
712 DescriptorMapType::const_iterator i = mDescriptorMap.find(type);
713 if (i == mDescriptorMap.end())
715 bbtkDebugDecTab("kernel",8);
716 return BlackBox::Pointer();
718 BlackBox::Pointer bb =i->second->NewBlackBox(name);
719 bbtkDebugDecTab("kernel",8);
723 //==========================================================================
727 //==========================================================================
728 /// Creates an instance of an adaptor of input type <typein> and
729 /// output type <typeout> with name <name>
730 BlackBox::Pointer Package::NewAdaptor(const DataInfo& typein,
731 const DataInfo& typeout,
732 const std::string& name) const
734 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
738 <<name<<"\")"<<bbtkendl);
740 AdaptorKey key(typein,typeout,
741 BlackBoxDescriptor::DEFAULT_ADAPTOR);
742 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
743 if (i == mAdaptorMap.end())
745 bbtkDebugDecTab("kernel",8);
746 return BlackBox::Pointer();
748 BlackBox::Pointer bb =i->second.lock()->NewBlackBox(name);
749 bbtkDebugDecTab("kernel",8);
753 //==========================================================================
755 //==========================================================================
756 /// Creates an instance of an adaptor of input type <typein> and
757 /// output type <typeout> with name <name>
758 BlackBox::Pointer Package::NewWidgetAdaptor(const DataInfo& typein,
759 const DataInfo& typeout,
760 const std::string& name) const
762 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
763 ">::NewWidgetAdaptor("
766 <<name<<"\")"<<bbtkendl);
768 AdaptorKey key(typein,typeout,
769 BlackBoxDescriptor::DEFAULT_GUI);
770 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
771 if (i == mAdaptorMap.end())
773 bbtkDebugDecTab("kernel",8);
774 return BlackBox::Pointer();
776 BlackBox::Pointer bb =i->second.lock()->NewBlackBox(name);
777 bbtkDebugDecTab("kernel",8);
781 //==========================================================================
785 //==========================================================================
786 /// Returns true is the package contains
787 /// an adaptor of input type <typein> and
788 /// output type <typeout>
789 /// If successfull then adaptor contains the black box type name
790 bool Package::FindWidgetAdaptor(const DataInfo& typein,
791 const DataInfo& typeout,
792 std::string& adaptor) const
794 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
795 ">::FindWidgetAdaptor("
797 <<typeout<<")"<<bbtkendl);
799 AdaptorKey key(/*typein*/
800 DataInfo(typeid(void),""),
802 BlackBoxDescriptor::DEFAULT_GUI);
803 // First try to find a single widget adaptor
804 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
805 if (i == mAdaptorMap.end())
807 bbtkDebugDecTab("kernel",8);
810 adaptor = i->second.lock()->GetTypeName();
811 bbtkDebugDecTab("kernel",8);
815 //==========================================================================
819 //==========================================================================
820 /// Returns true is the package contains
821 /// an adaptor of input type <typein> and
822 /// output type <typeout>
823 /// If successfull then adaptor contains the black box type name
824 bool Package::FindAdaptor(const DataInfo& typein,
825 const DataInfo& typeout,
826 std::string& adaptor) const
828 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
831 <<typeout<<")"<<bbtkendl);
833 AdaptorKey key(typein,typeout,
834 BlackBoxDescriptor::DEFAULT_ADAPTOR);
835 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
836 if (i == mAdaptorMap.end())
838 bbtkDebugDecTab("kernel",8);
841 adaptor = i->second.lock()->GetTypeName();
842 bbtkDebugDecTab("kernel",8);
846 //==========================================================================
849 //==========================================================================
850 /// Registers a black box descriptor in the package
851 bool Package::Register(BlackBoxDescriptor::Pointer d)
853 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<">::Register(\""<<d->GetTypeName()<<"\")"<<std::endl);
855 DescriptorMapType::iterator i = mDescriptorMap.find(d->GetTypeName());
856 if (i!=mDescriptorMap.end())
858 bbtkWarning("Package<"<<GetName()<<"> : Trying to register box type <"
859 <<d->GetTypeName()<<"> which is already in the package");
863 mDescriptorMap[d->GetTypeName()] = d;
865 d->SetPackage(GetThisPointer<Package>());
867 // If it is a default adaptor, also register it in the adaptors map
868 if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_ADAPTOR )
870 bbtkDebugMessage("kernel",8,"Package<"<<GetName()<<">::Register(\""<<d->GetTypeName()<<"\") : The box is an adaptor, inserting it in adaptors map ..."<<std::endl);
872 TypeInfo typein = d->GetInputDescriptor("In")->GetTypeInfo();
873 TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
874 DataInfo infoin(typein,d->GetInputDescriptor("In")->GetNature());
875 DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
876 AdaptorKey key(infoin,infoout,d->GetKind());
878 AdaptorMapType::const_iterator i;
879 i = mAdaptorMap.find(key);
880 if (i == mAdaptorMap.end())
882 mAdaptorMap[key] = d;
884 // If already an adaptor registered : error
887 if (i->second.lock()->GetTypeName() != d->GetTypeName())
889 bbtkError("Package <"<<GetName()<<
890 "> : trying to register black box <"
892 <<"> as default adaptor but there is already a default adaptor registered (<"
893 <<i->second.lock()->GetTypeName()<<">)");
897 // If it is a default adaptor, also register it in the adaptors map
898 else if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_GUI)
900 bbtkDebugMessage("kernel",8,"Package<"<<GetName()<<">::Register(\""<<d->GetTypeName()<<"\") : The box is a widget adaptor, inserting it in adaptors map ..."<<std::endl);
902 TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
903 DataInfo infoin(typeid(void),"");
904 DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
905 AdaptorKey key(infoin,infoout,d->GetKind());
907 AdaptorMapType::const_iterator i;
908 i = mAdaptorMap.find(key);
909 if (i == mAdaptorMap.end())
911 mAdaptorMap[key] = d;
913 // If already an adaptor registered : error
916 if (i->second.lock()->GetTypeName() != d->GetTypeName())
918 bbtkError("Package <"<<GetName()<<
919 "> : trying to register black box <"
921 <<"> as default widget adaptor but there is already a default adaptor registered (<"
922 <<i->second.lock()->GetTypeName()<<">)");
928 bbtkDebugDecTab("kernel",8);
932 //==========================================================================
934 //===================================================================
935 void Package::Check() const
937 bbtkMessage("debug",1,"****** Checking Package "<<(void*)this
938 <<" ["<<GetName()<<"]"<<std::endl);
939 DescriptorMapType::const_iterator i;
940 for (i=mDescriptorMap.begin();
941 i!=mDescriptorMap.end();
944 i->second->Check(true);
946 bbtkMessage("debug",1,"****** Checking Package "<<(void*)this
947 <<" ["<<GetName()<<"] ... OK"<<std::endl);
949 //===================================================================
952 //==========================================================================
953 /// Changes the name of a black box type
954 void Package::ChangeDescriptorName( const std::string& oldname, const std::string& newname )
956 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()
957 <<">::ChangeDescriptorName(\""<<oldname
958 <<"\",\""<<newname<<"\")"<<std::endl);
959 // Looking into the bb map
960 DescriptorMapType::iterator i = mDescriptorMap.find(oldname);
961 if (i == mDescriptorMap.end())
963 bbtkDebugDecTab("kernel",8);
964 bbtkError("ChangeDescriptorName : The package <"<<GetName()<<"> does not contains the black box <"<<oldname<<">");
967 i->second->SetTypeName(newname);
968 mDescriptorMap[newname] = i->second;
969 mDescriptorMap.erase(i);
971 bbtkDebugDecTab("kernel",8);
973 //==========================================================================
977 //==========================================================================
978 void Package::PrintHelpListDescriptors(bool description, bool adaptors) const
980 unsigned int lmax = 0;
981 std::vector<std::string> names;
982 std::vector<std::string> kinds;
983 std::vector<std::string> descrs;
985 DescriptorMapType::const_iterator i;
986 for (i=mDescriptorMap.begin();
987 i!=mDescriptorMap.end();
991 ( i->second->GetKind() == BlackBoxDescriptor::STANDARD) )
993 std::string name(" ");
994 name += i->second->GetTypeName();
995 names.push_back(name);
998 if ( i->second->GetKind() == BlackBoxDescriptor::ADAPTOR )
1000 kind = std::string("[A]");
1002 else if ( i->second->GetKind() ==
1003 BlackBoxDescriptor::DEFAULT_ADAPTOR )
1005 kind = std::string("[DA]");
1007 kinds.push_back(kind);
1009 unsigned int l = name.size()+kind.size();
1010 if (l>lmax) lmax = l;
1016 descr += i->second->GetDescription();
1018 descrs.push_back(descr);
1024 offs.append(lmax+3,' ');
1025 std::vector<std::string>::iterator ni,ci,di;
1026 for (ni = names.begin(), ci = kinds.begin(), di = descrs.begin();
1027 ni != names.end(); ++ni, ++ci, ++di)
1030 space.append(lmax - ni->size() - ci->size(),' ');
1031 bbtkMessage("help",1,*ni << space << *ci );
1033 unsigned int dmax = 75 - lmax;
1034 // while (d.size() > dmax )
1037 bbtkMessage("help",1,d.substr(0,dmax) << "..." << std::endl);
1039 bbtkMessage("help",1,d << std::endl);
1040 // d = d.substr(dmax,d.size());
1045 //==========================================================================
1047 //==========================================================================
1048 /// Displays the list of adaptors of the package
1049 void Package::PrintHelpListAdaptors(bool description) const
1051 DescriptorMapType::const_iterator i;
1052 for (i=mDescriptorMap.begin();
1053 i!=mDescriptorMap.end();
1056 if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD )
1058 bbtkMessage("help",1,
1059 " "<<i->second->GetTypeName());
1060 if ( i->second->GetKind() ==
1061 BlackBoxDescriptor::DEFAULT_ADAPTOR )
1063 bbtkMessage("help",1,
1068 bbtkMessage("help",1,
1069 " : "<<i->second->GetDescription());
1072 bbtkMessage("help",1,std::endl);
1076 AdaptorMapType::const_iterator i;
1077 for (i=mAdaptorMap.begin();
1078 i!=mAdaptorMap.end();
1081 bbtkMessage("help",1,
1082 " "<<i->second->GetTypeName());
1085 bbtkMessage("help",1,
1086 " : "<<i->second->GetDescription());
1089 bbtkMessage("help",1,std::endl);
1093 //==========================================================================
1095 //==========================================================================
1096 /// Prints help on a black box descriptor
1097 void Package::PrintHelpDescriptor(const std::string& name, bool full) const
1099 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()
1100 <<">::PrintHelpDescriptor(\""
1101 <<name<<"\")"<<bbtkendl);
1103 DescriptorMapType::const_iterator i = mDescriptorMap.find(name);
1104 if (i == mDescriptorMap.end())
1106 bbtkDebugDecTab("kernel",8);
1107 bbtkError("The package <"<<GetName()<<"> does not contains the black box <"<<name<<">");
1109 // bbtkMessage("help",1,"["<<GetName()<<"] ");
1110 i->second->GetHelp(full);
1111 bbtkDebugDecTab("kernel",8);
1114 //==========================================================================
1117 //==========================================================================
1118 /// Returns true iff the package contains the box of name boxname
1119 bool Package::ContainsDescriptor(const std::string& name) const
1121 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()
1122 <<">::ContainsDescriptor(\""
1123 <<name<<"\")"<<bbtkendl);
1125 DescriptorMapType::const_iterator i = mDescriptorMap.find(name);
1126 if (i == mDescriptorMap.end())
1128 bbtkDebugDecTab("kernel",8);
1131 bbtkDebugDecTab("kernel",8);
1134 //==========================================================================
1138 //==========================================================================
1139 void Package::CreateHtmlPage(const std::string& filename,
1140 const std::string& caller,
1141 const std::string& source,
1142 const std::string& custom_header,
1143 const std::string& custom_title,
1146 bool relative_link ) const
1148 bbtkDebugMessageInc("kernel",9,"Package<"<<GetName()<<">::CreateHtmlPage(\""
1149 <<filename<<"\")"<<bbtkendl);
1151 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1133"<<std::endl;
1153 //---------------------
1156 s.open(filename.c_str());
1159 bbtkError("Package "<<GetName()<<" : CreateHtmlPage : could not open file '"<<filename<<"'");
1162 //----------------------
1164 std::string title = "BBTK Package "+GetName()+" "+GetVersion();
1166 if (custom_title.length() != 0) title = custom_title;
1168 s << "<html lang=\"en\">\n";
1170 s << "<title>" << title << "</title>\n";
1171 s << "<meta http-equiv=\"Content-Type\" content=\"text/html\">\n";
1172 s << "<meta name=\"description\" content=\""<<title<<"\">\n";
1173 s << "<meta name=\"generator\" content=\"\">\n";
1174 s << "<link title=\"Top\" rel=\"top\" href=\"#Top\">\n";
1175 //<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
1176 s << "<meta http-equiv=\"Content-Style-Type\" content=\"text/css\"><style type=\"text/css\"><!--\n";
1177 s << "pre.display { font-family:inherit }\n";
1178 s << "pre.format { font-family:inherit }\n";
1179 s << "pre.smalldisplay { font-family:inherit; font-size:smaller }\n";
1180 s << "pre.smallformat { font-family:inherit; font-size:smaller }\n";
1181 s << "pre.smallexample { font-size:smaller }\n";
1182 s << "pre.smalllisp { font-size:smaller }\n";
1183 s << "span.sc { font-variant:small-caps }\n";
1184 s << "span.roman { font-family:serif; font-weight:normal; } \n";
1185 s << "span.sansserif { font-family:sans-serif; font-weight:normal; }\n";
1186 s << "--></style>\n";
1188 //----------------------
1190 //----------------------
1193 s << "<a name=\"Top\"></a>\n";
1195 //----------------------
1197 if ( custom_header.length() != 0)
1199 if ( custom_header != "none" )
1202 in.open(custom_header.c_str());
1205 bbtkError("Could not open file \""<<custom_header<<"\"");
1210 in.getline(buffer,512);
1211 std::string line(buffer);
1218 s << "<object data=\"" << custom_header
1219 << "\" type = \"text/html\"\"style=\"width: 1200px; height: 400px;\"> Warning: "
1220 << custom_header <<" could not be embedded.</object>\n";
1229 s << "<h1 class=\"settitle\">"<<title<<"</h1>\n";
1230 s << "<p><TABLE cellspacing=0 cellpadding=3>\n";
1231 s << "<TR><TD style='vertical-align: top;'><b> Description </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1232 << GetDescription() << "</TD></TR>\n";
1233 s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1234 << GetAuthor() << "</TD></TR>\n";
1235 s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1236 << GetCategory() << "</TD></TR>\n";
1237 s << "<TR><TD style='vertical-align: top;'><b> Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1238 << GetVersion() << "</TD></TR>\n";
1239 s << "<TR><TD style='vertical-align: top;'><b> bbtk Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1240 << bbtk::GetVersion() << "</TD></TR>\n";
1243 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1225"<<std::endl;
1244 //-------------------
1245 // Table of contents
1247 // s << "<div class=\"contents\">\n";
1248 s << "<p><b> Black Boxes : </b>\n";
1251 s << "<p><TABLE cellspacing=0 cellpadding=3>\n";
1253 DescriptorMapType::const_iterator i;
1254 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1236"<<std::endl;
1255 for (i=mDescriptorMap.begin(); i!=mDescriptorMap.end(); ++i) {
1256 if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD)
1259 std::string name = i->second->GetTypeName();
1260 Utilities::html_format(name);
1261 std::string descr = i->second->GetDescription();
1262 //Utilities::html_format(descr);
1263 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1246"<<std::endl;
1265 s << "<TD style='vertical-align: top;'>";
1266 s << " <a name=\"toc_"<<name
1267 <<"\" href=\"#"<<name<<"\">"
1270 s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
1279 //-------------------
1281 if (mAdaptorMap.size()>0)
1283 // s << "<div class=\"contents\">\n";
1284 s << "<p><b> Adaptors : </b>\n";
1286 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1268"<<std::endl;
1287 // DescriptorMapType::const_iterator i;
1288 s << "<p><TABLE cellspacing=0 cellpadding=3>\n";
1289 for (i=mDescriptorMap.begin(); i!=mDescriptorMap.end();++i)
1291 if ( i->second->GetKind() == BlackBoxDescriptor::STANDARD)
1294 std::string name = i->second->GetTypeName();
1295 Utilities::html_format(name);
1296 std::string descr = i->second->GetDescription();
1299 s << "<TD style='vertical-align: top;'>";
1300 s << " <a name=\"toc_"<<name
1301 <<"\" href=\"#"<<name<<"\">"
1304 s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
1314 // s << "<div class=\"node\">\n";
1316 // s << "<p><hr>\n";
1317 // s << "<a name=\"Top\"></a>\n";
1318 // s << "Top: <a rel=\"top\" accesskey=\"t\" href=\"#Top\">Top</a>\n";
1319 // s << "Previous: <a rel="previous" accesskey="p" href="#dir">(dir)</a>,
1320 // s << "Up: <a rel="up" accesskey="u" href="#dir">(dir)</a>
1324 //----------------------
1327 //-------------------
1328 // Computes output directory from filename to pass it to
1329 // BlackBoxDescriptor::InsertHtmlHelp
1332 std::string::size_type slash_position = filename.find_last_of("/\\");
1335 if (slash_position != std::string::npos) {
1336 if (slash_position == 0)
1338 dir = filename.substr(0,slash_position);
1341 for (i=mDescriptorMap.begin();
1342 i!=mDescriptorMap.end();
1345 i->second->InsertHtmlHelp(s,detail,level,dir,relative_link);
1348 //----------------------
1353 ptm = gmtime ( &rawtime );
1356 s << "Automatically generated by <b>"<<caller<<"</b> "//from <b>"
1359 << ptm->tm_mday << "/" << ptm->tm_mon << "/" << ptm->tm_year+1900
1360 << " - " << ptm->tm_hour << ":" << ptm->tm_min << " GMT\n";
1361 s << "</body></html>\n";
1363 //----------------------
1366 bbtkDebugDecTab("kernel",9);
1368 //==========================================================================
1370 //==========================================================================
1371 std::string Package::GetObjectName() const
1373 return std::string("Package '")+mName+std::string("'");
1375 //==========================================================================
1377 //==========================================================================
1378 std::string Package::GetObjectInfo() const
1380 std::stringstream i;
1381 i << " - "<<mDescriptorMap.size() << " boxes" << std::endl;
1382 if (mDynamicLibraryHandler)
1384 i<< " - Loaded from dynamic library"<<std::endl;
1388 //==========================================================================
1391 //==========================================================================
1392 size_t Package::GetObjectSize() const
1394 size_t s = Superclass::GetObjectSize();
1395 s += Package::GetObjectInternalSize();
1398 //==========================================================================
1399 //==========================================================================
1400 size_t Package::GetObjectInternalSize() const
1402 size_t s = sizeof(Package);
1405 //==========================================================================
1406 //==========================================================================
1407 size_t Package::GetObjectRecursiveSize() const
1409 size_t s = Superclass::GetObjectRecursiveSize();
1410 s += Package::GetObjectInternalSize();
1412 DescriptorMapType::const_iterator i;
1413 for (i = mDescriptorMap.begin(); i!=mDescriptorMap.end(); ++i )
1415 s += i->second->GetObjectRecursiveSize();
1419 //==========================================================================
1420 void Package::GetBoxesInside(NodeTreeC& tree, int cont)
1422 DescriptorMapType::const_iterator i;
1423 std::cout<<"*********a********"<<std::endl;
1424 for (i=mDescriptorMap.begin(); i!=mDescriptorMap.end(); ++i)
1426 i->second->GetBoxesInside(tree, cont);
1427 std::cout<<"*****************"<<std::endl;
1430 //==========================================================================
1431 //==========================================================================
1432 std::set<Package::WeakPointer>
1433 Package::mReleasedDynamicallyLoadedPackages;
1434 //==========================================================================