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<<"',...)"
90 std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
91 char c = default_doc_dir.c_str()[strlen(default_doc_dir.c_str())-1];
92 std::string url = default_doc_dir;
93 if (c != '/' && c !='\\') url = url + "/";
94 url = url + "temp_dir/" + name + "/index.html";
97 SetDocRelativeURL("Relative url not set");
100 std::string relurl(BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH));
101 relurl += "/packages/"+name+"/bbdoc/index.html";
102 std::string url = ConfigurationFile::GetInstance().Get_url()
105 SetDocRelativeURL(relurl);
108 // std::cout << " url=["<<url<<"]"<<std::endl;
109 // std::cout << "relurl=["<<relurl<<"]"<<std::endl;
110 bbtkDebugMessage("object",2,"<== Package::Package('"<<name<<"',...) OK"
114 //==========================================================================
118 //==========================================================================
122 bbtkDebugMessage("object",2,"==> ~Package(\""<<mName<<"\")"<<bbtkendl);
124 //==========================================================================
127 //==========================================================================
128 void PackageReleaseBlackBoxDescriptorInternal(Package::WeakPointer pack,
129 const std::string& descname)
131 // Try to release descriptor
132 std::string packname = pack.lock()->GetName();
134 bbtkDebugMessage("package",5,"--- Releasing descriptor '"
135 <<packname<<"::"<<descname<<"'"<<bbtkendl);
138 Package::DescriptorMapType::iterator desc =
139 pack.lock()->GetDescriptorMap().find(descname);
140 if (desc == pack.lock()->GetDescriptorMap().end())
142 bbtkDebugMessage("package",5,
143 " Descriptor has already been released"
147 // bbtkDebugMessage("package",3,
148 // " Trying unreferencing it ... "<<std::endl);
149 BlackBoxDescriptor::WeakPointer pdesc = desc->second;
150 desc->second.reset();
151 // if it is dead : remove it
154 bbtkDebugMessage("package",2," ==> '"<<packname<<"::"<<descname<<"' Descriptor expired"<<bbtkendl);
157 bbtkDebugMessage("package",2,
158 " ... and caused its package death"
162 desc = pack.lock()->GetDescriptorMap().find(descname);
163 if (desc != pack.lock()->GetDescriptorMap().end()) pack.lock()->GetDescriptorMap().erase(desc);
164 } else { //pdesc.expired
165 bbtkDebugMessage("package",5," ... Descriptor still alive ("
166 <<pdesc.use_count()<<" refs)"
168 pack.lock()->GetDescriptorMap()[descname] = pdesc.lock();
171 //==========================================================================
174 //==========================================================================
176 void Package::Release(Package::WeakPointer pack)
178 std::string packname = pack.lock()->mName;
179 bbtkDebugMessage("package",1,"==> Package::Release('"<<
180 packname<<"')"<<bbtkendl);
182 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
183 long ndesc = pack.lock()->GetDescriptorMap().size();
184 long nrefs = pack.use_count();
186 bbtkDebugMessage("package",5," "<<nrefs<<" refs / "
187 <<ndesc<<" descr / dyn="
190 // A package is "free" from any external reference iff :
191 // i) It is not dynamically loaded and nrefs == ndesc
192 // (each desc references its package) or
193 // ii) It is dynamically loaded and nrefs == ndesc + 1
194 // (A dynamic library holds a static pointer on the package it contains
195 // which is allocated when the PACKAGENAMEGetPackage() func is called,
196 // and descallocated (reset) by PACKAGENAMEDeletePackage())
197 if (nrefs == ndesc + dyn)
199 bbtkDebugMessage("package",5,
200 " -> No more external ref : checking descriptors"
202 // We must take care that removing refs on descriptors
203 // can lead to their deletion which can in turn unref
204 // internal boxes which can release their descriptors hence
205 // call Package::ReleaseBlackBoxDescriptor
206 // As a consequence during descriptors release :
207 // 1) The map can change dynamically : we cannot iterate over it
208 // as any iterator can become invalid
209 // 2) The package can auto-destruct : we must test its existence
210 // after each release
211 // We must also take care of not locking the package pointer
212 // or any ref count check in Package::ReleaseBlackBoxDescriptor
215 // The list of descriptors names at start
216 std::vector<std::string> descnamelist;
217 DescriptorMapType::iterator i;
218 for (i=pack.lock()->mDescriptorMap.begin();
219 i!= pack.lock()->mDescriptorMap.end();
221 descnamelist.push_back(i->first);
223 // Iterator over the initial names
224 std::vector<std::string>::iterator descname;
225 for (descname=descnamelist.begin();
226 descname!=descnamelist.end();
229 // Is package still alive ?
232 bbtkDebugMessage("package",1,"--- Package::Release('"<<
234 <<"') : package expired during release : bailing out"<<bbtkendl);
239 BlackBoxDescriptor::Pointer desc = pack.lock()->mDescriptorMap[*descname];
240 if ( (dyn==0) || (boost::dynamic_pointer_cast<ComplexBlackBoxDescriptor>(desc)) )
242 PackageReleaseBlackBoxDescriptorInternal(pack,*descname);
245 PackageReleaseBlackBoxDescriptorInternal(pack,*descname);
251 UnLoadDynamicLibrary(pack);
252 // Unload orphan dl packages
253 Package::UnLoadReleasedDynamicallyLoadedPackages();
257 #ifdef BBTK_COMPILE_DEBUG_MESSAGES
259 bbtkDebugMessage("package",2,"<== Package::Release('"<<
260 packname<<"')"<<bbtkendl);
264 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
265 long ndesc = pack.lock()->GetDescriptorMap().size();
266 long nrefs = pack.use_count();
268 bbtkDebugMessage("package",1," ... Package still alive ("
270 <<ndesc<<" descr / dyn="
271 <<dyn<<")"<<std::endl);
275 bbtkDebugMessage("package",1," ... Package has been released"
280 //==========================================================================
282 //==========================================================================
283 /// "Releases" the package
284 /// Signals the package that it can free the given descriptor
285 /// if they are no more used and free itself if it is no
287 /// Note : Any non-weak pointer on the package must have been freed
288 void Package::ReleaseBlackBoxDescriptor(Package::WeakPointer pack,
289 BlackBoxDescriptor::WeakPointer descr)
291 std::string packname = pack.lock()->mName;
292 std::string dname = descr.lock()->GetTypeName();
293 bbtkDebugMessage("package",3,"==> Package::ReleaseBlackBoxDescriptor('"<<
294 packname<<"','"<<dname<<"') : refs="
295 <<descr.use_count()<<bbtkendl);
297 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
298 long ndesc = pack.lock()->GetDescriptorMap().size();
299 long nrefs = pack.use_count();
301 bbtkDebugMessage("package",5," "<<nrefs<<" refs / "
302 <<ndesc<<" descr / dynamically loaded = "
305 // A package is "free" from any external reference iff :
306 // i) It is not dynamically loaded and nrefs == ndesc
307 // (each desc references its package) or
308 // ii) It is dynamically loaded and nrefs == ndesc + 1
309 // (A dynamic library holds a static pointer on the package it contains
310 // which is allocated when the PACKAGENAMEGetPackage() func is called,
311 // and descallocated (reset) by PACKAGENAMEDeletePackage())
312 if (nrefs == ndesc + dyn)
317 PackageReleaseBlackBoxDescriptorInternal(pack,dname);
319 PackageReleaseBlackBoxDescriptorInternal(pack,dname);
323 // If the package is released and dynamically loaded
324 // then put it in the static list mReleasedDynamicallyLoadedPackages
325 UnLoadDynamicLibrary(pack,false);
327 bbtkDebugMessage("package",4,"<== Package::ReleaseBlackBoxDescriptor('"<<
328 packname<<"','"<<dname<<"'): refs="
329 <<descr.use_count()<<bbtkendl);
333 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
334 long ndesc = pack.lock()->GetDescriptorMap().size();
335 long nrefs = pack.use_count();
337 bbtkDebugMessage("package",3," ... Package still alive ("
339 <<ndesc<<" descr / dyn="
340 <<dyn<<")"<<std::endl);
344 bbtkDebugMessage("package",3," ... Package has been released"
349 //==========================================================================
351 //==========================================================================
352 /// Opens a dynamic library which contains a bbtk package
353 /// Returns the handler
354 /// Load the package management symbols from the lib
355 /// returns false if a problem occured hence can be used
356 /// to test that a dyn lib is a valid bbtk package lib
357 /// NB : The BBTK version exported from the library
358 /// is tested against the current bbtk version
359 DynamicLibraryHandler Package::OpenDynamicLibrary( const std::string& libname,const std::string& package_name,
360 DLGetPackageFunction& getpack, DLDeletePackageFunction& delpack)
362 bbtkDebugMessage("package",3,"==> Package::OpenDynamicLibrary("
363 <<libname<<")"<<std::endl);
364 #if defined(__GNUC__)
368 handler = dlopen(libname.c_str(), BBTK_RTLD_TIME | BBTK_RTLD_SCOPE );
369 //EED handler = dlopen(libname.c_str(), RTLD_LAZY | RTLD_LOCAL );
373 bbtkMessage("package",0,
374 "BBTK ..ERROR.. loading could not open shared library [" <<libname<<"] : "
375 <<dlerror() << std::endl);
379 bbtkDebugMessage("package",3,"* Shared lib ["<<libname<<"] open"<<std::endl);
381 // Loads the Package bbtk version function
382 std::string getvername(package_name);
383 getvername += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME);
384 DLGetPackageBBTKVersionFunction getbbtkversion = (DLGetPackageBBTKVersionFunction)(dlsym(handler,getvername.c_str()));
387 bbtkDebugMessage("package",3,"***"<<std::endl);
388 bbtkMessage("package",0,
389 "BBTK ..ERROR.. loading shared library ["<<libname
390 <<"] is not a valid bbtk package."
391 <<" Symbol ["<<getvername<<"] :"<<dlerror()<< std::endl);
396 bbtkDebugMessage("package",3,"* Symbol ["<<getvername
397 <<"] found"<<std::endl);
400 if (getbbtkversion() != bbtk::GetVersion())
402 bbtkMessage("package",0,
403 "BBTK ..ERROR.. loading: "<<package_name
404 <<" - Shared library ["<<libname
405 <<"] was build with bbtk version "
407 <<" but the current program runs with version "
408 <<bbtk::GetVersion()<<" : cannot load it. You have to recompile your BBTK-Package."<<std::endl);
414 bbtkDebugMessage("package",3,"* Package bbtk version '"<<getbbtkversion()<<"' matches"<<std::endl);
415 // Loads the Package get function
416 std::string getpackname(package_name);
417 getpackname += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_FUNCTION_NAME);
418 getpack = (DLGetPackageFunction)(dlsym(handler, getpackname.c_str()));
421 bbtkMessage("package",0,
422 "BBTK ..ERROR.. loading shared library ["<<libname
423 <<"] is not a valid bbtk package."
424 <<" Symbol ["<<getpackname<<"] :"<<dlerror()<< std::endl);
429 bbtkDebugMessage("package",3,"* Symbol ["<<getpackname<<"] found"<<std::endl);
430 // Loads the Package delete function
432 std::string delpackname(package_name);
433 delpackname += BBTK_STRINGIFY_SYMBOL(BBTK_DEL_PACKAGE_FUNCTION_NAME);
434 delpack = (DLDeletePackageFunction)(dlsym(handler, delpackname.c_str()));
437 bbtkMessage("package",0,
438 "BBTK ..ERROR.. loading shared library ["<<libname
439 <<"] is not a valid bbtk package."
440 <<" Symbol ["<<delpackname<<"] :"<<dlerror()<< std::endl);
444 bbtkDebugMessage("package",3,"* Symbol ["<<delpackname<<"] found"<<std::endl);
445 #elif defined(_WIN32)
451 handler = LoadLibrary(libname.c_str());
454 bbtkMessage("package",0,
455 "BBTK ..ERROR.. could not open shared library [" <<libname<<"]"
457 DWORD dwErrorCode = 0;
458 dwErrorCode = GetLastError();
459 bbtkMessage("package",2,
460 "Windows Error: [" << dwErrorCode <<"]"
466 // Loads the Package bbtk version function
467 std::string getvername(package_name);
468 getvername += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME);
469 DLGetPackageBBTKVersionFunction getbbtkversion = (DLGetPackageBBTKVersionFunction)(GetProcAddress(handler, getvername.c_str()));
473 FreeLibrary(handler);
474 bbtkMessage("package",0,
475 "BBTK ..ERROR.. loading shared library ["<<libname
476 <<"] is not a valid bbtk package."
477 <<" Symbol ["<<getbbtkversion<<"] not found"<< std::endl);
482 if (getbbtkversion() != bbtk::GetVersion())
484 FreeLibrary(handler);
485 bbtkMessage("package",0,
486 "BBTK ..ERROR.. loading: "<<package_name
487 <<" - Shared library ["<<libname
488 <<"] was build with bbtk version "
490 <<" but the current program runs with version "
491 <<bbtk::GetVersion()<<" : cannot load it. You have to recompile your BBTK-Package."<<std::endl);
495 // Loads the Package get function
496 std::string getpackname(package_name);
497 getpackname += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_FUNCTION_NAME);
498 getpack = (DLGetPackageFunction)(GetProcAddress(handler, getpackname.c_str()));
501 FreeLibrary(handler);
502 bbtkMessage("package",0,
503 "BBTK ..ERROR.. loading shared library ["<<libname
504 <<"] is not a valid bbtk package."
505 <<" Symbol ["<<getpackname<<"] not found"<< std::endl);
509 // Loads the Package delete function
510 std::string delpackname(package_name);
511 delpackname += BBTK_STRINGIFY_SYMBOL(BBTK_DEL_PACKAGE_FUNCTION_NAME);
512 delpack = (DLDeletePackageFunction)(GetProcAddress(handler, delpackname.c_str()));
515 FreeLibrary(handler);
516 bbtkMessage("package",0,
517 "BBTK ..ERROR.. loading shared library ["<<libname
518 <<"] is not a valid bbtk package."
519 <<" Symbol ["<<delpackname<<"] not found"<< std::endl);
524 bbtkError("neither __GNUC__ nor _WIN32 ?!? How did you compile ?");
529 //==========================================================================
531 //==========================================================================
532 /// Loads a package from a dynamic library
533 Package::Pointer Package::CreateFromDynamicLibrary(const std::string& libname,
534 const std::string& pkgname,
535 const std::string& path)
537 bbtkDebugMessage("package",1,"==> Package::CreateFromDynamicLibrary("
538 <<libname<<")"<<std::endl);
540 DLGetPackageFunction gf;
541 DLDeletePackageFunction df;
542 DynamicLibraryHandler h = Package::OpenDynamicLibrary(libname,
545 if (h==0) return Package::Pointer();
546 Package::Pointer p = gf();
547 p->mDynamicLibraryHandler = h;
548 p->mDLDeletePackageFunction = df;
550 std::string separator =
551 ConfigurationFile::GetInstance().Get_file_separator ();
552 //BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
553 std::string docreldoc =
554 separator + "bbdoc" + separator + pkgname + separator + "index.html";
556 ".." + separator + ".." + docreldoc;
557 std::string doc = path + separator + ".." + separator
558 + BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
562 p->SetDocRelativeURL(reldoc);
564 bbtkDebugMessage("package",2,"<== Package::CreateFromDynamicLibrary("
565 <<libname<<") .. OK"<<std::endl);
568 //==========================================================================
573 //==========================================================================
574 /// UnLoads the package dynamic library (if any)
575 void Package::UnLoadDynamicLibrary(Package::WeakPointer pack, bool doit)
577 if (pack.expired() || (!pack.lock()->mDynamicLibraryHandler))
580 std::string packname = pack.lock()->GetName();
581 bbtkDebugMessage("package",5,"==> Package::UnLoadDynamicLibrary('"
585 if (!pack.lock()->GetDescriptorMap().empty())
588 bbtkDebugMessage("package",5," Package not empty ... abort"
592 bbtkGlobalError("Package::UnLoadDynamicLibrary('"<<packname<<") : "
593 <<"DescriptorMap not empty "
594 <<BBTK_INTERNAL_ERROR_MESSAGE);
598 if (pack.use_count()!=1)
600 bbtkGlobalError("Package::UnLoadDynamicLibrary('"<<packname<<") : "
601 <<"empty dl package with external refs"
602 <<BBTK_INTERNAL_ERROR_MESSAGE);
608 bbtkDebugMessage("package",5,"==> dynamic library for package '"
609 <<packname<<"' closed"
614 mReleasedDynamicallyLoadedPackages.insert(pack);
615 bbtkDebugMessage("package",1,"==> package '"<<packname
616 <<"' put in the 'to unload' list"
620 bbtkDebugMessage("package",5,"<== Package::UnLoadDynamicLibrary('"
624 //==========================================================================
626 //==========================================================================
627 /// UnLoads released packages that were loaded dynamically
628 /// see UnLoadDynamicLibrary and ReleaseBlackBoxDescriptor
629 void Package::UnLoadReleasedDynamicallyLoadedPackages()
631 bbtkDebugMessage("package",5,"==> Package::UnLoadReleasedDynamicallyLoadedPackages()"<<std::endl);
633 std::set<Package::WeakPointer>::iterator i;
636 if(mReleasedDynamicallyLoadedPackages.size()>0){
637 for (i=mReleasedDynamicallyLoadedPackages.begin();
638 i!=mReleasedDynamicallyLoadedPackages.end();
641 if (!i->expired()) UnLoad(*i);
645 bbtkDebugMessage("package",5,"<== Package::UnLoadReleasedDynamicallyLoadedPackages()"<<std::endl);
647 //==========================================================================
649 //==========================================================================
650 void Package::UnLoad(Package::WeakPointer pack)
652 std::string packname = pack.lock()->GetName();
653 bbtkDebugMessage("package",6,"==> Package::UnLoad("<<packname<<")"<<std::endl);
655 Package* p = pack.lock().get();
657 DynamicLibraryHandler h = p->mDynamicLibraryHandler;
659 // deletes the package
660 p->mDLDeletePackageFunction();
662 // closes the dl handler
663 #if defined(__GNUC__)
666 printf("EED Package::UnLoad ERROR %s\n", packname.c_str() );
667 bbtkWarning("Failed to close dynamic library for package '"<<packname
671 #elif defined(_WIN32)
675 bbtkDebugMessage("package",1,"==> dynamic library for package '"
676 <<packname<<"' closed"
678 bbtkDebugMessage("package",6," ... dynamic library unloaded"<<std::endl);
680 //==========================================================================
682 bool Package::ifBoxExist( std::string type)
685 DescriptorMapType::const_iterator i = mDescriptorMap.find(type);
686 if (i != mDescriptorMap.end())
693 //==========================================================================
694 /// Creates an instance of a black box of type <type> with name <name>
695 BlackBox::Pointer Package::NewBlackBox(const std::string& type,
696 const std::string& name) const
698 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<">::NewBlackBox(\""<<type<<"\",\""<<name<<"\")"<<bbtkendl);
700 DescriptorMapType::const_iterator i = mDescriptorMap.find(type);
701 if (i == mDescriptorMap.end())
703 bbtkDebugDecTab("kernel",8);
704 return BlackBox::Pointer();
706 BlackBox::Pointer bb =i->second->NewBlackBox(name);
707 bbtkDebugDecTab("kernel",8);
711 //==========================================================================
715 //==========================================================================
716 /// Creates an instance of an adaptor of input type <typein> and
717 /// output type <typeout> with name <name>
718 BlackBox::Pointer Package::NewAdaptor(const DataInfo& typein,
719 const DataInfo& typeout,
720 const std::string& name) const
722 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
726 <<name<<"\")"<<bbtkendl);
728 AdaptorKey key(typein,typeout,
729 BlackBoxDescriptor::DEFAULT_ADAPTOR);
730 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
731 if (i == mAdaptorMap.end())
733 bbtkDebugDecTab("kernel",8);
734 return BlackBox::Pointer();
736 BlackBox::Pointer bb =i->second.lock()->NewBlackBox(name);
737 bbtkDebugDecTab("kernel",8);
741 //==========================================================================
743 //==========================================================================
744 /// Creates an instance of an adaptor of input type <typein> and
745 /// output type <typeout> with name <name>
746 BlackBox::Pointer Package::NewWidgetAdaptor(const DataInfo& typein,
747 const DataInfo& typeout,
748 const std::string& name) const
750 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
751 ">::NewWidgetAdaptor("
754 <<name<<"\")"<<bbtkendl);
756 AdaptorKey key(typein,typeout,
757 BlackBoxDescriptor::DEFAULT_GUI);
758 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
759 if (i == mAdaptorMap.end())
761 bbtkDebugDecTab("kernel",8);
762 return BlackBox::Pointer();
764 BlackBox::Pointer bb =i->second.lock()->NewBlackBox(name);
765 bbtkDebugDecTab("kernel",8);
769 //==========================================================================
773 //==========================================================================
774 /// Returns true is the package contains
775 /// an adaptor of input type <typein> and
776 /// output type <typeout>
777 /// If successfull then adaptor contains the black box type name
778 bool Package::FindWidgetAdaptor(const DataInfo& typein,
779 const DataInfo& typeout,
780 std::string& adaptor) const
782 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
783 ">::FindWidgetAdaptor("
785 <<typeout<<")"<<bbtkendl);
787 AdaptorKey key(/*typein*/
788 DataInfo(typeid(void),""),
790 BlackBoxDescriptor::DEFAULT_GUI);
791 // First try to find a single widget adaptor
792 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
793 if (i == mAdaptorMap.end())
795 bbtkDebugDecTab("kernel",8);
798 adaptor = i->second.lock()->GetTypeName();
799 bbtkDebugDecTab("kernel",8);
803 //==========================================================================
807 //==========================================================================
808 /// Returns true is the package contains
809 /// an adaptor of input type <typein> and
810 /// output type <typeout>
811 /// If successfull then adaptor contains the black box type name
812 bool Package::FindAdaptor(const DataInfo& typein,
813 const DataInfo& typeout,
814 std::string& adaptor) const
816 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
819 <<typeout<<")"<<bbtkendl);
821 AdaptorKey key(typein,typeout,
822 BlackBoxDescriptor::DEFAULT_ADAPTOR);
823 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
824 if (i == mAdaptorMap.end())
826 bbtkDebugDecTab("kernel",8);
829 adaptor = i->second.lock()->GetTypeName();
830 bbtkDebugDecTab("kernel",8);
834 //==========================================================================
837 //==========================================================================
838 /// Registers a black box descriptor in the package
839 bool Package::Register(BlackBoxDescriptor::Pointer d)
841 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<">::Register(\""<<d->GetTypeName()<<"\")"<<std::endl);
843 DescriptorMapType::iterator i = mDescriptorMap.find(d->GetTypeName());
844 if (i!=mDescriptorMap.end())
846 bbtkWarning("Package<"<<GetName()<<"> : Trying to register box type <"
847 <<d->GetTypeName()<<"> which is already in the package");
851 mDescriptorMap[d->GetTypeName()] = d;
853 d->SetPackage(GetThisPointer<Package>());
855 // If it is a default adaptor, also register it in the adaptors map
856 if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_ADAPTOR )
858 bbtkDebugMessage("kernel",8,"Package<"<<GetName()<<">::Register(\""<<d->GetTypeName()<<"\") : The box is an adaptor, inserting it in adaptors map ..."<<std::endl);
860 TypeInfo typein = d->GetInputDescriptor("In")->GetTypeInfo();
861 TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
862 DataInfo infoin(typein,d->GetInputDescriptor("In")->GetNature());
863 DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
864 AdaptorKey key(infoin,infoout,d->GetKind());
866 AdaptorMapType::const_iterator i;
867 i = mAdaptorMap.find(key);
868 if (i == mAdaptorMap.end())
870 mAdaptorMap[key] = d;
872 // If already an adaptor registered : error
875 if (i->second.lock()->GetTypeName() != d->GetTypeName())
877 bbtkError("Package <"<<GetName()<<
878 "> : trying to register black box <"
880 <<"> as default adaptor but there is already a default adaptor registered (<"
881 <<i->second.lock()->GetTypeName()<<">)");
885 // If it is a default adaptor, also register it in the adaptors map
886 else if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_GUI)
888 bbtkDebugMessage("kernel",8,"Package<"<<GetName()<<">::Register(\""<<d->GetTypeName()<<"\") : The box is a widget adaptor, inserting it in adaptors map ..."<<std::endl);
890 TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
891 DataInfo infoin(typeid(void),"");
892 DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
893 AdaptorKey key(infoin,infoout,d->GetKind());
895 AdaptorMapType::const_iterator i;
896 i = mAdaptorMap.find(key);
897 if (i == mAdaptorMap.end())
899 mAdaptorMap[key] = d;
901 // If already an adaptor registered : error
904 if (i->second.lock()->GetTypeName() != d->GetTypeName())
906 bbtkError("Package <"<<GetName()<<
907 "> : trying to register black box <"
909 <<"> as default widget adaptor but there is already a default adaptor registered (<"
910 <<i->second.lock()->GetTypeName()<<">)");
916 bbtkDebugDecTab("kernel",8);
920 //==========================================================================
922 //===================================================================
923 void Package::Check() const
925 bbtkMessage("debug",1,"****** Checking Package "<<(void*)this
926 <<" ["<<GetName()<<"]"<<std::endl);
927 DescriptorMapType::const_iterator i;
928 for (i=mDescriptorMap.begin();
929 i!=mDescriptorMap.end();
932 i->second->Check(true);
934 bbtkMessage("debug",1,"****** Checking Package "<<(void*)this
935 <<" ["<<GetName()<<"] ... OK"<<std::endl);
937 //===================================================================
940 //==========================================================================
941 /// Changes the name of a black box type
942 void Package::ChangeDescriptorName( const std::string& oldname, const std::string& newname )
944 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()
945 <<">::ChangeDescriptorName(\""<<oldname
946 <<"\",\""<<newname<<"\")"<<std::endl);
947 // Looking into the bb map
948 DescriptorMapType::iterator i = mDescriptorMap.find(oldname);
949 if (i == mDescriptorMap.end())
951 bbtkDebugDecTab("kernel",8);
952 bbtkError("ChangeDescriptorName : The package <"<<GetName()<<"> does not contains the black box <"<<oldname<<">");
955 i->second->SetTypeName(newname);
956 mDescriptorMap[newname] = i->second;
957 mDescriptorMap.erase(i);
959 bbtkDebugDecTab("kernel",8);
961 //==========================================================================
965 //==========================================================================
966 void Package::PrintHelpListDescriptors(bool description, bool adaptors) const
968 unsigned int lmax = 0;
969 std::vector<std::string> names;
970 std::vector<std::string> kinds;
971 std::vector<std::string> descrs;
973 DescriptorMapType::const_iterator i;
974 for (i=mDescriptorMap.begin();
975 i!=mDescriptorMap.end();
979 ( i->second->GetKind() == BlackBoxDescriptor::STANDARD) )
981 std::string name(" ");
982 name += i->second->GetTypeName();
983 names.push_back(name);
986 if ( i->second->GetKind() == BlackBoxDescriptor::ADAPTOR )
988 kind = std::string("[A]");
990 else if ( i->second->GetKind() ==
991 BlackBoxDescriptor::DEFAULT_ADAPTOR )
993 kind = std::string("[DA]");
995 kinds.push_back(kind);
997 unsigned int l = name.size()+kind.size();
998 if (l>lmax) lmax = l;
1004 descr += i->second->GetDescription();
1006 descrs.push_back(descr);
1012 offs.append(lmax+3,' ');
1013 std::vector<std::string>::iterator ni,ci,di;
1014 for (ni = names.begin(), ci = kinds.begin(), di = descrs.begin();
1015 ni != names.end(); ++ni, ++ci, ++di)
1018 space.append(lmax - ni->size() - ci->size(),' ');
1019 bbtkMessage("help",1,*ni << space << *ci );
1021 unsigned int dmax = 75 - lmax;
1022 // while (d.size() > dmax )
1025 bbtkMessage("help",1,d.substr(0,dmax) << "..." << std::endl);
1027 bbtkMessage("help",1,d << std::endl);
1028 // d = d.substr(dmax,d.size());
1033 //==========================================================================
1035 //==========================================================================
1036 /// Displays the list of adaptors of the package
1037 void Package::PrintHelpListAdaptors(bool description) const
1039 DescriptorMapType::const_iterator i;
1040 for (i=mDescriptorMap.begin();
1041 i!=mDescriptorMap.end();
1044 if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD )
1046 bbtkMessage("help",1,
1047 " "<<i->second->GetTypeName());
1048 if ( i->second->GetKind() ==
1049 BlackBoxDescriptor::DEFAULT_ADAPTOR )
1051 bbtkMessage("help",1,
1056 bbtkMessage("help",1,
1057 " : "<<i->second->GetDescription());
1060 bbtkMessage("help",1,std::endl);
1064 AdaptorMapType::const_iterator i;
1065 for (i=mAdaptorMap.begin();
1066 i!=mAdaptorMap.end();
1069 bbtkMessage("help",1,
1070 " "<<i->second->GetTypeName());
1073 bbtkMessage("help",1,
1074 " : "<<i->second->GetDescription());
1077 bbtkMessage("help",1,std::endl);
1081 //==========================================================================
1083 //==========================================================================
1084 /// Prints help on a black box descriptor
1085 void Package::PrintHelpDescriptor(const std::string& name, bool full) const
1087 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()
1088 <<">::PrintHelpDescriptor(\""
1089 <<name<<"\")"<<bbtkendl);
1091 DescriptorMapType::const_iterator i = mDescriptorMap.find(name);
1092 if (i == mDescriptorMap.end())
1094 bbtkDebugDecTab("kernel",8);
1095 bbtkError("The package <"<<GetName()<<"> does not contains the black box <"<<name<<">");
1097 // bbtkMessage("help",1,"["<<GetName()<<"] ");
1098 i->second->GetHelp(full);
1099 bbtkDebugDecTab("kernel",8);
1102 //==========================================================================
1105 //==========================================================================
1106 /// Returns true iff the package contains the box of name boxname
1107 bool Package::ContainsDescriptor(const std::string& name) const
1109 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()
1110 <<">::ContainsDescriptor(\""
1111 <<name<<"\")"<<bbtkendl);
1113 DescriptorMapType::const_iterator i = mDescriptorMap.find(name);
1114 if (i == mDescriptorMap.end())
1116 bbtkDebugDecTab("kernel",8);
1119 bbtkDebugDecTab("kernel",8);
1122 //==========================================================================
1126 //==========================================================================
1127 void Package::CreateHtmlPage(const std::string& filename,
1128 const std::string& caller,
1129 const std::string& source,
1130 const std::string& custom_header,
1131 const std::string& custom_title,
1134 bool relative_link ) const
1136 bbtkDebugMessageInc("kernel",9,"Package<"<<GetName()<<">::CreateHtmlPage(\""
1137 <<filename<<"\")"<<bbtkendl);
1139 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1133"<<std::endl;
1141 //---------------------
1144 s.open(filename.c_str());
1147 bbtkError("Package "<<GetName()<<" : CreateHtmlPage : could not open file '"<<filename<<"'");
1150 //----------------------
1152 std::string title = "BBTK Package "+GetName()+" "+GetVersion();
1154 if (custom_title.length() != 0) title = custom_title;
1156 s << "<html lang=\"en\">\n";
1158 s << "<title>" << title << "</title>\n";
1159 s << "<meta http-equiv=\"Content-Type\" content=\"text/html\">\n";
1160 s << "<meta name=\"description\" content=\""<<title<<"\">\n";
1161 s << "<meta name=\"generator\" content=\"\">\n";
1162 s << "<link title=\"Top\" rel=\"top\" href=\"#Top\">\n";
1163 //<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
1164 s << "<meta http-equiv=\"Content-Style-Type\" content=\"text/css\"><style type=\"text/css\"><!--\n";
1165 s << "pre.display { font-family:inherit }\n";
1166 s << "pre.format { font-family:inherit }\n";
1167 s << "pre.smalldisplay { font-family:inherit; font-size:smaller }\n";
1168 s << "pre.smallformat { font-family:inherit; font-size:smaller }\n";
1169 s << "pre.smallexample { font-size:smaller }\n";
1170 s << "pre.smalllisp { font-size:smaller }\n";
1171 s << "span.sc { font-variant:small-caps }\n";
1172 s << "span.roman { font-family:serif; font-weight:normal; } \n";
1173 s << "span.sansserif { font-family:sans-serif; font-weight:normal; }\n";
1174 s << "--></style>\n";
1176 //----------------------
1178 //----------------------
1181 s << "<a name=\"Top\"></a>\n";
1183 //----------------------
1185 if ( custom_header.length() != 0)
1187 if ( custom_header != "none" )
1190 in.open(custom_header.c_str());
1193 bbtkError("Could not open file \""<<custom_header<<"\"");
1198 in.getline(buffer,512);
1199 std::string line(buffer);
1206 s << "<object data=\"" << custom_header
1207 << "\" type = \"text/html\"\"style=\"width: 1200px; height: 400px;\"> Warning: "
1208 << custom_header <<" could not be embedded.</object>\n";
1217 s << "<h1 class=\"settitle\">"<<title<<"</h1>\n";
1218 s << "<p><TABLE cellspacing=0 cellpadding=3>\n";
1219 s << "<TR><TD style='vertical-align: top;'><b> Description </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1220 << GetDescription() << "</TD></TR>\n";
1221 s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1222 << GetAuthor() << "</TD></TR>\n";
1223 s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1224 << GetCategory() << "</TD></TR>\n";
1225 s << "<TR><TD style='vertical-align: top;'><b> Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1226 << GetVersion() << "</TD></TR>\n";
1227 s << "<TR><TD style='vertical-align: top;'><b> bbtk Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1228 << bbtk::GetVersion() << "</TD></TR>\n";
1231 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1225"<<std::endl;
1232 //-------------------
1233 // Table of contents
1235 // s << "<div class=\"contents\">\n";
1236 s << "<p><b> Black Boxes : </b>\n";
1239 s << "<p><TABLE cellspacing=0 cellpadding=3>\n";
1241 DescriptorMapType::const_iterator i;
1242 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1236"<<std::endl;
1243 for (i=mDescriptorMap.begin(); i!=mDescriptorMap.end(); ++i) {
1244 if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD)
1247 std::string name = i->second->GetTypeName();
1248 Utilities::html_format(name);
1249 std::string descr = i->second->GetDescription();
1250 //Utilities::html_format(descr);
1251 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1246"<<std::endl;
1253 s << "<TD style='vertical-align: top;'>";
1254 s << " <a name=\"toc_"<<name
1255 <<"\" href=\"#"<<name<<"\">"
1258 s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
1267 //-------------------
1269 if (mAdaptorMap.size()>0)
1271 // s << "<div class=\"contents\">\n";
1272 s << "<p><b> Adaptors : </b>\n";
1274 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1268"<<std::endl;
1275 // DescriptorMapType::const_iterator i;
1276 s << "<p><TABLE cellspacing=0 cellpadding=3>\n";
1277 for (i=mDescriptorMap.begin(); i!=mDescriptorMap.end();++i)
1279 if ( i->second->GetKind() == BlackBoxDescriptor::STANDARD)
1282 std::string name = i->second->GetTypeName();
1283 Utilities::html_format(name);
1284 std::string descr = i->second->GetDescription();
1287 s << "<TD style='vertical-align: top;'>";
1288 s << " <a name=\"toc_"<<name
1289 <<"\" href=\"#"<<name<<"\">"
1292 s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
1302 // s << "<div class=\"node\">\n";
1304 // s << "<p><hr>\n";
1305 // s << "<a name=\"Top\"></a>\n";
1306 // s << "Top: <a rel=\"top\" accesskey=\"t\" href=\"#Top\">Top</a>\n";
1307 // s << "Previous: <a rel="previous" accesskey="p" href="#dir">(dir)</a>,
1308 // s << "Up: <a rel="up" accesskey="u" href="#dir">(dir)</a>
1312 //----------------------
1315 //-------------------
1316 // Computes output directory from filename to pass it to
1317 // BlackBoxDescriptor::InsertHtmlHelp
1320 std::string::size_type slash_position = filename.find_last_of("/\\");
1323 if (slash_position != std::string::npos) {
1324 if (slash_position == 0)
1326 dir = filename.substr(0,slash_position);
1329 for (i=mDescriptorMap.begin();
1330 i!=mDescriptorMap.end();
1333 i->second->InsertHtmlHelp(s,detail,level,dir,relative_link);
1336 //----------------------
1341 ptm = gmtime ( &rawtime );
1344 s << "Automatically generated by <b>"<<caller<<"</b> "//from <b>"
1347 << ptm->tm_mday << "/" << ptm->tm_mon << "/" << ptm->tm_year+1900
1348 << " - " << ptm->tm_hour << ":" << ptm->tm_min << " GMT\n";
1349 s << "</body></html>\n";
1351 //----------------------
1354 bbtkDebugDecTab("kernel",9);
1356 //==========================================================================
1358 //==========================================================================
1359 std::string Package::GetObjectName() const
1361 return std::string("Package '")+mName+std::string("'");
1363 //==========================================================================
1365 //==========================================================================
1366 std::string Package::GetObjectInfo() const
1368 std::stringstream i;
1369 i << " - "<<mDescriptorMap.size() << " boxes" << std::endl;
1370 if (mDynamicLibraryHandler)
1372 i<< " - Loaded from dynamic library"<<std::endl;
1376 //==========================================================================
1379 //==========================================================================
1380 size_t Package::GetObjectSize() const
1382 size_t s = Superclass::GetObjectSize();
1383 s += Package::GetObjectInternalSize();
1386 //==========================================================================
1387 //==========================================================================
1388 size_t Package::GetObjectInternalSize() const
1390 size_t s = sizeof(Package);
1393 //==========================================================================
1394 //==========================================================================
1395 size_t Package::GetObjectRecursiveSize() const
1397 size_t s = Superclass::GetObjectRecursiveSize();
1398 s += Package::GetObjectInternalSize();
1400 DescriptorMapType::const_iterator i;
1401 for (i = mDescriptorMap.begin(); i!=mDescriptorMap.end(); ++i )
1403 s += i->second->GetObjectRecursiveSize();
1407 //==========================================================================
1408 void Package::GetBoxesInside(NodeTreeC& tree, int cont)
1410 DescriptorMapType::const_iterator i;
1411 std::cout<<"*********a********"<<std::endl;
1412 for (i=mDescriptorMap.begin(); i!=mDescriptorMap.end(); ++i)
1414 i->second->GetBoxesInside(tree, cont);
1415 std::cout<<"*****************"<<std::endl;
1418 //==========================================================================
1419 //==========================================================================
1420 std::set<Package::WeakPointer>
1421 Package::mReleasedDynamicallyLoadedPackages;
1422 //==========================================================================