2 /*=========================================================================
4 Module: $RCSfile: bbtkPackage.cxx,v $
6 Date: $Date: 2012/11/14 07:12:00 $
7 Version: $Revision: 1.36 $
8 =========================================================================*/
10 /* ---------------------------------------------------------------------
12 * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
13 * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
15 * This software is governed by the CeCILL-B license under French law and
16 * abiding by the rules of distribution of free software. You can use,
17 * modify and/ or redistribute the software under the terms of the CeCILL-B
18 * license as circulated by CEA, CNRS and INRIA at the following URL
19 * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
20 * or in the file LICENSE.txt.
22 * As a counterpart to the access to the source code and rights to copy,
23 * modify and redistribute granted by the license, users are provided only
24 * with a limited warranty and the software's author, the holder of the
25 * economic rights, and the successive licensors have only limited
28 * The fact that you are presently reading this means that you have had
29 * knowledge of the CeCILL-B license and that you accept its terms.
30 * ------------------------------------------------------------------------ */
34 *\brief Class bbtk::Package : registers black boxes descriptors and is able to create instances of the black boxes registered.
36 #include "bbtkPackage.h"
37 #include "bbtkComplexBlackBoxDescriptor.h"
38 #include "bbtkMessageManager.h"
39 #include "bbtkConfigurationFile.h"
42 #include "bbtkUtilities.h"
49 //==========================================================================
50 /// Creates a new package
51 Package::Pointer Package::New(const std::string& name,
52 const std::string& author,
53 const std::string& description,
54 const std::string& version)
56 bbtkDebugMessage("object",1,"##> Package::New('"<<name<<"',...)"
58 Package::Pointer p = MakePointer(new Package(name,
62 bbtkDebugMessage("object",2,"<## Package::New('"<<name<<"',...)"
66 //==========================================================================
68 //==========================================================================
69 /// Ctor with the name of the package
70 Package::Package(const std::string& name,
71 const std::string& author,
72 const std::string& description,
73 const std::string& version)
75 mDynamicLibraryHandler(0),
78 mDescription(description),
81 bbtkDebugMessage("object",2,"==> Package('"<<name<<"',...)"
83 std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
84 char c = default_doc_dir.c_str()[strlen(default_doc_dir.c_str())-1];
85 std::string url = default_doc_dir;
86 if (c != '/' && c !='\\') url = url + "/";
87 url = url + "temp_dir/" + name + "/index.html";
90 SetDocRelativeURL("Relative url not set");
93 std::string relurl(BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH));
94 relurl += "/packages/"+name+"/bbdoc/index.html";
95 std::string url = ConfigurationFile::GetInstance().Get_url()
98 SetDocRelativeURL(relurl);
101 // std::cout << " url=["<<url<<"]"<<std::endl;
102 // std::cout << "relurl=["<<relurl<<"]"<<std::endl;
103 bbtkDebugMessage("object",2,"<== Package::Package('"<<name<<"',...) OK"
107 //==========================================================================
111 //==========================================================================
115 bbtkDebugMessage("object",2,"==> ~Package(\""<<mName<<"\")"<<bbtkendl);
117 //==========================================================================
120 //==========================================================================
121 void PackageReleaseBlackBoxDescriptorInternal(Package::WeakPointer pack,
122 const std::string& descname)
124 // Try to release descriptor
125 std::string packname = pack.lock()->GetName();
127 bbtkDebugMessage("package",5,"--- Releasing descriptor '"
128 <<packname<<"::"<<descname<<"'"<<bbtkendl);
131 Package::DescriptorMapType::iterator desc =
132 pack.lock()->GetDescriptorMap().find(descname);
133 if (desc == pack.lock()->GetDescriptorMap().end())
135 bbtkDebugMessage("package",5,
136 " Descriptor has already been released"
140 // bbtkDebugMessage("package",3,
141 // " Trying unreferencing it ... "<<std::endl);
142 BlackBoxDescriptor::WeakPointer pdesc = desc->second;
143 desc->second.reset();
144 // if it is dead : remove it
147 bbtkDebugMessage("package",2," ==> '"<<packname<<"::"<<descname<<"' Descriptor expired"<<bbtkendl);
150 bbtkDebugMessage("package",2,
151 " ... and caused its package death"
155 desc = pack.lock()->GetDescriptorMap().find(descname);
156 if (desc != pack.lock()->GetDescriptorMap().end()) pack.lock()->GetDescriptorMap().erase(desc);
157 } else { //pdesc.expired
158 bbtkDebugMessage("package",5," ... Descriptor still alive ("
159 <<pdesc.use_count()<<" refs)"
161 pack.lock()->GetDescriptorMap()[descname] = pdesc.lock();
164 //==========================================================================
167 //==========================================================================
169 void Package::Release(Package::WeakPointer pack)
171 std::string packname = pack.lock()->mName;
172 bbtkDebugMessage("package",1,"==> Package::Release('"<<
173 packname<<"')"<<bbtkendl);
175 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
176 long ndesc = pack.lock()->GetDescriptorMap().size();
177 long nrefs = pack.use_count();
179 bbtkDebugMessage("package",5," "<<nrefs<<" refs / "
180 <<ndesc<<" descr / dyn="
183 // A package is "free" from any external reference iff :
184 // i) It is not dynamically loaded and nrefs == ndesc
185 // (each desc references its package) or
186 // ii) It is dynamically loaded and nrefs == ndesc + 1
187 // (A dynamic library holds a static pointer on the package it contains
188 // which is allocated when the PACKAGENAMEGetPackage() func is called,
189 // and descallocated (reset) by PACKAGENAMEDeletePackage())
190 if (nrefs == ndesc + dyn)
192 bbtkDebugMessage("package",5,
193 " -> No more external ref : checking descriptors"
195 // We must take care that removing refs on descriptors
196 // can lead to their deletion which can in turn unref
197 // internal boxes which can release their descriptors hence
198 // call Package::ReleaseBlackBoxDescriptor
199 // As a consequence during descriptors release :
200 // 1) The map can change dynamically : we cannot iterate over it
201 // as any iterator can become invalid
202 // 2) The package can auto-destruct : we must test its existence
203 // after each release
204 // We must also take care of not locking the package pointer
205 // or any ref count check in Package::ReleaseBlackBoxDescriptor
208 // The list of descriptors names at start
209 std::vector<std::string> descnamelist;
210 DescriptorMapType::iterator i;
211 for (i=pack.lock()->mDescriptorMap.begin();
212 i!= pack.lock()->mDescriptorMap.end();
214 descnamelist.push_back(i->first);
216 // Iterator over the initial names
217 std::vector<std::string>::iterator descname;
218 for (descname=descnamelist.begin();
219 descname!=descnamelist.end();
222 // Is package still alive ?
225 bbtkDebugMessage("package",1,"--- Package::Release('"<<
227 <<"') : package expired during release : bailing out"<<bbtkendl);
232 BlackBoxDescriptor::Pointer desc = pack.lock()->mDescriptorMap[*descname];
233 if ( (dyn==0) || (boost::dynamic_pointer_cast<ComplexBlackBoxDescriptor>(desc)) )
235 PackageReleaseBlackBoxDescriptorInternal(pack,*descname);
238 PackageReleaseBlackBoxDescriptorInternal(pack,*descname);
244 UnLoadDynamicLibrary(pack);
245 // Unload orphan dl packages
246 Package::UnLoadReleasedDynamicallyLoadedPackages();
250 #ifdef BBTK_COMPILE_DEBUG_MESSAGES
252 bbtkDebugMessage("package",2,"<== Package::Release('"<<
253 packname<<"')"<<bbtkendl);
257 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
258 long ndesc = pack.lock()->GetDescriptorMap().size();
259 long nrefs = pack.use_count();
261 bbtkDebugMessage("package",1," ... Package still alive ("
263 <<ndesc<<" descr / dyn="
264 <<dyn<<")"<<std::endl);
268 bbtkDebugMessage("package",1," ... Package has been released"
273 //==========================================================================
275 //==========================================================================
276 /// "Releases" the package
277 /// Signals the package that it can free the given descriptor
278 /// if they are no more used and free itself if it is no
280 /// Note : Any non-weak pointer on the package must have been freed
281 void Package::ReleaseBlackBoxDescriptor(Package::WeakPointer pack,
282 BlackBoxDescriptor::WeakPointer descr)
284 std::string packname = pack.lock()->mName;
285 std::string dname = descr.lock()->GetTypeName();
286 bbtkDebugMessage("package",3,"==> Package::ReleaseBlackBoxDescriptor('"<<
287 packname<<"','"<<dname<<"') : refs="
288 <<descr.use_count()<<bbtkendl);
290 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
291 long ndesc = pack.lock()->GetDescriptorMap().size();
292 long nrefs = pack.use_count();
294 bbtkDebugMessage("package",5," "<<nrefs<<" refs / "
295 <<ndesc<<" descr / dynamically loaded = "
298 // A package is "free" from any external reference iff :
299 // i) It is not dynamically loaded and nrefs == ndesc
300 // (each desc references its package) or
301 // ii) It is dynamically loaded and nrefs == ndesc + 1
302 // (A dynamic library holds a static pointer on the package it contains
303 // which is allocated when the PACKAGENAMEGetPackage() func is called,
304 // and descallocated (reset) by PACKAGENAMEDeletePackage())
305 if (nrefs == ndesc + dyn)
310 PackageReleaseBlackBoxDescriptorInternal(pack,dname);
312 PackageReleaseBlackBoxDescriptorInternal(pack,dname);
316 // If the package is released and dynamically loaded
317 // then put it in the static list mReleasedDynamicallyLoadedPackages
318 UnLoadDynamicLibrary(pack,false);
320 bbtkDebugMessage("package",4,"<== Package::ReleaseBlackBoxDescriptor('"<<
321 packname<<"','"<<dname<<"'): refs="
322 <<descr.use_count()<<bbtkendl);
326 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
327 long ndesc = pack.lock()->GetDescriptorMap().size();
328 long nrefs = pack.use_count();
330 bbtkDebugMessage("package",3," ... Package still alive ("
332 <<ndesc<<" descr / dyn="
333 <<dyn<<")"<<std::endl);
337 bbtkDebugMessage("package",3," ... Package has been released"
342 //==========================================================================
344 //==========================================================================
345 /// Opens a dynamic library which contains a bbtk package
346 /// Returns the handler
347 /// Load the package management symbols from the lib
348 /// returns false if a problem occured hence can be used
349 /// to test that a dyn lib is a valid bbtk package lib
350 /// NB : The BBTK version exported from the library
351 /// is tested against the current bbtk version
352 DynamicLibraryHandler Package::OpenDynamicLibrary( const std::string& libname,const std::string& package_name,
353 DLGetPackageFunction& getpack, DLDeletePackageFunction& delpack)
355 bbtkDebugMessage("package",3,"==> Package::OpenDynamicLibrary("
356 <<libname<<")"<<std::endl);
357 #if defined(__GNUC__)
361 handler = dlopen(libname.c_str(), BBTK_RTLD_TIME | BBTK_RTLD_SCOPE );
362 //EED handler = dlopen(libname.c_str(), RTLD_LAZY | RTLD_LOCAL );
366 bbtkMessage("package",0,
367 "BBTK ..ERROR.. loading could not open shared library [" <<libname<<"] : "
368 <<dlerror() << std::endl);
372 bbtkDebugMessage("package",3,"* Shared lib ["<<libname<<"] open"<<std::endl);
374 // Loads the Package bbtk version function
375 std::string getvername(package_name);
376 getvername += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME);
377 DLGetPackageBBTKVersionFunction getbbtkversion = (DLGetPackageBBTKVersionFunction)(dlsym(handler,getvername.c_str()));
380 bbtkDebugMessage("package",3,"***"<<std::endl);
381 bbtkMessage("package",0,
382 "BBTK ..ERROR.. loading shared library ["<<libname
383 <<"] is not a valid bbtk package."
384 <<" Symbol ["<<getvername<<"] :"<<dlerror()<< std::endl);
389 bbtkDebugMessage("package",3,"* Symbol ["<<getvername
390 <<"] found"<<std::endl);
392 if (getbbtkversion() != bbtk::GetVersion())
394 bbtkMessage("package",0,
395 "BBTK ..ERROR.. loading: "<<package_name
396 <<" - Shared library ["<<libname
397 <<"] was build with bbtk version "
399 <<" but the current program runs with version "
400 <<bbtk::GetVersion()<<" : cannot load it. You have to recompile your BBTK-Package."<<std::endl);
406 bbtkDebugMessage("package",3,"* Package bbtk version '"<<getbbtkversion()<<"' matches"<<std::endl);
407 // Loads the Package get function
408 std::string getpackname(package_name);
409 getpackname += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_FUNCTION_NAME);
410 getpack = (DLGetPackageFunction)(dlsym(handler, getpackname.c_str()));
413 bbtkMessage("package",0,
414 "BBTK ..ERROR.. loading shared library ["<<libname
415 <<"] is not a valid bbtk package."
416 <<" Symbol ["<<getpackname<<"] :"<<dlerror()<< std::endl);
421 bbtkDebugMessage("package",3,"* Symbol ["<<getpackname<<"] found"<<std::endl);
422 // Loads the Package delete function
424 std::string delpackname(package_name);
425 delpackname += BBTK_STRINGIFY_SYMBOL(BBTK_DEL_PACKAGE_FUNCTION_NAME);
426 delpack = (DLDeletePackageFunction)(dlsym(handler, delpackname.c_str()));
429 bbtkMessage("package",0,
430 "BBTK ..ERROR.. loading shared library ["<<libname
431 <<"] is not a valid bbtk package."
432 <<" Symbol ["<<delpackname<<"] :"<<dlerror()<< std::endl);
436 bbtkDebugMessage("package",3,"* Symbol ["<<delpackname<<"] found"<<std::endl);
437 #elif defined(_WIN32)
443 handler = LoadLibrary(libname.c_str());
446 bbtkMessage("package",0,
447 "BBTK ..ERROR.. could not open shared library [" <<libname<<"]"
449 DWORD dwErrorCode = 0;
450 dwErrorCode = GetLastError();
451 bbtkMessage("package",2,
452 "Windows Error: [" << dwErrorCode <<"]"
458 // Loads the Package bbtk version function
459 std::string getvername(package_name);
460 getvername += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME);
461 DLGetPackageBBTKVersionFunction getbbtkversion = (DLGetPackageBBTKVersionFunction)(GetProcAddress(handler, getvername.c_str()));
465 FreeLibrary(handler);
466 bbtkMessage("package",0,
467 "BBTK ..ERROR.. loading shared library ["<<libname
468 <<"] is not a valid bbtk package."
469 <<" Symbol ["<<getbbtkversion<<"] not found"<< std::endl);
474 if (getbbtkversion() != bbtk::GetVersion())
476 FreeLibrary(handler);
477 bbtkMessage("package",0,
478 "BBTK ..ERROR.. loading: "<<package_name
479 <<" - Shared library ["<<libname
480 <<"] was build with bbtk version "
482 <<" but the current program runs with version "
483 <<bbtk::GetVersion()<<" : cannot load it. You have to recompile your BBTK-Package."<<std::endl);
487 // Loads the Package get function
488 std::string getpackname(package_name);
489 getpackname += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_FUNCTION_NAME);
490 getpack = (DLGetPackageFunction)(GetProcAddress(handler, getpackname.c_str()));
493 FreeLibrary(handler);
494 bbtkMessage("package",0,
495 "BBTK ..ERROR.. loading shared library ["<<libname
496 <<"] is not a valid bbtk package."
497 <<" Symbol ["<<getpackname<<"] not found"<< std::endl);
501 // Loads the Package delete function
502 std::string delpackname(package_name);
503 delpackname += BBTK_STRINGIFY_SYMBOL(BBTK_DEL_PACKAGE_FUNCTION_NAME);
504 delpack = (DLDeletePackageFunction)(GetProcAddress(handler, delpackname.c_str()));
507 FreeLibrary(handler);
508 bbtkMessage("package",0,
509 "BBTK ..ERROR.. loading shared library ["<<libname
510 <<"] is not a valid bbtk package."
511 <<" Symbol ["<<delpackname<<"] not found"<< std::endl);
516 bbtkError("neither __GNUC__ nor _WIN32 ?!? How did you compile ?");
521 //==========================================================================
523 //==========================================================================
524 /// Loads a package from a dynamic library
525 Package::Pointer Package::CreateFromDynamicLibrary(const std::string& libname,
526 const std::string& pkgname,
527 const std::string& path)
529 bbtkDebugMessage("package",1,"==> Package::CreateFromDynamicLibrary("
530 <<libname<<")"<<std::endl);
532 DLGetPackageFunction gf;
533 DLDeletePackageFunction df;
534 DynamicLibraryHandler h = Package::OpenDynamicLibrary(libname,
537 if (h==0) return Package::Pointer();
538 Package::Pointer p = gf();
539 p->mDynamicLibraryHandler = h;
540 p->mDLDeletePackageFunction = df;
542 std::string separator =
543 ConfigurationFile::GetInstance().Get_file_separator ();
544 //BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
545 std::string docreldoc =
546 separator + "bbdoc" + separator + pkgname + separator + "index.html";
548 ".." + separator + ".." + docreldoc;
549 std::string doc = path + separator + ".." + separator
550 + BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
554 p->SetDocRelativeURL(reldoc);
556 bbtkDebugMessage("package",2,"<== Package::CreateFromDynamicLibrary("
557 <<libname<<") .. OK"<<std::endl);
560 //==========================================================================
565 //==========================================================================
566 /// UnLoads the package dynamic library (if any)
567 void Package::UnLoadDynamicLibrary(Package::WeakPointer pack, bool doit)
569 if (pack.expired() || (!pack.lock()->mDynamicLibraryHandler))
572 std::string packname = pack.lock()->GetName();
573 bbtkDebugMessage("package",5,"==> Package::UnLoadDynamicLibrary('"
577 if (!pack.lock()->GetDescriptorMap().empty())
580 bbtkDebugMessage("package",5," Package not empty ... abort"
584 bbtkGlobalError("Package::UnLoadDynamicLibrary('"<<packname<<") : "
585 <<"DescriptorMap not empty "
586 <<BBTK_INTERNAL_ERROR_MESSAGE);
590 if (pack.use_count()!=1)
592 bbtkGlobalError("Package::UnLoadDynamicLibrary('"<<packname<<") : "
593 <<"empty dl package with external refs"
594 <<BBTK_INTERNAL_ERROR_MESSAGE);
600 bbtkDebugMessage("package",5,"==> dynamic library for package '"
601 <<packname<<"' closed"
606 mReleasedDynamicallyLoadedPackages.insert(pack);
607 bbtkDebugMessage("package",1,"==> package '"<<packname
608 <<"' put in the 'to unload' list"
612 bbtkDebugMessage("package",5,"<== Package::UnLoadDynamicLibrary('"
616 //==========================================================================
618 //==========================================================================
619 /// UnLoads released packages that were loaded dynamically
620 /// see UnLoadDynamicLibrary and ReleaseBlackBoxDescriptor
621 void Package::UnLoadReleasedDynamicallyLoadedPackages()
623 bbtkDebugMessage("package",5,"==> Package::UnLoadReleasedDynamicallyLoadedPackages()"<<std::endl);
625 std::set<Package::WeakPointer>::iterator i;
628 if(mReleasedDynamicallyLoadedPackages.size()>0){
629 for (i=mReleasedDynamicallyLoadedPackages.begin();
630 i!=mReleasedDynamicallyLoadedPackages.end();
633 if (!i->expired()) UnLoad(*i);
637 bbtkDebugMessage("package",5,"<== Package::UnLoadReleasedDynamicallyLoadedPackages()"<<std::endl);
639 //==========================================================================
641 //==========================================================================
642 void Package::UnLoad(Package::WeakPointer pack)
644 std::string packname = pack.lock()->GetName();
645 bbtkDebugMessage("package",6,"==> Package::UnLoad("<<packname<<")"<<std::endl);
647 Package* p = pack.lock().get();
649 DynamicLibraryHandler h = p->mDynamicLibraryHandler;
651 // deletes the package
652 p->mDLDeletePackageFunction();
654 // closes the dl handler
655 #if defined(__GNUC__)
658 printf("EED Package::UnLoad ERROR %s\n", packname.c_str() );
659 bbtkWarning("Failed to close dynamic library for package '"<<packname
663 #elif defined(_WIN32)
667 bbtkDebugMessage("package",1,"==> dynamic library for package '"
668 <<packname<<"' closed"
670 bbtkDebugMessage("package",6," ... dynamic library unloaded"<<std::endl);
672 //==========================================================================
674 bool Package::ifBoxExist( std::string type)
677 DescriptorMapType::const_iterator i = mDescriptorMap.find(type);
678 if (i != mDescriptorMap.end())
685 //==========================================================================
686 /// Creates an instance of a black box of type <type> with name <name>
687 BlackBox::Pointer Package::NewBlackBox(const std::string& type,
688 const std::string& name) const
690 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<">::NewBlackBox(\""<<type<<"\",\""<<name<<"\")"<<bbtkendl);
692 DescriptorMapType::const_iterator i = mDescriptorMap.find(type);
693 if (i == mDescriptorMap.end())
695 bbtkDebugDecTab("kernel",8);
696 return BlackBox::Pointer();
698 BlackBox::Pointer bb =i->second->NewBlackBox(name);
699 bbtkDebugDecTab("kernel",8);
703 //==========================================================================
707 //==========================================================================
708 /// Creates an instance of an adaptor of input type <typein> and
709 /// output type <typeout> with name <name>
710 BlackBox::Pointer Package::NewAdaptor(const DataInfo& typein,
711 const DataInfo& typeout,
712 const std::string& name) const
714 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
718 <<name<<"\")"<<bbtkendl);
720 AdaptorKey key(typein,typeout,
721 BlackBoxDescriptor::DEFAULT_ADAPTOR);
722 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
723 if (i == mAdaptorMap.end())
725 bbtkDebugDecTab("kernel",8);
726 return BlackBox::Pointer();
728 BlackBox::Pointer bb =i->second.lock()->NewBlackBox(name);
729 bbtkDebugDecTab("kernel",8);
733 //==========================================================================
735 //==========================================================================
736 /// Creates an instance of an adaptor of input type <typein> and
737 /// output type <typeout> with name <name>
738 BlackBox::Pointer Package::NewWidgetAdaptor(const DataInfo& typein,
739 const DataInfo& typeout,
740 const std::string& name) const
742 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
743 ">::NewWidgetAdaptor("
746 <<name<<"\")"<<bbtkendl);
748 AdaptorKey key(typein,typeout,
749 BlackBoxDescriptor::DEFAULT_GUI);
750 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
751 if (i == mAdaptorMap.end())
753 bbtkDebugDecTab("kernel",8);
754 return BlackBox::Pointer();
756 BlackBox::Pointer bb =i->second.lock()->NewBlackBox(name);
757 bbtkDebugDecTab("kernel",8);
761 //==========================================================================
765 //==========================================================================
766 /// Returns true is the package contains
767 /// an adaptor of input type <typein> and
768 /// output type <typeout>
769 /// If successfull then adaptor contains the black box type name
770 bool Package::FindWidgetAdaptor(const DataInfo& typein,
771 const DataInfo& typeout,
772 std::string& adaptor) const
774 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
775 ">::FindWidgetAdaptor("
777 <<typeout<<")"<<bbtkendl);
779 AdaptorKey key(/*typein*/
780 DataInfo(typeid(void),""),
782 BlackBoxDescriptor::DEFAULT_GUI);
783 // First try to find a single widget adaptor
784 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
785 if (i == mAdaptorMap.end())
787 bbtkDebugDecTab("kernel",8);
790 adaptor = i->second.lock()->GetTypeName();
791 bbtkDebugDecTab("kernel",8);
795 //==========================================================================
799 //==========================================================================
800 /// Returns true is the package contains
801 /// an adaptor of input type <typein> and
802 /// output type <typeout>
803 /// If successfull then adaptor contains the black box type name
804 bool Package::FindAdaptor(const DataInfo& typein,
805 const DataInfo& typeout,
806 std::string& adaptor) const
808 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
811 <<typeout<<")"<<bbtkendl);
813 AdaptorKey key(typein,typeout,
814 BlackBoxDescriptor::DEFAULT_ADAPTOR);
815 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
816 if (i == mAdaptorMap.end())
818 bbtkDebugDecTab("kernel",8);
821 adaptor = i->second.lock()->GetTypeName();
822 bbtkDebugDecTab("kernel",8);
826 //==========================================================================
829 //==========================================================================
830 /// Registers a black box descriptor in the package
831 bool Package::Register(BlackBoxDescriptor::Pointer d)
833 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<">::Register(\""<<d->GetTypeName()<<"\")"<<std::endl);
835 DescriptorMapType::iterator i = mDescriptorMap.find(d->GetTypeName());
836 if (i!=mDescriptorMap.end())
838 bbtkWarning("Package<"<<GetName()<<"> : Trying to register box type <"
839 <<d->GetTypeName()<<"> which is already in the package");
843 mDescriptorMap[d->GetTypeName()] = d;
845 d->SetPackage(GetThisPointer<Package>());
847 // If it is a default adaptor, also register it in the adaptors map
848 if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_ADAPTOR )
850 bbtkDebugMessage("kernel",8,"Package<"<<GetName()<<">::Register(\""<<d->GetTypeName()<<"\") : The box is an adaptor, inserting it in adaptors map ..."<<std::endl);
852 TypeInfo typein = d->GetInputDescriptor("In")->GetTypeInfo();
853 TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
854 DataInfo infoin(typein,d->GetInputDescriptor("In")->GetNature());
855 DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
856 AdaptorKey key(infoin,infoout,d->GetKind());
858 AdaptorMapType::const_iterator i;
859 i = mAdaptorMap.find(key);
860 if (i == mAdaptorMap.end())
862 mAdaptorMap[key] = d;
864 // If already an adaptor registered : error
867 if (i->second.lock()->GetTypeName() != d->GetTypeName())
869 bbtkError("Package <"<<GetName()<<
870 "> : trying to register black box <"
872 <<"> as default adaptor but there is already a default adaptor registered (<"
873 <<i->second.lock()->GetTypeName()<<">)");
877 // If it is a default adaptor, also register it in the adaptors map
878 else if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_GUI)
880 bbtkDebugMessage("kernel",8,"Package<"<<GetName()<<">::Register(\""<<d->GetTypeName()<<"\") : The box is a widget adaptor, inserting it in adaptors map ..."<<std::endl);
882 TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
883 DataInfo infoin(typeid(void),"");
884 DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
885 AdaptorKey key(infoin,infoout,d->GetKind());
887 AdaptorMapType::const_iterator i;
888 i = mAdaptorMap.find(key);
889 if (i == mAdaptorMap.end())
891 mAdaptorMap[key] = d;
893 // If already an adaptor registered : error
896 if (i->second.lock()->GetTypeName() != d->GetTypeName())
898 bbtkError("Package <"<<GetName()<<
899 "> : trying to register black box <"
901 <<"> as default widget adaptor but there is already a default adaptor registered (<"
902 <<i->second.lock()->GetTypeName()<<">)");
908 bbtkDebugDecTab("kernel",8);
912 //==========================================================================
914 //===================================================================
915 void Package::Check() const
917 bbtkMessage("debug",1,"****** Checking Package "<<(void*)this
918 <<" ["<<GetName()<<"]"<<std::endl);
919 DescriptorMapType::const_iterator i;
920 for (i=mDescriptorMap.begin();
921 i!=mDescriptorMap.end();
924 i->second->Check(true);
926 bbtkMessage("debug",1,"****** Checking Package "<<(void*)this
927 <<" ["<<GetName()<<"] ... OK"<<std::endl);
929 //===================================================================
932 //==========================================================================
933 /// Changes the name of a black box type
934 void Package::ChangeDescriptorName( const std::string& oldname, const std::string& newname )
936 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()
937 <<">::ChangeDescriptorName(\""<<oldname
938 <<"\",\""<<newname<<"\")"<<std::endl);
939 // Looking into the bb map
940 DescriptorMapType::iterator i = mDescriptorMap.find(oldname);
941 if (i == mDescriptorMap.end())
943 bbtkDebugDecTab("kernel",8);
944 bbtkError("ChangeDescriptorName : The package <"<<GetName()<<"> does not contains the black box <"<<oldname<<">");
947 i->second->SetTypeName(newname);
948 mDescriptorMap[newname] = i->second;
949 mDescriptorMap.erase(i);
951 bbtkDebugDecTab("kernel",8);
953 //==========================================================================
957 //==========================================================================
958 void Package::PrintHelpListDescriptors(bool description, bool adaptors) const
960 unsigned int lmax = 0;
961 std::vector<std::string> names;
962 std::vector<std::string> kinds;
963 std::vector<std::string> descrs;
965 DescriptorMapType::const_iterator i;
966 for (i=mDescriptorMap.begin();
967 i!=mDescriptorMap.end();
971 ( i->second->GetKind() == BlackBoxDescriptor::STANDARD) )
973 std::string name(" ");
974 name += i->second->GetTypeName();
975 names.push_back(name);
978 if ( i->second->GetKind() == BlackBoxDescriptor::ADAPTOR )
980 kind = std::string("[A]");
982 else if ( i->second->GetKind() ==
983 BlackBoxDescriptor::DEFAULT_ADAPTOR )
985 kind = std::string("[DA]");
987 kinds.push_back(kind);
989 unsigned int l = name.size()+kind.size();
990 if (l>lmax) lmax = l;
996 descr += i->second->GetDescription();
998 descrs.push_back(descr);
1004 offs.append(lmax+3,' ');
1005 std::vector<std::string>::iterator ni,ci,di;
1006 for (ni = names.begin(), ci = kinds.begin(), di = descrs.begin();
1007 ni != names.end(); ++ni, ++ci, ++di)
1010 space.append(lmax - ni->size() - ci->size(),' ');
1011 bbtkMessage("help",1,*ni << space << *ci );
1013 unsigned int dmax = 75 - lmax;
1014 // while (d.size() > dmax )
1017 bbtkMessage("help",1,d.substr(0,dmax) << "..." << std::endl);
1019 bbtkMessage("help",1,d << std::endl);
1020 // d = d.substr(dmax,d.size());
1025 //==========================================================================
1027 //==========================================================================
1028 /// Displays the list of adaptors of the package
1029 void Package::PrintHelpListAdaptors(bool description) const
1031 DescriptorMapType::const_iterator i;
1032 for (i=mDescriptorMap.begin();
1033 i!=mDescriptorMap.end();
1036 if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD )
1038 bbtkMessage("help",1,
1039 " "<<i->second->GetTypeName());
1040 if ( i->second->GetKind() ==
1041 BlackBoxDescriptor::DEFAULT_ADAPTOR )
1043 bbtkMessage("help",1,
1048 bbtkMessage("help",1,
1049 " : "<<i->second->GetDescription());
1052 bbtkMessage("help",1,std::endl);
1056 AdaptorMapType::const_iterator i;
1057 for (i=mAdaptorMap.begin();
1058 i!=mAdaptorMap.end();
1061 bbtkMessage("help",1,
1062 " "<<i->second->GetTypeName());
1065 bbtkMessage("help",1,
1066 " : "<<i->second->GetDescription());
1069 bbtkMessage("help",1,std::endl);
1073 //==========================================================================
1075 //==========================================================================
1076 /// Prints help on a black box descriptor
1077 void Package::PrintHelpDescriptor(const std::string& name, bool full) const
1079 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()
1080 <<">::PrintHelpDescriptor(\""
1081 <<name<<"\")"<<bbtkendl);
1083 DescriptorMapType::const_iterator i = mDescriptorMap.find(name);
1084 if (i == mDescriptorMap.end())
1086 bbtkDebugDecTab("kernel",8);
1087 bbtkError("The package <"<<GetName()<<"> does not contains the black box <"<<name<<">");
1089 // bbtkMessage("help",1,"["<<GetName()<<"] ");
1090 i->second->GetHelp(full);
1091 bbtkDebugDecTab("kernel",8);
1094 //==========================================================================
1097 //==========================================================================
1098 /// Returns true iff the package contains the box of name boxname
1099 bool Package::ContainsDescriptor(const std::string& name) const
1101 bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()
1102 <<">::ContainsDescriptor(\""
1103 <<name<<"\")"<<bbtkendl);
1105 DescriptorMapType::const_iterator i = mDescriptorMap.find(name);
1106 if (i == mDescriptorMap.end())
1108 bbtkDebugDecTab("kernel",8);
1111 bbtkDebugDecTab("kernel",8);
1114 //==========================================================================
1118 //==========================================================================
1119 void Package::CreateHtmlPage(const std::string& filename,
1120 const std::string& caller,
1121 const std::string& source,
1122 const std::string& custom_header,
1123 const std::string& custom_title,
1126 bool relative_link ) const
1128 bbtkDebugMessageInc("kernel",9,"Package<"<<GetName()<<">::CreateHtmlPage(\""
1129 <<filename<<"\")"<<bbtkendl);
1131 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1133"<<std::endl;
1133 //---------------------
1136 s.open(filename.c_str());
1139 bbtkError("Package "<<GetName()<<" : CreateHtmlPage : could not open file '"<<filename<<"'");
1142 //----------------------
1144 std::string title = "BBTK Package "+GetName()+" "+GetVersion();
1146 if (custom_title.length() != 0) title = custom_title;
1148 s << "<html lang=\"en\">\n";
1150 s << "<title>" << title << "</title>\n";
1151 s << "<meta http-equiv=\"Content-Type\" content=\"text/html\">\n";
1152 s << "<meta name=\"description\" content=\""<<title<<"\">\n";
1153 s << "<meta name=\"generator\" content=\"\">\n";
1154 s << "<link title=\"Top\" rel=\"top\" href=\"#Top\">\n";
1155 //<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
1156 s << "<meta http-equiv=\"Content-Style-Type\" content=\"text/css\"><style type=\"text/css\"><!--\n";
1157 s << "pre.display { font-family:inherit }\n";
1158 s << "pre.format { font-family:inherit }\n";
1159 s << "pre.smalldisplay { font-family:inherit; font-size:smaller }\n";
1160 s << "pre.smallformat { font-family:inherit; font-size:smaller }\n";
1161 s << "pre.smallexample { font-size:smaller }\n";
1162 s << "pre.smalllisp { font-size:smaller }\n";
1163 s << "span.sc { font-variant:small-caps }\n";
1164 s << "span.roman { font-family:serif; font-weight:normal; } \n";
1165 s << "span.sansserif { font-family:sans-serif; font-weight:normal; }\n";
1166 s << "--></style>\n";
1168 //----------------------
1170 //----------------------
1173 s << "<a name=\"Top\"></a>\n";
1175 //----------------------
1177 if ( custom_header.length() != 0)
1179 if ( custom_header != "none" )
1182 in.open(custom_header.c_str());
1185 bbtkError("Could not open file \""<<custom_header<<"\"");
1190 in.getline(buffer,512);
1191 std::string line(buffer);
1198 s << "<object data=\"" << custom_header
1199 << "\" type = \"text/html\"\"style=\"width: 1200px; height: 400px;\"> Warning: "
1200 << custom_header <<" could not be embedded.</object>\n";
1209 s << "<h1 class=\"settitle\">"<<title<<"</h1>\n";
1210 s << "<p><TABLE cellspacing=0 cellpadding=3>\n";
1211 s << "<TR><TD style='vertical-align: top;'><b> Description </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1212 << GetDescription() << "</TD></TR>\n";
1213 s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1214 << GetAuthor() << "</TD></TR>\n";
1215 s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1216 << GetCategory() << "</TD></TR>\n";
1217 s << "<TR><TD style='vertical-align: top;'><b> Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1218 << GetVersion() << "</TD></TR>\n";
1219 s << "<TR><TD style='vertical-align: top;'><b> bbtk Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1220 << bbtk::GetVersion() << "</TD></TR>\n";
1223 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1225"<<std::endl;
1224 //-------------------
1225 // Table of contents
1227 // s << "<div class=\"contents\">\n";
1228 s << "<p><b> Black Boxes : </b>\n";
1231 s << "<p><TABLE cellspacing=0 cellpadding=3>\n";
1233 DescriptorMapType::const_iterator i;
1234 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1236"<<std::endl;
1235 for (i=mDescriptorMap.begin(); i!=mDescriptorMap.end(); ++i) {
1236 if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD)
1239 std::string name = i->second->GetTypeName();
1240 Utilities::html_format(name);
1241 std::string descr = i->second->GetDescription();
1242 //Utilities::html_format(descr);
1243 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1246"<<std::endl;
1245 s << "<TD style='vertical-align: top;'>";
1246 s << " <a name=\"toc_"<<name
1247 <<"\" href=\"#"<<name<<"\">"
1250 s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
1259 //-------------------
1261 if (mAdaptorMap.size()>0)
1263 // s << "<div class=\"contents\">\n";
1264 s << "<p><b> Adaptors : </b>\n";
1266 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1268"<<std::endl;
1267 // DescriptorMapType::const_iterator i;
1268 s << "<p><TABLE cellspacing=0 cellpadding=3>\n";
1269 for (i=mDescriptorMap.begin(); i!=mDescriptorMap.end();++i)
1271 if ( i->second->GetKind() == BlackBoxDescriptor::STANDARD)
1274 std::string name = i->second->GetTypeName();
1275 Utilities::html_format(name);
1276 std::string descr = i->second->GetDescription();
1279 s << "<TD style='vertical-align: top;'>";
1280 s << " <a name=\"toc_"<<name
1281 <<"\" href=\"#"<<name<<"\">"
1284 s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
1294 // s << "<div class=\"node\">\n";
1296 // s << "<p><hr>\n";
1297 // s << "<a name=\"Top\"></a>\n";
1298 // s << "Top: <a rel=\"top\" accesskey=\"t\" href=\"#Top\">Top</a>\n";
1299 // s << "Previous: <a rel="previous" accesskey="p" href="#dir">(dir)</a>,
1300 // s << "Up: <a rel="up" accesskey="u" href="#dir">(dir)</a>
1304 //----------------------
1307 //-------------------
1308 // Computes output directory from filename to pass it to
1309 // BlackBoxDescriptor::InsertHtmlHelp
1312 std::string::size_type slash_position = filename.find_last_of("/\\");
1315 if (slash_position != std::string::npos) {
1316 if (slash_position == 0)
1318 dir = filename.substr(0,slash_position);
1321 for (i=mDescriptorMap.begin();
1322 i!=mDescriptorMap.end();
1325 i->second->InsertHtmlHelp(s,detail,level,dir,relative_link);
1328 //----------------------
1333 ptm = gmtime ( &rawtime );
1336 s << "Automatically generated by <b>"<<caller<<"</b> "//from <b>"
1339 << ptm->tm_mday << "/" << ptm->tm_mon << "/" << ptm->tm_year+1900
1340 << " - " << ptm->tm_hour << ":" << ptm->tm_min << " GMT\n";
1341 s << "</body></html>\n";
1343 //----------------------
1346 bbtkDebugDecTab("kernel",9);
1348 //==========================================================================
1350 //==========================================================================
1351 std::string Package::GetObjectName() const
1353 return std::string("Package '")+mName+std::string("'");
1355 //==========================================================================
1357 //==========================================================================
1358 std::string Package::GetObjectInfo() const
1360 std::stringstream i;
1361 i << " - "<<mDescriptorMap.size() << " boxes" << std::endl;
1362 if (mDynamicLibraryHandler)
1364 i<< " - Loaded from dynamic library"<<std::endl;
1368 //==========================================================================
1371 //==========================================================================
1372 size_t Package::GetObjectSize() const
1374 size_t s = Superclass::GetObjectSize();
1375 s += Package::GetObjectInternalSize();
1378 //==========================================================================
1379 //==========================================================================
1380 size_t Package::GetObjectInternalSize() const
1382 size_t s = sizeof(Package);
1385 //==========================================================================
1386 //==========================================================================
1387 size_t Package::GetObjectRecursiveSize() const
1389 size_t s = Superclass::GetObjectRecursiveSize();
1390 s += Package::GetObjectInternalSize();
1392 DescriptorMapType::const_iterator i;
1393 for (i = mDescriptorMap.begin(); i!=mDescriptorMap.end(); ++i )
1395 s += i->second->GetObjectRecursiveSize();
1399 //==========================================================================
1401 //==========================================================================
1402 std::set<Package::WeakPointer>
1403 Package::mReleasedDynamicallyLoadedPackages;
1404 //==========================================================================