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 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"
115 //==========================================================================
119 //==========================================================================
123 bbtkDebugMessage("object",2,"==> ~Package(\""<<mName<<"\")"<<bbtkendl);
125 //==========================================================================
128 //==========================================================================
129 void PackageReleaseBlackBoxDescriptorInternal(Package::WeakPointer pack,
130 const std::string& descname)
132 // Try to release descriptor
133 std::string packname = pack.lock()->GetName();
135 bbtkDebugMessage("package",5,"--- Releasing descriptor '"
136 <<packname<<"::"<<descname<<"'"<<bbtkendl);
139 Package::DescriptorMapType::iterator desc =
140 pack.lock()->GetDescriptorMap().find(descname);
141 if (desc == pack.lock()->GetDescriptorMap().end())
143 bbtkDebugMessage("package",5,
144 " Descriptor has already been released"
148 // bbtkDebugMessage("package",3,
149 // " Trying unreferencing it ... "<<std::endl);
150 BlackBoxDescriptor::WeakPointer pdesc = desc->second;
151 desc->second.reset();
152 // if it is dead : remove it
155 bbtkDebugMessage("package",2," ==> '"<<packname<<"::"<<descname<<"' Descriptor expired"<<bbtkendl);
158 bbtkDebugMessage("package",2,
159 " ... and caused its package death"
163 desc = pack.lock()->GetDescriptorMap().find(descname);
164 if (desc != pack.lock()->GetDescriptorMap().end()) pack.lock()->GetDescriptorMap().erase(desc);
165 } else { //pdesc.expired
166 bbtkDebugMessage("package",5," ... Descriptor still alive ("
167 <<pdesc.use_count()<<" refs)"
169 pack.lock()->GetDescriptorMap()[descname] = pdesc.lock();
172 //==========================================================================
175 //==========================================================================
177 void Package::Release(Package::WeakPointer pack)
179 std::string packname = pack.lock()->mName;
180 bbtkDebugMessage("package",1,"==> Package::Release('"<<
181 packname<<"')"<<bbtkendl);
183 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
184 long ndesc = pack.lock()->GetDescriptorMap().size();
185 long nrefs = pack.use_count();
187 bbtkDebugMessage("package",5," "<<nrefs<<" refs / "
188 <<ndesc<<" descr / dyn="
191 // A package is "free" from any external reference iff :
192 // i) It is not dynamically loaded and nrefs == ndesc
193 // (each desc references its package) or
194 // ii) It is dynamically loaded and nrefs == ndesc + 1
195 // (A dynamic library holds a static pointer on the package it contains
196 // which is allocated when the PACKAGENAMEGetPackage() func is called,
197 // and descallocated (reset) by PACKAGENAMEDeletePackage())
198 if (nrefs == ndesc + dyn)
200 bbtkDebugMessage("package",5,
201 " -> No more external ref : checking descriptors"
203 // We must take care that removing refs on descriptors
204 // can lead to their deletion which can in turn unref
205 // internal boxes which can release their descriptors hence
206 // call Package::ReleaseBlackBoxDescriptor
207 // As a consequence during descriptors release :
208 // 1) The map can change dynamically : we cannot iterate over it
209 // as any iterator can become invalid
210 // 2) The package can auto-destruct : we must test its existence
211 // after each release
212 // We must also take care of not locking the package pointer
213 // or any ref count check in Package::ReleaseBlackBoxDescriptor
216 // The list of descriptors names at start
217 std::vector<std::string> descnamelist;
218 DescriptorMapType::iterator i;
219 for (i=pack.lock()->mDescriptorMap.begin();
220 i!= pack.lock()->mDescriptorMap.end();
222 descnamelist.push_back(i->first);
224 // Iterator over the initial names
225 std::vector<std::string>::iterator descname;
226 for (descname=descnamelist.begin();
227 descname!=descnamelist.end();
230 // Is package still alive ?
233 bbtkDebugMessage("package",1,"--- Package::Release('"<<
235 <<"') : package expired during release : bailing out"<<bbtkendl);
240 BlackBoxDescriptor::Pointer desc = pack.lock()->mDescriptorMap[*descname];
241 if ( (dyn==0) || (boost::dynamic_pointer_cast<ComplexBlackBoxDescriptor>(desc)) )
243 PackageReleaseBlackBoxDescriptorInternal(pack,*descname);
246 PackageReleaseBlackBoxDescriptorInternal(pack,*descname);
252 UnLoadDynamicLibrary(pack);
253 // Unload orphan dl packages
254 Package::UnLoadReleasedDynamicallyLoadedPackages();
258 #ifdef BBTK_COMPILE_DEBUG_MESSAGES
260 bbtkDebugMessage("package",2,"<== Package::Release('"<<
261 packname<<"')"<<bbtkendl);
265 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
266 long ndesc = pack.lock()->GetDescriptorMap().size();
267 long nrefs = pack.use_count();
269 bbtkDebugMessage("package",1," ... Package still alive ("
271 <<ndesc<<" descr / dyn="
272 <<dyn<<")"<<std::endl);
276 bbtkDebugMessage("package",1," ... Package has been released"
281 //==========================================================================
283 //==========================================================================
284 /// "Releases" the package
285 /// Signals the package that it can free the given descriptor
286 /// if they are no more used and free itself if it is no
288 /// Note : Any non-weak pointer on the package must have been freed
289 void Package::ReleaseBlackBoxDescriptor(Package::WeakPointer pack,
290 BlackBoxDescriptor::WeakPointer descr)
292 std::string packname = pack.lock()->mName;
293 std::string dname = descr.lock()->GetTypeName();
294 bbtkDebugMessage("package",3,"==> Package::ReleaseBlackBoxDescriptor('"<<
295 packname<<"','"<<dname<<"') : refs="
296 <<descr.use_count()<<bbtkendl);
298 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
299 long ndesc = pack.lock()->GetDescriptorMap().size();
300 long nrefs = pack.use_count();
302 bbtkDebugMessage("package",5," "<<nrefs<<" refs / "
303 <<ndesc<<" descr / dynamically loaded = "
306 // A package is "free" from any external reference iff :
307 // i) It is not dynamically loaded and nrefs == ndesc
308 // (each desc references its package) or
309 // ii) It is dynamically loaded and nrefs == ndesc + 1
310 // (A dynamic library holds a static pointer on the package it contains
311 // which is allocated when the PACKAGENAMEGetPackage() func is called,
312 // and descallocated (reset) by PACKAGENAMEDeletePackage())
313 if (nrefs == ndesc + dyn)
318 PackageReleaseBlackBoxDescriptorInternal(pack,dname);
320 PackageReleaseBlackBoxDescriptorInternal(pack,dname);
324 // If the package is released and dynamically loaded
325 // then put it in the static list mReleasedDynamicallyLoadedPackages
326 UnLoadDynamicLibrary(pack,false);
328 bbtkDebugMessage("package",4,"<== Package::ReleaseBlackBoxDescriptor('"<<
329 packname<<"','"<<dname<<"'): refs="
330 <<descr.use_count()<<bbtkendl);
334 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
335 long ndesc = pack.lock()->GetDescriptorMap().size();
336 long nrefs = pack.use_count();
338 bbtkDebugMessage("package",3," ... Package still alive ("
340 <<ndesc<<" descr / dyn="
341 <<dyn<<")"<<std::endl);
345 bbtkDebugMessage("package",3," ... Package has been released"
350 //==========================================================================
352 //==========================================================================
353 /// Opens a dynamic library which contains a bbtk package
354 /// Returns the handler
355 /// Load the package management symbols from the lib
356 /// returns false if a problem occured hence can be used
357 /// to test that a dyn lib is a valid bbtk package lib
358 /// NB : The BBTK version exported from the library
359 /// is tested against the current bbtk version
360 DynamicLibraryHandler Package::OpenDynamicLibrary( const std::string& libname,const std::string& package_name,
361 DLGetPackageFunction& getpack, DLDeletePackageFunction& delpack)
364 printf("EED Package::OpenDynamicLibrary %s %s \n", libname.c_str(), package_name.c_str() );
366 bbtkDebugMessage("package",3,"==> Package::OpenDynamicLibrary("
367 <<libname<<")"<<std::endl);
368 #if defined(__GNUC__)
372 handler = dlopen(libname.c_str(), BBTK_RTLD_TIME | BBTK_RTLD_SCOPE );
373 // handler = dlopen(libname.c_str(), RTLD_LAZY | RTLD_LOCAL );
377 bbtkMessage("package",0,
378 "BBTK ..ERROR.. loading could not open shared library [" <<libname<<"] : "
379 <<dlerror() << std::endl);
383 bbtkDebugMessage("package",3,"* Shared lib ["<<libname<<"] open"<<std::endl);
385 // Loads the Package bbtk version function
386 std::string getvername(package_name);
387 getvername += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME);
388 DLGetPackageBBTKVersionFunction getbbtkversion = (DLGetPackageBBTKVersionFunction)(dlsym(handler,getvername.c_str()));
391 bbtkDebugMessage("package",3,"***"<<std::endl);
392 bbtkMessage("package",0,
393 "BBTK ..ERROR.. loading shared library ["<<libname
394 <<"] is not a valid bbtk package."
395 <<" Symbol ["<<getvername<<"] :"<<dlerror()<< std::endl);
400 bbtkDebugMessage("package",3,"* Symbol ["<<getvername
401 <<"] found"<<std::endl);
404 if (getbbtkversion() != bbtk::GetVersion())
406 bbtkMessage("package",0,
407 "BBTK ..ERROR.. loading: "<<package_name
408 <<" - Shared library ["<<libname
409 <<"] was build with bbtk version "
411 <<" but the current program runs with version "
412 <<bbtk::GetVersion()<<" : cannot load it. You have to recompile your BBTK-Package."<<std::endl);
418 bbtkDebugMessage("package",3,"* Package bbtk version '"<<getbbtkversion()<<"' matches"<<std::endl);
419 // Loads the Package get function
420 std::string getpackname(package_name);
421 getpackname += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_FUNCTION_NAME);
422 getpack = (DLGetPackageFunction)(dlsym(handler, getpackname.c_str()));
425 bbtkMessage("package",0,
426 "BBTK ..ERROR.. loading shared library ["<<libname
427 <<"] is not a valid bbtk package."
428 <<" Symbol ["<<getpackname<<"] :"<<dlerror()<< std::endl);
433 bbtkDebugMessage("package",3,"* Symbol ["<<getpackname<<"] found"<<std::endl);
434 // Loads the Package delete function
436 std::string delpackname(package_name);
437 delpackname += BBTK_STRINGIFY_SYMBOL(BBTK_DEL_PACKAGE_FUNCTION_NAME);
438 delpack = (DLDeletePackageFunction)(dlsym(handler, delpackname.c_str()));
441 bbtkMessage("package",0,
442 "BBTK ..ERROR.. loading shared library ["<<libname
443 <<"] is not a valid bbtk package."
444 <<" Symbol ["<<delpackname<<"] :"<<dlerror()<< std::endl);
448 bbtkDebugMessage("package",3,"* Symbol ["<<delpackname<<"] found"<<std::endl);
449 #elif defined(_WIN32)
455 handler = LoadLibrary(libname.c_str());
458 bbtkMessage("package",0,
459 "BBTK ..ERROR.. could not open shared library [" <<libname<<"]"
461 DWORD dwErrorCode = 0;
462 dwErrorCode = GetLastError();
463 bbtkMessage("package",2,
464 "Windows Error: [" << dwErrorCode <<"]"
470 // Loads the Package bbtk version function
471 std::string getvername(package_name);
472 getvername += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME);
473 DLGetPackageBBTKVersionFunction getbbtkversion = (DLGetPackageBBTKVersionFunction)(GetProcAddress(handler, getvername.c_str()));
477 FreeLibrary(handler);
478 bbtkMessage("package",0,
479 "BBTK ..ERROR.. loading shared library ["<<libname
480 <<"] is not a valid bbtk package."
481 <<" Symbol ["<<getbbtkversion<<"] not found"<< std::endl);
486 if (getbbtkversion() != bbtk::GetVersion())
488 FreeLibrary(handler);
489 bbtkMessage("package",0,
490 "BBTK ..ERROR.. loading: "<<package_name
491 <<" - Shared library ["<<libname
492 <<"] was build with bbtk version "
494 <<" but the current program runs with version "
495 <<bbtk::GetVersion()<<" : cannot load it. You have to recompile your BBTK-Package."<<std::endl);
499 // Loads the Package get function
500 std::string getpackname(package_name);
501 getpackname += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_FUNCTION_NAME);
502 getpack = (DLGetPackageFunction)(GetProcAddress(handler, getpackname.c_str()));
505 FreeLibrary(handler);
506 bbtkMessage("package",0,
507 "BBTK ..ERROR.. loading shared library ["<<libname
508 <<"] is not a valid bbtk package."
509 <<" Symbol ["<<getpackname<<"] not found"<< std::endl);
513 // Loads the Package delete function
514 std::string delpackname(package_name);
515 delpackname += BBTK_STRINGIFY_SYMBOL(BBTK_DEL_PACKAGE_FUNCTION_NAME);
516 delpack = (DLDeletePackageFunction)(GetProcAddress(handler, delpackname.c_str()));
519 FreeLibrary(handler);
520 bbtkMessage("package",0,
521 "BBTK ..ERROR.. loading shared library ["<<libname
522 <<"] is not a valid bbtk package."
523 <<" Symbol ["<<delpackname<<"] not found"<< std::endl);
528 bbtkError("neither __GNUC__ nor _WIN32 ?!? How did you compile ?");
533 //==========================================================================
535 //==========================================================================
536 /// Loads a package from a dynamic library
537 Package::Pointer Package::CreateFromDynamicLibrary(const std::string& libname,
538 const std::string& pkgname,
539 const std::string& path)
541 bbtkDebugMessage("package",1,"==> Package::CreateFromDynamicLibrary("
542 <<libname<<")"<<std::endl);
544 DLGetPackageFunction gf;
545 DLDeletePackageFunction df;
546 DynamicLibraryHandler h = Package::OpenDynamicLibrary(libname,
549 if (h==0) return Package::Pointer();
550 Package::Pointer p = gf();
551 p->mDynamicLibraryHandler = h;
552 p->mDLDeletePackageFunction = df;
554 std::string separator =
555 ConfigurationFile::GetInstance().Get_file_separator ();
556 //BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
557 std::string docreldoc =
558 separator + "bbdoc" + separator + pkgname + separator + "index.html";
560 ".." + separator + ".." + docreldoc;
561 std::string doc = path + separator + ".." + separator
562 + BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
566 p->SetDocRelativeURL(reldoc);
568 bbtkDebugMessage("package",2,"<== Package::CreateFromDynamicLibrary("
569 <<libname<<") .. OK"<<std::endl);
572 //==========================================================================
577 //==========================================================================
578 /// UnLoads the package dynamic library (if any)
579 void Package::UnLoadDynamicLibrary(Package::WeakPointer pack, bool doit)
581 if (pack.expired() || (!pack.lock()->mDynamicLibraryHandler))
584 std::string packname = pack.lock()->GetName();
585 bbtkDebugMessage("package",5,"==> Package::UnLoadDynamicLibrary('"
589 if (!pack.lock()->GetDescriptorMap().empty())
592 bbtkDebugMessage("package",5," Package not empty ... abort"
596 bbtkGlobalError("Package::UnLoadDynamicLibrary('"<<packname<<") : "
597 <<"DescriptorMap not empty "
598 <<BBTK_INTERNAL_ERROR_MESSAGE);
602 if (pack.use_count()!=1)
604 bbtkGlobalError("Package::UnLoadDynamicLibrary('"<<packname<<") : "
605 <<"empty dl package with external refs"
606 <<BBTK_INTERNAL_ERROR_MESSAGE);
612 bbtkDebugMessage("package",5,"==> dynamic library for package '"
613 <<packname<<"' closed"
618 mReleasedDynamicallyLoadedPackages.insert(pack);
619 bbtkDebugMessage("package",1,"==> package '"<<packname
620 <<"' put in the 'to unload' list"
624 bbtkDebugMessage("package",5,"<== Package::UnLoadDynamicLibrary('"
628 //==========================================================================
630 //==========================================================================
631 /// UnLoads released packages that were loaded dynamically
632 /// see UnLoadDynamicLibrary and ReleaseBlackBoxDescriptor
633 void Package::UnLoadReleasedDynamicallyLoadedPackages()
635 bbtkDebugMessage("package",5,"==> Package::UnLoadReleasedDynamicallyLoadedPackages()"<<std::endl);
637 std::set<Package::WeakPointer>::iterator i;
640 if(mReleasedDynamicallyLoadedPackages.size()>0){
641 for (i=mReleasedDynamicallyLoadedPackages.begin();
642 i!=mReleasedDynamicallyLoadedPackages.end();
645 if (!i->expired()) UnLoad(*i);
649 bbtkDebugMessage("package",5,"<== Package::UnLoadReleasedDynamicallyLoadedPackages()"<<std::endl);
651 //==========================================================================
653 //==========================================================================
654 void Package::UnLoad(Package::WeakPointer pack)
656 std::string packname = pack.lock()->GetName();
657 bbtkDebugMessage("package",6,"==> Package::UnLoad("<<packname<<")"<<std::endl);
659 Package* p = pack.lock().get();
661 DynamicLibraryHandler h = p->mDynamicLibraryHandler;
663 // deletes the package
664 p->mDLDeletePackageFunction();
666 // closes the dl handler
667 #if defined(__GNUC__)
670 printf("EED Package::UnLoad ERROR %s\n", packname.c_str() );
671 bbtkWarning("Failed to close dynamic library for package '"<<packname
675 #elif defined(_WIN32)
679 bbtkDebugMessage("package",1,"==> dynamic library for package '"
680 <<packname<<"' closed"
682 bbtkDebugMessage("package",6," ... dynamic library unloaded"<<std::endl);
684 //==========================================================================
686 bool Package::ifBoxExist( std::string type)
689 DescriptorMapType::const_iterator i = mDescriptorMap.find(type);
690 if (i != mDescriptorMap.end())
697 //==========================================================================
698 /// Creates an instance of a black box of type <type> with name <name>
699 BlackBox::Pointer Package::NewBlackBox(const std::string& type,
700 const std::string& name) const
702 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<">::NewBlackBox(\""<<type<<"\",\""<<name<<"\")"<<bbtkendl);
704 DescriptorMapType::const_iterator i = mDescriptorMap.find(type);
705 if (i == mDescriptorMap.end())
707 bbtkDebugDecTab("kernel",8);
708 return BlackBox::Pointer();
710 BlackBox::Pointer bb =i->second->NewBlackBox(name);
711 bbtkDebugDecTab("kernel",8);
715 //==========================================================================
719 //==========================================================================
720 /// Creates an instance of an adaptor of input type <typein> and
721 /// output type <typeout> with name <name>
722 BlackBox::Pointer Package::NewAdaptor(const DataInfo& typein,
723 const DataInfo& typeout,
724 const std::string& name) const
726 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
730 <<name<<"\")"<<bbtkendl);
732 AdaptorKey key(typein,typeout,
733 BlackBoxDescriptor::DEFAULT_ADAPTOR);
734 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
735 if (i == mAdaptorMap.end())
737 bbtkDebugDecTab("kernel",8);
738 return BlackBox::Pointer();
740 BlackBox::Pointer bb =i->second.lock()->NewBlackBox(name);
741 bbtkDebugDecTab("kernel",8);
745 //==========================================================================
747 //==========================================================================
748 /// Creates an instance of an adaptor of input type <typein> and
749 /// output type <typeout> with name <name>
750 BlackBox::Pointer Package::NewWidgetAdaptor(const DataInfo& typein,
751 const DataInfo& typeout,
752 const std::string& name) const
754 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
755 ">::NewWidgetAdaptor("
758 <<name<<"\")"<<bbtkendl);
760 AdaptorKey key(typein,typeout,
761 BlackBoxDescriptor::DEFAULT_GUI);
762 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
763 if (i == mAdaptorMap.end())
765 bbtkDebugDecTab("kernel",8);
766 return BlackBox::Pointer();
768 BlackBox::Pointer bb =i->second.lock()->NewBlackBox(name);
769 bbtkDebugDecTab("kernel",8);
773 //==========================================================================
777 //==========================================================================
778 /// Returns true is the package contains
779 /// an adaptor of input type <typein> and
780 /// output type <typeout>
781 /// If successfull then adaptor contains the black box type name
782 bool Package::FindWidgetAdaptor(const DataInfo& typein,
783 const DataInfo& typeout,
784 std::string& adaptor) const
786 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
787 ">::FindWidgetAdaptor("
789 <<typeout<<")"<<bbtkendl);
791 AdaptorKey key(/*typein*/
792 DataInfo(typeid(void),""),
794 BlackBoxDescriptor::DEFAULT_GUI);
795 // First try to find a single widget adaptor
796 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
797 if (i == mAdaptorMap.end())
799 bbtkDebugDecTab("kernel",8);
802 adaptor = i->second.lock()->GetTypeName();
803 bbtkDebugDecTab("kernel",8);
807 //==========================================================================
811 //==========================================================================
812 /// Returns true is the package contains
813 /// an adaptor of input type <typein> and
814 /// output type <typeout>
815 /// If successfull then adaptor contains the black box type name
816 bool Package::FindAdaptor(const DataInfo& typein,
817 const DataInfo& typeout,
818 std::string& adaptor) const
820 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
823 <<typeout<<")"<<bbtkendl);
825 AdaptorKey key(typein,typeout,
826 BlackBoxDescriptor::DEFAULT_ADAPTOR);
827 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
828 if (i == mAdaptorMap.end())
830 bbtkDebugDecTab("kernel",8);
833 adaptor = i->second.lock()->GetTypeName();
834 bbtkDebugDecTab("kernel",8);
838 //==========================================================================
841 //==========================================================================
842 /// Registers a black box descriptor in the package
843 bool Package::Register(BlackBoxDescriptor::Pointer d)
845 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<">::Register(\""<<d->GetTypeName()<<"\")"<<std::endl);
847 DescriptorMapType::iterator i = mDescriptorMap.find(d->GetTypeName());
848 if (i!=mDescriptorMap.end())
850 bbtkWarning("Package<"<<GetName()<<"> : Trying to register box type <"
851 <<d->GetTypeName()<<"> which is already in the package");
855 mDescriptorMap[d->GetTypeName()] = d;
857 d->SetPackage(GetThisPointer<Package>());
859 // If it is a default adaptor, also register it in the adaptors map
860 if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_ADAPTOR )
862 bbtkDebugMessage("kernel",8,"Package<"<<GetName()<<">::Register(\""<<d->GetTypeName()<<"\") : The box is an adaptor, inserting it in adaptors map ..."<<std::endl);
864 TypeInfo typein = d->GetInputDescriptor("In")->GetTypeInfo();
865 TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
866 DataInfo infoin(typein,d->GetInputDescriptor("In")->GetNature());
867 DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
868 AdaptorKey key(infoin,infoout,d->GetKind());
870 AdaptorMapType::const_iterator i;
871 i = mAdaptorMap.find(key);
872 if (i == mAdaptorMap.end())
874 mAdaptorMap[key] = d;
876 // If already an adaptor registered : error
879 if (i->second.lock()->GetTypeName() != d->GetTypeName())
881 bbtkError("Package <"<<GetName()<<
882 "> : trying to register black box <"
884 <<"> as default adaptor but there is already a default adaptor registered (<"
885 <<i->second.lock()->GetTypeName()<<">)");
889 // If it is a default adaptor, also register it in the adaptors map
890 else if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_GUI)
892 bbtkDebugMessage("kernel",8,"Package<"<<GetName()<<">::Register(\""<<d->GetTypeName()<<"\") : The box is a widget adaptor, inserting it in adaptors map ..."<<std::endl);
894 TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
895 DataInfo infoin(typeid(void),"");
896 DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
897 AdaptorKey key(infoin,infoout,d->GetKind());
899 AdaptorMapType::const_iterator i;
900 i = mAdaptorMap.find(key);
901 if (i == mAdaptorMap.end())
903 mAdaptorMap[key] = d;
905 // If already an adaptor registered : error
908 if (i->second.lock()->GetTypeName() != d->GetTypeName())
910 bbtkError("Package <"<<GetName()<<
911 "> : trying to register black box <"
913 <<"> as default widget adaptor but there is already a default adaptor registered (<"
914 <<i->second.lock()->GetTypeName()<<">)");
920 bbtkDebugDecTab("kernel",8);
924 //==========================================================================
926 //===================================================================
927 void Package::Check() const
929 bbtkMessage("debug",1,"****** Checking Package "<<(void*)this
930 <<" ["<<GetName()<<"]"<<std::endl);
931 DescriptorMapType::const_iterator i;
932 for (i=mDescriptorMap.begin();
933 i!=mDescriptorMap.end();
936 i->second->Check(true);
938 bbtkMessage("debug",1,"****** Checking Package "<<(void*)this
939 <<" ["<<GetName()<<"] ... OK"<<std::endl);
941 //===================================================================
944 //==========================================================================
945 /// Changes the name of a black box type
946 void Package::ChangeDescriptorName( const std::string& oldname, const std::string& newname )
948 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()
949 <<">::ChangeDescriptorName(\""<<oldname
950 <<"\",\""<<newname<<"\")"<<std::endl);
951 // Looking into the bb map
952 DescriptorMapType::iterator i = mDescriptorMap.find(oldname);
953 if (i == mDescriptorMap.end())
955 bbtkDebugDecTab("kernel",8);
956 bbtkError("ChangeDescriptorName : The package <"<<GetName()<<"> does not contains the black box <"<<oldname<<">");
959 i->second->SetTypeName(newname);
960 mDescriptorMap[newname] = i->second;
961 mDescriptorMap.erase(i);
963 bbtkDebugDecTab("kernel",8);
965 //==========================================================================
969 //==========================================================================
970 void Package::PrintHelpListDescriptors(bool description, bool adaptors) const
972 unsigned int lmax = 0;
973 std::vector<std::string> names;
974 std::vector<std::string> kinds;
975 std::vector<std::string> descrs;
977 DescriptorMapType::const_iterator i;
978 for (i=mDescriptorMap.begin();
979 i!=mDescriptorMap.end();
983 ( i->second->GetKind() == BlackBoxDescriptor::STANDARD) )
985 std::string name(" ");
986 name += i->second->GetTypeName();
987 names.push_back(name);
990 if ( i->second->GetKind() == BlackBoxDescriptor::ADAPTOR )
992 kind = std::string("[A]");
994 else if ( i->second->GetKind() ==
995 BlackBoxDescriptor::DEFAULT_ADAPTOR )
997 kind = std::string("[DA]");
999 kinds.push_back(kind);
1001 unsigned int l = name.size()+kind.size();
1002 if (l>lmax) lmax = l;
1008 descr += i->second->GetDescription();
1010 descrs.push_back(descr);
1016 offs.append(lmax+3,' ');
1017 std::vector<std::string>::iterator ni,ci,di;
1018 for (ni = names.begin(), ci = kinds.begin(), di = descrs.begin();
1019 ni != names.end(); ++ni, ++ci, ++di)
1022 space.append(lmax - ni->size() - ci->size(),' ');
1023 bbtkMessage("help",1,*ni << space << *ci );
1025 unsigned int dmax = 75 - lmax;
1026 // while (d.size() > dmax )
1029 bbtkMessage("help",1,d.substr(0,dmax) << "..." << std::endl);
1031 bbtkMessage("help",1,d << std::endl);
1032 // d = d.substr(dmax,d.size());
1037 //==========================================================================
1039 //==========================================================================
1040 /// Displays the list of adaptors of the package
1041 void Package::PrintHelpListAdaptors(bool description) const
1043 DescriptorMapType::const_iterator i;
1044 for (i=mDescriptorMap.begin();
1045 i!=mDescriptorMap.end();
1048 if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD )
1050 bbtkMessage("help",1,
1051 " "<<i->second->GetTypeName());
1052 if ( i->second->GetKind() ==
1053 BlackBoxDescriptor::DEFAULT_ADAPTOR )
1055 bbtkMessage("help",1,
1060 bbtkMessage("help",1,
1061 " : "<<i->second->GetDescription());
1064 bbtkMessage("help",1,std::endl);
1068 AdaptorMapType::const_iterator i;
1069 for (i=mAdaptorMap.begin();
1070 i!=mAdaptorMap.end();
1073 bbtkMessage("help",1,
1074 " "<<i->second->GetTypeName());
1077 bbtkMessage("help",1,
1078 " : "<<i->second->GetDescription());
1081 bbtkMessage("help",1,std::endl);
1085 //==========================================================================
1087 //==========================================================================
1088 /// Prints help on a black box descriptor
1089 void Package::PrintHelpDescriptor(const std::string& name, bool full) const
1091 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()
1092 <<">::PrintHelpDescriptor(\""
1093 <<name<<"\")"<<bbtkendl);
1095 DescriptorMapType::const_iterator i = mDescriptorMap.find(name);
1096 if (i == mDescriptorMap.end())
1098 bbtkDebugDecTab("kernel",8);
1099 bbtkError("The package <"<<GetName()<<"> does not contains the black box <"<<name<<">");
1101 // bbtkMessage("help",1,"["<<GetName()<<"] ");
1102 i->second->GetHelp(full);
1103 bbtkDebugDecTab("kernel",8);
1106 //==========================================================================
1109 //==========================================================================
1110 /// Returns true iff the package contains the box of name boxname
1111 bool Package::ContainsDescriptor(const std::string& name) const
1113 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()
1114 <<">::ContainsDescriptor(\""
1115 <<name<<"\")"<<bbtkendl);
1117 DescriptorMapType::const_iterator i = mDescriptorMap.find(name);
1118 if (i == mDescriptorMap.end())
1120 bbtkDebugDecTab("kernel",8);
1123 bbtkDebugDecTab("kernel",8);
1126 //==========================================================================
1130 //==========================================================================
1131 void Package::CreateHtmlPage(const std::string& filename,
1132 const std::string& caller,
1133 const std::string& source,
1134 const std::string& custom_header,
1135 const std::string& custom_title,
1138 bool relative_link ) const
1140 bbtkDebugMessageInc("kernel",9,"Package<"<<GetName()<<">::CreateHtmlPage(\""
1141 <<filename<<"\")"<<bbtkendl);
1143 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1133"<<std::endl;
1145 //---------------------
1148 s.open(filename.c_str());
1151 bbtkError("Package "<<GetName()<<" : CreateHtmlPage : could not open file '"<<filename<<"'");
1154 //----------------------
1156 std::string title = "BBTK Package "+GetName()+" "+GetVersion();
1158 if (custom_title.length() != 0) title = custom_title;
1160 s << "<html lang=\"en\">\n";
1162 s << "<title>" << title << "</title>\n";
1163 s << "<meta http-equiv=\"Content-Type\" content=\"text/html\">\n";
1164 s << "<meta name=\"description\" content=\""<<title<<"\">\n";
1165 s << "<meta name=\"generator\" content=\"\">\n";
1166 s << "<link title=\"Top\" rel=\"top\" href=\"#Top\">\n";
1167 //<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
1168 s << "<meta http-equiv=\"Content-Style-Type\" content=\"text/css\"><style type=\"text/css\"><!--\n";
1169 s << "pre.display { font-family:inherit }\n";
1170 s << "pre.format { font-family:inherit }\n";
1171 s << "pre.smalldisplay { font-family:inherit; font-size:smaller }\n";
1172 s << "pre.smallformat { font-family:inherit; font-size:smaller }\n";
1173 s << "pre.smallexample { font-size:smaller }\n";
1174 s << "pre.smalllisp { font-size:smaller }\n";
1175 s << "span.sc { font-variant:small-caps }\n";
1176 s << "span.roman { font-family:serif; font-weight:normal; } \n";
1177 s << "span.sansserif { font-family:sans-serif; font-weight:normal; }\n";
1178 s << "--></style>\n";
1180 //----------------------
1182 //----------------------
1185 s << "<a name=\"Top\"></a>\n";
1187 //----------------------
1189 if ( custom_header.length() != 0)
1191 if ( custom_header != "none" )
1194 in.open(custom_header.c_str());
1197 bbtkError("Could not open file \""<<custom_header<<"\"");
1202 in.getline(buffer,512);
1203 std::string line(buffer);
1210 s << "<object data=\"" << custom_header
1211 << "\" type = \"text/html\"\"style=\"width: 1200px; height: 400px;\"> Warning: "
1212 << custom_header <<" could not be embedded.</object>\n";
1218 s << "<h1 class=\"settitle\">"<<title<<"</h1>\n";
1219 s << "<p><TABLE cellspacing=0 cellpadding=3>\n";
1220 s << "<TR><TD style='vertical-align: top;'><b> Description </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1221 << GetDescription() << "</TD></TR>\n";
1222 s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1223 << GetAuthor() << "</TD></TR>\n";
1224 s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1225 << GetCategory() << "</TD></TR>\n";
1226 s << "<TR><TD style='vertical-align: top;'><b> Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1227 << GetVersion() << "</TD></TR>\n";
1228 s << "<TR><TD style='vertical-align: top;'><b> bbtk Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1229 << bbtk::GetVersion() << "</TD></TR>\n";
1232 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1225"<<std::endl;
1233 //-------------------
1234 // Table of contents
1236 // s << "<div class=\"contents\">\n";
1237 s << "<p><b> Black Boxes : </b>\n";
1240 s << "<p><TABLE cellspacing=0 cellpadding=3>\n";
1242 DescriptorMapType::const_iterator i;
1243 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1236"<<std::endl;
1244 for (i=mDescriptorMap.begin(); i!=mDescriptorMap.end(); ++i) {
1245 if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD)
1248 std::string name = i->second->GetTypeName();
1249 Utilities::html_format(name);
1250 std::string descr = i->second->GetDescription();
1251 //Utilities::html_format(descr);
1252 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1246"<<std::endl;
1254 s << "<TD style='vertical-align: top;'>";
1255 s << " <a name=\"toc_"<<name
1256 <<"\" href=\"#"<<name<<"\">"
1259 s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
1268 //-------------------
1270 if (mAdaptorMap.size()>0)
1272 // s << "<div class=\"contents\">\n";
1273 s << "<p><b> Adaptors : </b>\n";
1275 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1268"<<std::endl;
1276 // DescriptorMapType::const_iterator i;
1277 s << "<p><TABLE cellspacing=0 cellpadding=3>\n";
1278 for (i=mDescriptorMap.begin(); i!=mDescriptorMap.end();++i)
1280 if ( i->second->GetKind() == BlackBoxDescriptor::STANDARD)
1283 std::string name = i->second->GetTypeName();
1284 Utilities::html_format(name);
1285 std::string descr = i->second->GetDescription();
1288 s << "<TD style='vertical-align: top;'>";
1289 s << " <a name=\"toc_"<<name
1290 <<"\" href=\"#"<<name<<"\">"
1293 s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
1303 // s << "<div class=\"node\">\n";
1305 // s << "<p><hr>\n";
1306 // s << "<a name=\"Top\"></a>\n";
1307 // s << "Top: <a rel=\"top\" accesskey=\"t\" href=\"#Top\">Top</a>\n";
1308 // s << "Previous: <a rel="previous" accesskey="p" href="#dir">(dir)</a>,
1309 // s << "Up: <a rel="up" accesskey="u" href="#dir">(dir)</a>
1313 //----------------------
1316 //-------------------
1317 // Computes output directory from filename to pass it to
1318 // BlackBoxDescriptor::InsertHtmlHelp
1321 std::string::size_type slash_position = filename.find_last_of("/\\");
1324 if (slash_position != std::string::npos) {
1325 if (slash_position == 0)
1327 dir = filename.substr(0,slash_position);
1330 for (i=mDescriptorMap.begin();
1331 i!=mDescriptorMap.end();
1334 i->second->InsertHtmlHelp(s,detail,level,dir,relative_link);
1337 //----------------------
1342 ptm = gmtime ( &rawtime );
1345 s << "Automatically generated by <b>"<<caller<<"</b> "//from <b>"
1348 << ptm->tm_mday << "/" << ptm->tm_mon << "/" << ptm->tm_year+1900
1349 << " - " << ptm->tm_hour << ":" << ptm->tm_min << " GMT\n";
1350 s << "</body></html>\n";
1352 //----------------------
1355 bbtkDebugDecTab("kernel",9);
1357 //==========================================================================
1359 //==========================================================================
1360 std::string Package::GetObjectName() const
1362 return std::string("Package '")+mName+std::string("'");
1364 //==========================================================================
1366 //==========================================================================
1367 std::string Package::GetObjectInfo() const
1369 std::stringstream i;
1370 i << " - "<<mDescriptorMap.size() << " boxes" << std::endl;
1371 if (mDynamicLibraryHandler)
1373 i<< " - Loaded from dynamic library"<<std::endl;
1377 //==========================================================================
1380 //==========================================================================
1381 size_t Package::GetObjectSize() const
1383 size_t s = Superclass::GetObjectSize();
1384 s += Package::GetObjectInternalSize();
1387 //==========================================================================
1388 //==========================================================================
1389 size_t Package::GetObjectInternalSize() const
1391 size_t s = sizeof(Package);
1394 //==========================================================================
1395 //==========================================================================
1396 size_t Package::GetObjectRecursiveSize() const
1398 size_t s = Superclass::GetObjectRecursiveSize();
1399 s += Package::GetObjectInternalSize();
1401 DescriptorMapType::const_iterator i;
1402 for (i = mDescriptorMap.begin(); i!=mDescriptorMap.end(); ++i )
1404 s += i->second->GetObjectRecursiveSize();
1408 //==========================================================================
1409 void Package::GetBoxesInside(NodeTreeC& tree, int cont)
1411 DescriptorMapType::const_iterator i;
1412 std::cout<<"*********a********"<<std::endl;
1413 for (i=mDescriptorMap.begin(); i!=mDescriptorMap.end(); ++i)
1415 i->second->GetBoxesInside(tree, cont);
1416 std::cout<<"*****************"<<std::endl;
1419 //==========================================================================
1420 //==========================================================================
1421 std::set<Package::WeakPointer>
1422 Package::mReleasedDynamicallyLoadedPackages;
1423 //==========================================================================