1 /*=========================================================================
4 Module: $RCSfile: bbtkPackage.cxx,v $
6 Date: $Date: 2008/10/10 12:25:09 $
7 Version: $Revision: 1.21 $
9 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10 l'Image). All rights reserved. See doc/license.txt or
11 http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
13 This software is distributed WITHOUT ANY WARRANTY; without even
14 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 PURPOSE. See the above copyright notices for more information.
17 =========================================================================*/
20 *\brief Class bbtk::Package : registers black boxes descriptors and is able to create instances of the black boxes registered.
22 #include "bbtkPackage.h"
23 #include "bbtkMessageManager.h"
24 #include "bbtkConfigurationFile.h"
27 #include "bbtkUtilities.h"
34 //==========================================================================
35 /// Creates a new package
36 Package::Pointer Package::New(const std::string& name,
37 const std::string& author,
38 const std::string& description,
39 const std::string& version,
40 const std::string& BBTKVersion)
42 bbtkDebugMessage("object",1,"##> Package::New('"<<name<<"',...)"
44 Package::Pointer p = MakePointer(new Package(name,
49 bbtkDebugMessage("object",2,"<## Package::New('"<<name<<"',...)"
53 //==========================================================================
55 //==========================================================================
56 /// Ctor with the name of the package
57 Package::Package(const std::string& name,
58 const std::string& author,
59 const std::string& description,
60 const std::string& version,
61 const std::string& BBTKVersion)
63 mDynamicLibraryHandler(0),
66 mDescription(description),
69 bbtkDebugMessage("object",2,"==> Package::Package('"<<name<<"',...)"
71 std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
72 char c = default_doc_dir.c_str()[strlen(default_doc_dir.c_str())-1];
73 std::string url = default_doc_dir;
74 if (c != '/' && c !='\\') url = url + "/";
75 url = url + "temp_dir/" + name + "/index.html";
78 SetDocRelativeURL("Relative url not set");
81 std::string relurl(BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH));
82 relurl += "/packages/"+name+"/bbdoc/index.html";
83 std::string url = ConfigurationFile::GetInstance().Get_url()
86 SetDocRelativeURL(relurl);
89 // std::cout << " url=["<<url<<"]"<<std::endl;
90 // std::cout << "relurl=["<<relurl<<"]"<<std::endl;
91 bbtkDebugMessage("object",2,"<== Package::Package('"<<name<<"',...) OK"
95 //==========================================================================
99 //==========================================================================
103 bbtkDebugMessage("object",2,"==> Package::~Package(\""<<mName<<"\")"<<bbtkendl);
104 bbtkDebugMessage("object",2,"<== Package::~Package(\""<<mName<<"\")"<<bbtkendl);
106 //==========================================================================
109 //==========================================================================
110 void PackageReleaseBlackBoxDescriptorInternal(Package::WeakPointer pack,
111 const std::string& descname)
113 // Try to release descriptor
114 std::string packname = pack.lock()->GetName();
116 bbtkDebugMessage("package",5,"--- Releasing descriptor '"
117 <<packname<<"::"<<descname<<"'"<<bbtkendl);
120 Package::BlackBoxMapType::iterator desc =
121 pack.lock()->GetBlackBoxMap().find(descname);
122 if (desc == pack.lock()->GetBlackBoxMap().end())
124 bbtkDebugMessage("package",5,
125 " Descriptor has already been released"
129 // bbtkDebugMessage("package",3,
130 // " Trying unreferencing it ... "<<std::endl);
131 BlackBoxDescriptor::WeakPointer pdesc = desc->second;
132 desc->second.reset();
133 // if it is dead : remove it
136 bbtkDebugMessage("package",2," ==> '"<<packname<<"::"<<descname<<"' Descriptor expired"<<bbtkendl);
139 bbtkDebugMessage("package",2,
140 " ... and caused its package death"
144 desc = pack.lock()->GetBlackBoxMap().find(descname);
145 if (desc != pack.lock()->GetBlackBoxMap().end())
146 pack.lock()->GetBlackBoxMap().erase(desc);
150 bbtkDebugMessage("package",5," ... Descriptor still alive ("
151 <<pdesc.use_count()<<" refs)"
153 pack.lock()->GetBlackBoxMap()[descname] = pdesc.lock();
156 //==========================================================================
159 //==========================================================================
161 void Package::Release(Package::WeakPointer pack)
163 std::string packname = pack.lock()->mName;
164 bbtkDebugMessage("package",1,"==> Package::Release('"<<
165 packname<<"')"<<bbtkendl);
167 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
168 long ndesc = pack.lock()->GetBlackBoxMap().size();
169 long nrefs = pack.use_count();
171 bbtkDebugMessage("package",5," "<<nrefs<<" refs / "
172 <<ndesc<<" descr / dyn="
175 // A package is "free" from any external reference iff :
176 // i) It is not dynamically loaded and nrefs == ndesc
177 // (each desc references its package) or
178 // ii) It is dynamically loaded and nrefs == ndesc + 1
179 // (A dynamic library holds a static pointer on the package it contains
180 // which is allocated when the PACKAGENAMEGetPackage() func is called,
181 // and descallocated (reset) by PACKAGENAMEDeletePackage())
182 if (nrefs == ndesc + dyn)
184 bbtkDebugMessage("package",5,
185 " -> No more external ref : checking descriptors"
187 // We must take care that removing refs on descriptors
188 // can lead to their deletion which can in turn unref
189 // internal boxes which can release their descriptors hence
190 // call Package::ReleaseBlackBoxDescriptor
191 // As a consequence during descriptors release :
192 // 1) The map can change dynamically : we cannot iterate over it
193 // as any iterator can become invalid
194 // 2) The package can auto-destruct : we must test its existence
195 // after each release
196 // We must also take care of not locking the package pointer
197 // or any ref count check in Package::ReleaseBlackBoxDescriptor
200 // The list of descriptors names at start
201 std::vector<std::string> descnamelist;
202 BlackBoxMapType::iterator i;
203 for (i=pack.lock()->mBlackBoxMap.begin();
204 i!= pack.lock()->mBlackBoxMap.end();
206 descnamelist.push_back(i->first);
208 // Iterator over the initial names
209 std::vector<std::string>::iterator descname;
210 for (descname=descnamelist.begin();
211 descname!=descnamelist.end();
214 // Is package still alive ?
217 bbtkDebugMessage("package",1,"--- Package::Release('"<<
219 <<"') : package expired during release : bailing out"<<bbtkendl);
223 PackageReleaseBlackBoxDescriptorInternal(pack,*descname);
228 UnLoadDynamicLibrary(pack);
229 // Unload orphan dl packages
230 Package::UnLoadReleasedDynamicallyLoadedPackages();
237 #ifdef BBTK_COMPILE_DEBUG_MESSAGES
239 bbtkDebugMessage("package",2,"<== Package::Release('"<<
240 packname<<"')"<<bbtkendl);
244 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
245 long ndesc = pack.lock()->GetBlackBoxMap().size();
246 long nrefs = pack.use_count();
248 bbtkDebugMessage("package",1," ... Package still alive ("
250 <<ndesc<<" descr / dyn="
251 <<dyn<<")"<<std::endl);
255 bbtkDebugMessage("package",1," ... Package has been released"
260 //==========================================================================
262 //==========================================================================
263 /// "Releases" the package
264 /// Signals the package that it can free the given descriptor
265 /// if they are no more used and free itself if it is no
267 /// Note : Any non-weak pointer on the package must have been freed
268 void Package::ReleaseBlackBoxDescriptor(Package::WeakPointer pack,
269 BlackBoxDescriptor::WeakPointer descr)
271 std::string packname = pack.lock()->mName;
272 std::string dname = descr.lock()->GetTypeName();
273 bbtkDebugMessage("package",3,"==> Package::ReleaseBlackBoxDescriptor('"<<
274 packname<<"','"<<dname<<"') : refs="
275 <<descr.use_count()<<bbtkendl);
277 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
278 long ndesc = pack.lock()->GetBlackBoxMap().size();
279 long nrefs = pack.use_count();
281 bbtkDebugMessage("package",5," "<<nrefs<<" refs / "
282 <<ndesc<<" descr / dynamically loaded = "
285 // A package is "free" from any external reference iff :
286 // i) It is not dynamically loaded and nrefs == ndesc
287 // (each desc references its package) or
288 // ii) It is dynamically loaded and nrefs == ndesc + 1
289 // (A dynamic library holds a static pointer on the package it contains
290 // which is allocated when the PACKAGENAMEGetPackage() func is called,
291 // and descallocated (reset) by PACKAGENAMEDeletePackage())
292 if (nrefs == ndesc + dyn)
294 PackageReleaseBlackBoxDescriptorInternal(pack,dname);
297 // If the package is released and dynamically loaded
298 // then put it in the static list mReleasedDynamicallyLoadedPackages
299 UnLoadDynamicLibrary(pack,false);
301 bbtkDebugMessage("package",4,"<== Package::ReleaseBlackBoxDescriptor('"<<
302 packname<<"','"<<dname<<"'): refs="
303 <<descr.use_count()<<bbtkendl);
307 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
308 long ndesc = pack.lock()->GetBlackBoxMap().size();
309 long nrefs = pack.use_count();
311 bbtkDebugMessage("package",3," ... Package still alive ("
313 <<ndesc<<" descr / dyn="
314 <<dyn<<")"<<std::endl);
318 bbtkDebugMessage("package",3," ... Package has been released"
323 //==========================================================================
325 //==========================================================================
326 /// Opens a dynamic library which contains a bbtk package
327 /// Returns the handler
328 /// Load the package management symbols from the lib
329 /// returns false if a problem occured hence can be used
330 /// to test that a dyn lib is a valid bbtk package lib
331 /// NB : The BBTK version exported from the library
332 /// is tested against the current bbtk version
333 DynamicLibraryHandler Package::OpenDynamicLibrary
334 ( const std::string& libname,
335 const std::string& package_name,
336 DLGetPackageFunction& getpack,
337 DLDeletePackageFunction& delpack)
339 bbtkDebugMessage("package",3,"==> Package::OpenDynamicLibrary("
340 <<libname<<")"<<std::endl);
341 #if defined(__GNUC__)
345 handler = dlopen(libname.c_str(),
346 BBTK_RTLD_TIME | BBTK_RTLD_SCOPE );
349 bbtkMessage("package",2,
350 "Could not open shared library [" <<libname<<"] : "
351 <<dlerror() << std::endl);
355 bbtkDebugMessage("package",3,"* Shared lib ["<<libname<<"] open"<<std::endl);
357 // Loads the Package bbtk version function
358 std::string getvername(package_name);
360 BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME);
361 DLGetPackageBBTKVersionFunction getbbtkversion
362 = (DLGetPackageBBTKVersionFunction)(dlsym(handler,getvername.c_str()));
365 bbtkDebugMessage("package",3,"***"<<std::endl);
366 bbtkMessage("package",2,
367 "Shared library ["<<libname
368 <<"] is not a valid bbtk package."
369 <<" Symbol ["<<getvername<<"] :"<<dlerror()<< std::endl);
374 bbtkDebugMessage("package",3,"* Symbol ["<<getvername
375 <<"] found"<<std::endl);
377 if (getbbtkversion() != bbtk::GetVersion())
379 bbtkMessage("package",2,
380 "Shared library ["<<libname
381 <<"] was build with bbtk version "
383 <<" but the current program runs with version "
384 <<bbtk::GetVersion()<<" : cannot load it"<<std::endl);
390 bbtkDebugMessage("package",3,"* Package bbtk version '"<<getbbtkversion()<<"' matches"<<std::endl);
391 // Loads the Package get function
392 std::string getpackname(package_name);
393 getpackname += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_FUNCTION_NAME);
394 getpack = (DLGetPackageFunction)(dlsym(handler, getpackname.c_str()));
397 bbtkMessage("package",2,
398 "Shared library ["<<libname
399 <<"] is not a valid bbtk package."
400 <<" Symbol ["<<getpackname<<"] :"<<dlerror()<< std::endl);
405 bbtkDebugMessage("package",3,"* Symbol ["<<getpackname<<"] found"<<std::endl);
406 // Loads the Package delete function
408 std::string delpackname(package_name);
409 delpackname += BBTK_STRINGIFY_SYMBOL(BBTK_DEL_PACKAGE_FUNCTION_NAME);
410 delpack = (DLDeletePackageFunction)(dlsym(handler, delpackname.c_str()));
413 bbtkMessage("package",2,
414 "Shared library ["<<libname
415 <<"] is not a valid bbtk package."
416 <<" Symbol ["<<delpackname<<"] :"<<dlerror()<< std::endl);
420 bbtkDebugMessage("package",3,"* Symbol ["<<delpackname<<"] found"<<std::endl);
421 #elif defined(_WIN32)
427 handler = LoadLibrary(libname.c_str());
430 bbtkMessage("package",2,
431 "Could not open shared library [" <<libname<<"]"
433 DWORD dwErrorCode = 0;
434 dwErrorCode = GetLastError();
435 bbtkMessage("package",2,
436 "Windows Error: [" << dwErrorCode <<"]"
442 // Loads the Package bbtk version function
443 std::string getvername(package_name);
445 BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME);
446 DLGetPackageBBTKVersionFunction getbbtkversion
447 = (DLGetPackageBBTKVersionFunction)(GetProcAddress(handler,
448 getvername.c_str()));
451 FreeLibrary(handler);
452 bbtkMessage("package",2,
453 "Shared library ["<<libname
454 <<"] is not a valid bbtk package."
455 <<" Symbol ["<<getbbtkversion<<"] not found"<< std::endl);
460 if (getbbtkversion() != bbtk::GetVersion())
462 FreeLibrary(handler);
463 bbtkMessage("package",2,
464 "Shared library ["<<libname
465 <<"] was build with bbtk version "
467 <<" but the current program runs with version "
468 <<bbtk::GetVersion()<<" : cannot load it"<<std::endl);
473 // Loads the Package get function
474 std::string getpackname(package_name);
475 getpackname += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_FUNCTION_NAME);
476 getpack = (DLGetPackageFunction)(GetProcAddress(handler, getpackname.c_str()));
479 FreeLibrary(handler);
480 bbtkMessage("package",2,
481 "Shared library ["<<libname
482 <<"] is not a valid bbtk package."
483 <<" Symbol ["<<getpackname<<"] not found"<< std::endl);
487 // Loads the Package delete function
488 std::string delpackname(package_name);
489 delpackname += BBTK_STRINGIFY_SYMBOL(BBTK_DEL_PACKAGE_FUNCTION_NAME);
490 delpack = (DLDeletePackageFunction)(GetProcAddress(handler, delpackname.c_str()));
493 FreeLibrary(handler);
494 bbtkMessage("package",2,
495 "Shared library ["<<libname
496 <<"] is not a valid bbtk package."
497 <<" Symbol ["<<delpackname<<"] not found"<< std::endl);
502 bbtkError("neither __GNUC__ nor _WIN32 ?!? How did you compile ?");
507 //==========================================================================
509 //==========================================================================
510 /// Loads a package from a dynamic library
511 Package::Pointer Package::CreateFromDynamicLibrary(const std::string& libname,
512 const std::string& pkgname,
513 const std::string& path)
515 bbtkDebugMessage("package",1,"==> Package::CreateFromDynamicLibrary("
516 <<libname<<")"<<std::endl);
518 DLGetPackageFunction gf;
519 DLDeletePackageFunction df;
520 DynamicLibraryHandler h = Package::OpenDynamicLibrary(libname,
523 if (h==0) return Package::Pointer();
524 Package::Pointer p = gf();
525 p->mDynamicLibraryHandler = h;
526 p->mDLDeletePackageFunction = df;
528 std::string separator =
529 ConfigurationFile::GetInstance().Get_file_separator ();
530 //BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
531 std::string docreldoc =
532 separator + "bbdoc" + separator + pkgname + separator + "index.html";
534 ".." + separator + ".." + docreldoc;
535 std::string doc = path + separator + ".." + separator
536 + BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
540 p->SetDocRelativeURL(reldoc);
542 bbtkDebugMessage("package",2,"<== Package::CreateFromDynamicLibrary("
543 <<libname<<") .. OK"<<std::endl);
546 //==========================================================================
551 //==========================================================================
552 /// UnLoads the package dynamic library (if any)
553 void Package::UnLoadDynamicLibrary(Package::WeakPointer pack, bool doit)
555 if (pack.expired() || (!pack.lock()->mDynamicLibraryHandler))
559 std::string packname = pack.lock()->GetName();
560 bbtkDebugMessage("package",5,"==> Package::UnLoadDynamicLibrary('"
564 if (!pack.lock()->GetBlackBoxMap().empty())
567 bbtkDebugMessage("package",5," Package not empty ... abort"
571 bbtkGlobalError("Package::UnLoadDynamicLibrary('"<<packname<<") : "
572 <<"BlackBoxMap not empty "
573 <<BBTK_INTERNAL_ERROR_MESSAGE);
578 if (pack.use_count()!=1)
580 bbtkGlobalError("Package::UnLoadDynamicLibrary('"<<packname<<") : "
581 <<"empty dl package with external refs"
582 <<BBTK_INTERNAL_ERROR_MESSAGE);
588 bbtkDebugMessage("package",5,"==> dynamic library for package '"
589 <<packname<<"' closed"
594 mReleasedDynamicallyLoadedPackages.insert(pack);
595 bbtkDebugMessage("package",1,"==> package '"<<packname
596 <<"' put in the 'to unload' list"
601 bbtkDebugMessage("package",5,"<== Package::UnLoadDynamicLibrary('"
606 //==========================================================================
608 //==========================================================================
609 /// UnLoads released packages that were loaded dynamically
610 /// see UnLoadDynamicLibrary and ReleaseBlackBoxDescriptor
611 void Package::UnLoadReleasedDynamicallyLoadedPackages()
613 bbtkDebugMessage("package",5,"==> Package::UnLoadReleasedDynamicallyLoadedPackages()"<<std::endl);
615 std::set<Package::WeakPointer>::iterator i;
616 for (i=mReleasedDynamicallyLoadedPackages.begin();
617 i!=mReleasedDynamicallyLoadedPackages.end();
620 if (!i->expired()) UnLoad(*i);
622 bbtkDebugMessage("package",5,"<== Package::UnLoadReleasedDynamicallyLoadedPackages()"<<std::endl);
624 //==========================================================================
626 //==========================================================================
627 void Package::UnLoad(Package::WeakPointer pack)
629 std::string packname = pack.lock()->GetName();
630 bbtkDebugMessage("package",6,"==> Package::UnLoad("<<packname<<")"<<std::endl);
632 Package* p = pack.lock().get();
634 DynamicLibraryHandler h = p->mDynamicLibraryHandler;
636 // deletes the package
637 p->mDLDeletePackageFunction();
639 // closes the dl handler
640 #if defined(__GNUC__)
642 #elif defined(_WIN32)
646 bbtkDebugMessage("package",1,"==> dynamic library for package '"
647 <<packname<<"' closed"
649 bbtkDebugMessage("package",6," ... dynamic library unloaded"<<std::endl);
651 //==========================================================================
653 //==========================================================================
654 /// Creates an instance of a black box of type <type> with name <name>
655 BlackBox::Pointer Package::NewBlackBox(const std::string& type,
656 const std::string& name) const
658 bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::NewBlackBox(\""<<type<<"\",\""<<name<<"\")"<<bbtkendl);
660 BlackBoxMapType::const_iterator i = mBlackBoxMap.find(type);
661 if (i == mBlackBoxMap.end())
663 bbtkDebugDecTab("Kernel",8);
664 return BlackBox::Pointer();
666 BlackBox::Pointer bb =i->second->NewBlackBox(name);
667 bbtkDebugDecTab("Kernel",8);
671 //==========================================================================
675 //==========================================================================
676 /// Creates an instance of an adaptor of input type <typein> and
677 /// output type <typeout> with name <name>
678 BlackBox::Pointer Package::NewAdaptor(const DataInfo& typein,
679 const DataInfo& typeout,
680 const std::string& name) const
682 bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<
686 <<name<<"\")"<<bbtkendl);
688 AdaptorKey key(typein,typeout,
689 BlackBoxDescriptor::DEFAULT_ADAPTOR);
690 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
691 if (i == mAdaptorMap.end())
693 bbtkDebugDecTab("Kernel",8);
694 return BlackBox::Pointer();
696 BlackBox::Pointer bb =i->second.lock()->NewBlackBox(name);
697 bbtkDebugDecTab("Kernel",8);
701 //==========================================================================
703 //==========================================================================
704 /// Creates an instance of an adaptor of input type <typein> and
705 /// output type <typeout> with name <name>
706 BlackBox::Pointer Package::NewWidgetAdaptor(const DataInfo& typein,
707 const DataInfo& typeout,
708 const std::string& name) const
710 bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<
711 ">::NewWidgetAdaptor("
714 <<name<<"\")"<<bbtkendl);
716 AdaptorKey key(typein,typeout,
717 BlackBoxDescriptor::DEFAULT_GUI);
718 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
719 if (i == mAdaptorMap.end())
721 bbtkDebugDecTab("Kernel",8);
722 return BlackBox::Pointer();
724 BlackBox::Pointer bb =i->second.lock()->NewBlackBox(name);
725 bbtkDebugDecTab("Kernel",8);
729 //==========================================================================
733 //==========================================================================
734 /// Returns true is the package contains
735 /// an adaptor of input type <typein> and
736 /// output type <typeout>
737 /// If successfull then adaptor contains the black box type name
738 bool Package::FindWidgetAdaptor(const DataInfo& typein,
739 const DataInfo& typeout,
740 std::string& adaptor) const
742 bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<
743 ">::FindWidgetAdaptor("
745 <<typeout<<")"<<bbtkendl);
747 AdaptorKey key(/*typein*/
748 DataInfo(typeid(void),""),
750 BlackBoxDescriptor::DEFAULT_GUI);
751 // First try to find a single widget adaptor
752 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
753 if (i == mAdaptorMap.end())
755 bbtkDebugDecTab("Kernel",8);
758 adaptor = i->second.lock()->GetTypeName();
759 bbtkDebugDecTab("Kernel",8);
763 //==========================================================================
767 //==========================================================================
768 /// Returns true is the package contains
769 /// an adaptor of input type <typein> and
770 /// output type <typeout>
771 /// If successfull then adaptor contains the black box type name
772 bool Package::FindAdaptor(const DataInfo& typein,
773 const DataInfo& typeout,
774 std::string& adaptor) const
776 bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<
779 <<typeout<<")"<<bbtkendl);
781 AdaptorKey key(typein,typeout,
782 BlackBoxDescriptor::DEFAULT_ADAPTOR);
783 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
784 if (i == mAdaptorMap.end())
786 bbtkDebugDecTab("Kernel",8);
789 adaptor = i->second.lock()->GetTypeName();
790 bbtkDebugDecTab("Kernel",8);
794 //==========================================================================
797 //==========================================================================
798 /// Registers a black box descriptor in the package
799 bool Package::RegisterBlackBox(BlackBoxDescriptor::Pointer d)
801 bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::RegisterBlackBox(\""<<d->GetTypeName()<<"\")"<<std::endl);
803 BlackBoxMapType::iterator i = mBlackBoxMap.find(d->GetTypeName());
804 if (i!=mBlackBoxMap.end())
806 bbtkWarning("Package<"<<GetName()<<"> : Trying to register box type <"
807 <<d->GetTypeName()<<"> which is already in the package");
811 mBlackBoxMap[d->GetTypeName()] = d;
813 d->SetPackage(GetThisPointer<Package>());
815 // If it is a default adaptor, also register it in the adaptors map
816 if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_ADAPTOR )
818 bbtkDebugMessage("Kernel",8,"Package<"<<GetName()<<">::RegisterBlackBox(\""<<d->GetTypeName()<<"\") : The box is an adaptor, inserting it in adaptors map ..."<<std::endl);
820 TypeInfo typein = d->GetInputDescriptor("In")->GetTypeInfo();
821 TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
822 DataInfo infoin(typein,d->GetInputDescriptor("In")->GetNature());
823 DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
824 AdaptorKey key(infoin,infoout,d->GetKind());
826 AdaptorMapType::const_iterator i;
827 i = mAdaptorMap.find(key);
828 if (i == mAdaptorMap.end())
830 mAdaptorMap[key] = d;
832 // If already an adaptor registered : error
835 if (i->second.lock()->GetTypeName() != d->GetTypeName())
837 bbtkError("Package <"<<GetName()<<
838 "> : trying to register black box <"
840 <<"> as default adaptor but there is already a default adaptor registered (<"
841 <<i->second.lock()->GetTypeName()<<">)");
845 // If it is a default adaptor, also register it in the adaptors map
846 else if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_GUI)
848 bbtkDebugMessage("Kernel",8,"Package<"<<GetName()<<">::RegisterBlackBox(\""<<d->GetTypeName()<<"\") : The box is a widget adaptor, inserting it in adaptors map ..."<<std::endl);
850 TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
851 DataInfo infoin(typeid(void),"");
852 DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
853 AdaptorKey key(infoin,infoout,d->GetKind());
855 AdaptorMapType::const_iterator i;
856 i = mAdaptorMap.find(key);
857 if (i == mAdaptorMap.end())
859 mAdaptorMap[key] = d;
861 // If already an adaptor registered : error
864 if (i->second.lock()->GetTypeName() != d->GetTypeName())
866 bbtkError("Package <"<<GetName()<<
867 "> : trying to register black box <"
869 <<"> as default widget adaptor but there is already a default adaptor registered (<"
870 <<i->second.lock()->GetTypeName()<<">)");
876 bbtkDebugDecTab("Kernel",8);
880 //==========================================================================
882 //===================================================================
883 void Package::CheckBoxes() const
885 bbtkMessage("debug",1,"****** Checking Package "<<(void*)this
886 <<" ["<<GetName()<<"]"<<std::endl);
887 BlackBoxMapType::const_iterator i;
888 for (i=mBlackBoxMap.begin();
889 i!=mBlackBoxMap.end();
892 i->second->Check(true);
894 bbtkMessage("debug",1,"****** Checking Package "<<(void*)this
895 <<" ["<<GetName()<<"] ... OK"<<std::endl);
897 //===================================================================
900 //==========================================================================
901 /// Changes the name of a black box type
902 void Package::ChangeBlackBoxName( const std::string& oldname, const std::string& newname )
904 bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::ChangeBlackBoxName(\""<<oldname<<"\",\""<<newname<<"\")"<<std::endl);
905 // Looking into the bb map
906 BlackBoxMapType::iterator i = mBlackBoxMap.find(oldname);
907 if (i == mBlackBoxMap.end())
909 bbtkDebugDecTab("Kernel",8);
910 bbtkError("ChangeBlackBoxName : The package <"<<GetName()<<"> does not contains the black box <"<<oldname<<">");
913 i->second->SetTypeName(newname);
914 mBlackBoxMap[newname] = i->second;
915 mBlackBoxMap.erase(i);
917 bbtkDebugDecTab("Kernel",8);
919 //==========================================================================
923 //==========================================================================
924 /// Displays the list of black boxes of the package
925 void Package::PrintBlackBoxes(bool description, bool adaptors) const
927 unsigned int lmax = 0;
928 std::vector<std::string> names;
929 std::vector<std::string> kinds;
930 std::vector<std::string> descrs;
932 BlackBoxMapType::const_iterator i;
933 for (i=mBlackBoxMap.begin();
934 i!=mBlackBoxMap.end();
938 ( i->second->GetKind() == BlackBoxDescriptor::STANDARD) )
940 std::string name(" ");
941 name += i->second->GetTypeName();
942 names.push_back(name);
945 if ( i->second->GetKind() == BlackBoxDescriptor::ADAPTOR )
947 kind = std::string("[A]");
949 else if ( i->second->GetKind() ==
950 BlackBoxDescriptor::DEFAULT_ADAPTOR )
952 kind = std::string("[DA]");
954 kinds.push_back(kind);
956 unsigned int l = name.size()+kind.size();
957 if (l>lmax) lmax = l;
963 descr += i->second->GetDescription();
965 descrs.push_back(descr);
971 offs.append(lmax+3,' ');
972 std::vector<std::string>::iterator ni,ci,di;
973 for (ni = names.begin(), ci = kinds.begin(), di = descrs.begin();
974 ni != names.end(); ++ni, ++ci, ++di)
977 space.append(lmax - ni->size() - ci->size(),' ');
978 bbtkMessage("Help",1,*ni << space << *ci );
980 unsigned int dmax = 75 - lmax;
981 // while (d.size() > dmax )
984 bbtkMessage("Help",1,d.substr(0,dmax) << "..." << std::endl);
986 bbtkMessage("Help",1,d << std::endl);
987 // d = d.substr(dmax,d.size());
992 //==========================================================================
994 //==========================================================================
995 /// Displays the list of adaptors of the package
996 void Package::PrintAdaptors(bool description) const
998 BlackBoxMapType::const_iterator i;
999 for (i=mBlackBoxMap.begin();
1000 i!=mBlackBoxMap.end();
1003 if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD )
1005 bbtkMessage("Help",1,
1006 " "<<i->second->GetTypeName());
1007 if ( i->second->GetKind() ==
1008 BlackBoxDescriptor::DEFAULT_ADAPTOR )
1010 bbtkMessage("Help",1,
1015 bbtkMessage("Help",1,
1016 " : "<<i->second->GetDescription());
1019 bbtkMessage("Help",1,std::endl);
1023 AdaptorMapType::const_iterator i;
1024 for (i=mAdaptorMap.begin();
1025 i!=mAdaptorMap.end();
1028 bbtkMessage("Help",1,
1029 " "<<i->second->GetTypeName());
1032 bbtkMessage("Help",1,
1033 " : "<<i->second->GetDescription());
1036 bbtkMessage("Help",1,std::endl);
1040 //==========================================================================
1042 //==========================================================================
1043 /// Prints help on a black box
1044 void Package::HelpBlackBox(const std::string& name, bool full) const
1046 bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::HelpBlackBox(\""
1047 <<name<<"\")"<<bbtkendl);
1049 BlackBoxMapType::const_iterator i = mBlackBoxMap.find(name);
1050 if (i == mBlackBoxMap.end())
1052 bbtkDebugDecTab("Kernel",8);
1053 bbtkError("The package <"<<GetName()<<"> does not contains the black box <"<<name<<">");
1055 // bbtkMessage("Help",1,"["<<GetName()<<"] ");
1056 i->second->GetHelp(full);
1057 bbtkDebugDecTab("Kernel",8);
1060 //==========================================================================
1063 //==========================================================================
1064 /// Returns true iff the package contains the box of name boxname
1065 bool Package::ContainsBlackBox(const std::string& name) const
1067 bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::HelpBlackBox(\""
1068 <<name<<"\")"<<bbtkendl);
1070 BlackBoxMapType::const_iterator i = mBlackBoxMap.find(name);
1071 if (i == mBlackBoxMap.end())
1073 bbtkDebugDecTab("Kernel",8);
1076 bbtkDebugDecTab("Kernel",8);
1079 //==========================================================================
1083 //==========================================================================
1084 void Package::CreateHtmlPage(const std::string& filename,
1085 const std::string& caller,
1086 const std::string& source,
1087 const std::string& custom_header,
1088 const std::string& custom_title,
1091 bool relative_link ) const
1093 bbtkDebugMessageInc("Kernel",9,"Package<"<<GetName()<<">::CreateHtmlPage(\""
1094 <<filename<<"\")"<<bbtkendl);
1096 //---------------------
1099 s.open(filename.c_str());
1102 bbtkError("Package "<<GetName()<<" : CreateHtmlPage : could not open file '"<<filename<<"'");
1105 //----------------------
1107 std::string title = "BBTK Package "+GetName()+" "+GetVersion();
1109 if (custom_title.length() != 0) title = custom_title;
1111 s << "<html lang=\"en\">\n";
1113 s << "<title>" << title << "</title>\n";
1114 s << "<meta http-equiv=\"Content-Type\" content=\"text/html\">\n";
1115 s << "<meta name=\"description\" content=\""<<title<<"\">\n";
1116 s << "<meta name=\"generator\" content=\"\">\n";
1117 s << "<link title=\"Top\" rel=\"top\" href=\"#Top\">\n";
1118 //<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
1119 s << "<meta http-equiv=\"Content-Style-Type\" content=\"text/css\"><style type=\"text/css\"><!--\n";
1120 s << "pre.display { font-family:inherit }\n";
1121 s << "pre.format { font-family:inherit }\n";
1122 s << "pre.smalldisplay { font-family:inherit; font-size:smaller }\n";
1123 s << "pre.smallformat { font-family:inherit; font-size:smaller }\n";
1124 s << "pre.smallexample { font-size:smaller }\n";
1125 s << "pre.smalllisp { font-size:smaller }\n";
1126 s << "span.sc { font-variant:small-caps }\n";
1127 s << "span.roman { font-family:serif; font-weight:normal; } \n";
1128 s << "span.sansserif { font-family:sans-serif; font-weight:normal; }\n";
1129 s << "--></style>\n";
1131 //----------------------
1133 //----------------------
1136 s << "<a name=\"Top\"></a>\n";
1138 //----------------------
1140 if ( custom_header.length() != 0)
1142 if ( custom_header != "none" )
1145 in.open(custom_header.c_str());
1148 bbtkError("Could not open file \""<<custom_header<<"\"");
1153 in.getline(buffer,512);
1154 std::string line(buffer);
1161 s << "<object data=\"" << custom_header
1162 << "\" type = \"text/html\"\"style=\"width: 1200px; height: 400px;\"> Warning: "
1163 << custom_header <<" could not be embedded.</object>\n";
1172 s << "<h1 class=\"settitle\">"<<title<<"</h1>\n";
1173 s << "<p><TABLE cellspacing=0 cellpadding=3>\n";
1174 s << "<TR><TD style='vertical-align: top;'><b> Description </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1175 << GetDescription() << "</TD></TR>\n";
1176 s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1177 << GetAuthor() << "</TD></TR>\n";
1178 s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1179 << GetCategory() << "</TD></TR>\n";
1180 s << "<TR><TD style='vertical-align: top;'><b> Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1181 << GetVersion() << "</TD></TR>\n";
1182 s << "<TR><TD style='vertical-align: top;'><b> bbtk Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1183 << bbtk::GetVersion() << "</TD></TR>\n";
1187 //-------------------
1188 // Table of contents
1190 // s << "<div class=\"contents\">\n";
1191 s << "<p><b> Black Boxes : </b>\n";
1194 s << "<p><TABLE cellspacing=0 cellpadding=3>\n";
1196 BlackBoxMapType::const_iterator i;
1197 for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end(); ++i)
1199 if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD)
1202 std::string name = i->second->GetTypeName();
1203 Utilities::html_format(name);
1204 std::string descr = i->second->GetDescription();
1205 //Utilities::html_format(descr);
1208 s << "<TD style='vertical-align: top;'>";
1209 s << " <a name=\"toc_"<<name
1210 <<"\" href=\"#"<<name<<"\">"
1213 s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
1222 //-------------------
1224 if (mAdaptorMap.size()>0)
1226 // s << "<div class=\"contents\">\n";
1227 s << "<p><b> Adaptors : </b>\n";
1230 // BlackBoxMapType::const_iterator i;
1231 s << "<p><TABLE cellspacing=0 cellpadding=3>\n";
1232 for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end();++i)
1234 if ( i->second->GetKind() == BlackBoxDescriptor::STANDARD)
1237 std::string name = i->second->GetTypeName();
1238 Utilities::html_format(name);
1239 std::string descr = i->second->GetDescription();
1242 s << "<TD style='vertical-align: top;'>";
1243 s << " <a name=\"toc_"<<name
1244 <<"\" href=\"#"<<name<<"\">"
1247 s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
1257 // s << "<div class=\"node\">\n";
1259 // s << "<p><hr>\n";
1260 // s << "<a name=\"Top\"></a>\n";
1261 // s << "Top: <a rel=\"top\" accesskey=\"t\" href=\"#Top\">Top</a>\n";
1262 // s << "Previous: <a rel="previous" accesskey="p" href="#dir">(dir)</a>,
1263 // s << "Up: <a rel="up" accesskey="u" href="#dir">(dir)</a>
1267 //----------------------
1270 //-------------------
1271 // Computes output directory from filename to pass it to
1272 // BlackBoxDescriptor::InsertHtmlHelp
1275 std::string::size_type slash_position = filename.find_last_of("/\\");
1278 if (slash_position != std::string::npos) {
1279 if (slash_position == 0)
1281 dir = filename.substr(0,slash_position);
1284 for (i=mBlackBoxMap.begin();
1285 i!=mBlackBoxMap.end();
1288 i->second->InsertHtmlHelp(s,detail,level,dir,relative_link);
1291 //----------------------
1296 ptm = gmtime ( &rawtime );
1299 s << "Automatically generated by <b>"<<caller<<"</b> "//from <b>"
1302 << ptm->tm_mday << "/" << ptm->tm_mon << "/" << ptm->tm_year+1900
1303 << " - " << ptm->tm_hour << ":" << ptm->tm_min << " GMT\n";
1304 s << "</body></html>\n";
1306 //----------------------
1309 bbtkDebugDecTab("Kernel",9);
1311 //==========================================================================
1313 //==========================================================================
1314 std::string Package::GetObjectName() const
1316 return std::string("Package '")+mName+std::string("'");
1318 //==========================================================================
1320 //==========================================================================
1321 std::string Package::GetObjectInfo() const
1323 std::stringstream i;
1324 i << " - "<<mBlackBoxMap.size() << " boxes" << std::endl;
1325 if (mDynamicLibraryHandler)
1327 i<< " - Loaded from dynamic library"<<std::endl;
1331 //==========================================================================
1334 //==========================================================================
1335 size_t Package::GetObjectSize() const
1337 size_t s = Superclass::GetObjectSize();
1338 s += Package::GetObjectInternalSize();
1341 //==========================================================================
1342 //==========================================================================
1343 size_t Package::GetObjectInternalSize() const
1345 size_t s = sizeof(Package);
1348 //==========================================================================
1349 //==========================================================================
1350 size_t Package::GetObjectRecursiveSize() const
1352 size_t s = Superclass::GetObjectRecursiveSize();
1353 s += Package::GetObjectInternalSize();
1355 BlackBoxMapType::const_iterator i;
1356 for (i = mBlackBoxMap.begin(); i!=mBlackBoxMap.end(); ++i )
1358 s += i->second->GetObjectRecursiveSize();
1362 //==========================================================================
1364 //==========================================================================
1365 std::set<Package::WeakPointer>
1366 Package::mReleasedDynamicallyLoadedPackages;
1367 //==========================================================================