2 /*=========================================================================
4 Module: $RCSfile: bbtkPackage.cxx,v $
6 Date: $Date: 2008/10/17 08:21:44 $
7 Version: $Revision: 1.23 $
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 "bbtkMessageManager.h"
38 #include "bbtkConfigurationFile.h"
41 #include "bbtkUtilities.h"
48 //==========================================================================
49 /// Creates a new package
50 Package::Pointer Package::New(const std::string& name,
51 const std::string& author,
52 const std::string& description,
53 const std::string& version,
54 const std::string& BBTKVersion)
56 bbtkDebugMessage("object",1,"##> Package::New('"<<name<<"',...)"
58 Package::Pointer p = MakePointer(new Package(name,
63 bbtkDebugMessage("object",2,"<## Package::New('"<<name<<"',...)"
67 //==========================================================================
69 //==========================================================================
70 /// Ctor with the name of the package
71 Package::Package(const std::string& name,
72 const std::string& author,
73 const std::string& description,
74 const std::string& version,
75 const std::string& BBTKVersion)
77 mDynamicLibraryHandler(0),
80 mDescription(description),
83 bbtkDebugMessage("object",2,"==> Package::Package('"<<name<<"',...)"
85 std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
86 char c = default_doc_dir.c_str()[strlen(default_doc_dir.c_str())-1];
87 std::string url = default_doc_dir;
88 if (c != '/' && c !='\\') url = url + "/";
89 url = url + "temp_dir/" + name + "/index.html";
92 SetDocRelativeURL("Relative url not set");
95 std::string relurl(BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH));
96 relurl += "/packages/"+name+"/bbdoc/index.html";
97 std::string url = ConfigurationFile::GetInstance().Get_url()
100 SetDocRelativeURL(relurl);
103 // std::cout << " url=["<<url<<"]"<<std::endl;
104 // std::cout << "relurl=["<<relurl<<"]"<<std::endl;
105 bbtkDebugMessage("object",2,"<== Package::Package('"<<name<<"',...) OK"
109 //==========================================================================
113 //==========================================================================
117 bbtkDebugMessage("object",2,"==> Package::~Package(\""<<mName<<"\")"<<bbtkendl);
118 bbtkDebugMessage("object",2,"<== Package::~Package(\""<<mName<<"\")"<<bbtkendl);
120 //==========================================================================
123 //==========================================================================
124 void PackageReleaseBlackBoxDescriptorInternal(Package::WeakPointer pack,
125 const std::string& descname)
127 // Try to release descriptor
128 std::string packname = pack.lock()->GetName();
130 bbtkDebugMessage("package",5,"--- Releasing descriptor '"
131 <<packname<<"::"<<descname<<"'"<<bbtkendl);
134 Package::BlackBoxMapType::iterator desc =
135 pack.lock()->GetBlackBoxMap().find(descname);
136 if (desc == pack.lock()->GetBlackBoxMap().end())
138 bbtkDebugMessage("package",5,
139 " Descriptor has already been released"
143 // bbtkDebugMessage("package",3,
144 // " Trying unreferencing it ... "<<std::endl);
145 BlackBoxDescriptor::WeakPointer pdesc = desc->second;
146 desc->second.reset();
147 // if it is dead : remove it
150 bbtkDebugMessage("package",2," ==> '"<<packname<<"::"<<descname<<"' Descriptor expired"<<bbtkendl);
153 bbtkDebugMessage("package",2,
154 " ... and caused its package death"
158 desc = pack.lock()->GetBlackBoxMap().find(descname);
159 if (desc != pack.lock()->GetBlackBoxMap().end())
160 pack.lock()->GetBlackBoxMap().erase(desc);
164 bbtkDebugMessage("package",5," ... Descriptor still alive ("
165 <<pdesc.use_count()<<" refs)"
167 pack.lock()->GetBlackBoxMap()[descname] = pdesc.lock();
170 //==========================================================================
173 //==========================================================================
175 void Package::Release(Package::WeakPointer pack)
177 std::string packname = pack.lock()->mName;
178 bbtkDebugMessage("package",1,"==> Package::Release('"<<
179 packname<<"')"<<bbtkendl);
181 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
182 long ndesc = pack.lock()->GetBlackBoxMap().size();
183 long nrefs = pack.use_count();
185 bbtkDebugMessage("package",5," "<<nrefs<<" refs / "
186 <<ndesc<<" descr / dyn="
189 // A package is "free" from any external reference iff :
190 // i) It is not dynamically loaded and nrefs == ndesc
191 // (each desc references its package) or
192 // ii) It is dynamically loaded and nrefs == ndesc + 1
193 // (A dynamic library holds a static pointer on the package it contains
194 // which is allocated when the PACKAGENAMEGetPackage() func is called,
195 // and descallocated (reset) by PACKAGENAMEDeletePackage())
196 if (nrefs == ndesc + dyn)
198 bbtkDebugMessage("package",5,
199 " -> No more external ref : checking descriptors"
201 // We must take care that removing refs on descriptors
202 // can lead to their deletion which can in turn unref
203 // internal boxes which can release their descriptors hence
204 // call Package::ReleaseBlackBoxDescriptor
205 // As a consequence during descriptors release :
206 // 1) The map can change dynamically : we cannot iterate over it
207 // as any iterator can become invalid
208 // 2) The package can auto-destruct : we must test its existence
209 // after each release
210 // We must also take care of not locking the package pointer
211 // or any ref count check in Package::ReleaseBlackBoxDescriptor
214 // The list of descriptors names at start
215 std::vector<std::string> descnamelist;
216 BlackBoxMapType::iterator i;
217 for (i=pack.lock()->mBlackBoxMap.begin();
218 i!= pack.lock()->mBlackBoxMap.end();
220 descnamelist.push_back(i->first);
222 // Iterator over the initial names
223 std::vector<std::string>::iterator descname;
224 for (descname=descnamelist.begin();
225 descname!=descnamelist.end();
228 // Is package still alive ?
231 bbtkDebugMessage("package",1,"--- Package::Release('"<<
233 <<"') : package expired during release : bailing out"<<bbtkendl);
237 PackageReleaseBlackBoxDescriptorInternal(pack,*descname);
242 UnLoadDynamicLibrary(pack);
243 // Unload orphan dl packages
244 Package::UnLoadReleasedDynamicallyLoadedPackages();
251 #ifdef BBTK_COMPILE_DEBUG_MESSAGES
253 bbtkDebugMessage("package",2,"<== Package::Release('"<<
254 packname<<"')"<<bbtkendl);
258 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
259 long ndesc = pack.lock()->GetBlackBoxMap().size();
260 long nrefs = pack.use_count();
262 bbtkDebugMessage("package",1," ... Package still alive ("
264 <<ndesc<<" descr / dyn="
265 <<dyn<<")"<<std::endl);
269 bbtkDebugMessage("package",1," ... Package has been released"
274 //==========================================================================
276 //==========================================================================
277 /// "Releases" the package
278 /// Signals the package that it can free the given descriptor
279 /// if they are no more used and free itself if it is no
281 /// Note : Any non-weak pointer on the package must have been freed
282 void Package::ReleaseBlackBoxDescriptor(Package::WeakPointer pack,
283 BlackBoxDescriptor::WeakPointer descr)
285 std::string packname = pack.lock()->mName;
286 std::string dname = descr.lock()->GetTypeName();
287 bbtkDebugMessage("package",3,"==> Package::ReleaseBlackBoxDescriptor('"<<
288 packname<<"','"<<dname<<"') : refs="
289 <<descr.use_count()<<bbtkendl);
291 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
292 long ndesc = pack.lock()->GetBlackBoxMap().size();
293 long nrefs = pack.use_count();
295 bbtkDebugMessage("package",5," "<<nrefs<<" refs / "
296 <<ndesc<<" descr / dynamically loaded = "
299 // A package is "free" from any external reference iff :
300 // i) It is not dynamically loaded and nrefs == ndesc
301 // (each desc references its package) or
302 // ii) It is dynamically loaded and nrefs == ndesc + 1
303 // (A dynamic library holds a static pointer on the package it contains
304 // which is allocated when the PACKAGENAMEGetPackage() func is called,
305 // and descallocated (reset) by PACKAGENAMEDeletePackage())
306 if (nrefs == ndesc + dyn)
308 PackageReleaseBlackBoxDescriptorInternal(pack,dname);
311 // If the package is released and dynamically loaded
312 // then put it in the static list mReleasedDynamicallyLoadedPackages
313 UnLoadDynamicLibrary(pack,false);
315 bbtkDebugMessage("package",4,"<== Package::ReleaseBlackBoxDescriptor('"<<
316 packname<<"','"<<dname<<"'): refs="
317 <<descr.use_count()<<bbtkendl);
321 long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0;
322 long ndesc = pack.lock()->GetBlackBoxMap().size();
323 long nrefs = pack.use_count();
325 bbtkDebugMessage("package",3," ... Package still alive ("
327 <<ndesc<<" descr / dyn="
328 <<dyn<<")"<<std::endl);
332 bbtkDebugMessage("package",3," ... Package has been released"
337 //==========================================================================
339 //==========================================================================
340 /// Opens a dynamic library which contains a bbtk package
341 /// Returns the handler
342 /// Load the package management symbols from the lib
343 /// returns false if a problem occured hence can be used
344 /// to test that a dyn lib is a valid bbtk package lib
345 /// NB : The BBTK version exported from the library
346 /// is tested against the current bbtk version
347 DynamicLibraryHandler Package::OpenDynamicLibrary
348 ( const std::string& libname,
349 const std::string& package_name,
350 DLGetPackageFunction& getpack,
351 DLDeletePackageFunction& delpack)
353 bbtkDebugMessage("package",3,"==> Package::OpenDynamicLibrary("
354 <<libname<<")"<<std::endl);
355 #if defined(__GNUC__)
359 handler = dlopen(libname.c_str(),
360 BBTK_RTLD_TIME | BBTK_RTLD_SCOPE );
363 bbtkMessage("package",2,
364 "Could not open shared library [" <<libname<<"] : "
365 <<dlerror() << std::endl);
369 bbtkDebugMessage("package",3,"* Shared lib ["<<libname<<"] open"<<std::endl);
371 // Loads the Package bbtk version function
372 std::string getvername(package_name);
374 BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME);
375 DLGetPackageBBTKVersionFunction getbbtkversion
376 = (DLGetPackageBBTKVersionFunction)(dlsym(handler,getvername.c_str()));
379 bbtkDebugMessage("package",3,"***"<<std::endl);
380 bbtkMessage("package",2,
381 "Shared library ["<<libname
382 <<"] is not a valid bbtk package."
383 <<" Symbol ["<<getvername<<"] :"<<dlerror()<< std::endl);
388 bbtkDebugMessage("package",3,"* Symbol ["<<getvername
389 <<"] found"<<std::endl);
391 if (getbbtkversion() != bbtk::GetVersion())
393 bbtkMessage("package",2,
394 "Shared library ["<<libname
395 <<"] was build with bbtk version "
397 <<" but the current program runs with version "
398 <<bbtk::GetVersion()<<" : cannot load it"<<std::endl);
404 bbtkDebugMessage("package",3,"* Package bbtk version '"<<getbbtkversion()<<"' matches"<<std::endl);
405 // Loads the Package get function
406 std::string getpackname(package_name);
407 getpackname += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_FUNCTION_NAME);
408 getpack = (DLGetPackageFunction)(dlsym(handler, getpackname.c_str()));
411 bbtkMessage("package",2,
412 "Shared library ["<<libname
413 <<"] is not a valid bbtk package."
414 <<" Symbol ["<<getpackname<<"] :"<<dlerror()<< std::endl);
419 bbtkDebugMessage("package",3,"* Symbol ["<<getpackname<<"] found"<<std::endl);
420 // Loads the Package delete function
422 std::string delpackname(package_name);
423 delpackname += BBTK_STRINGIFY_SYMBOL(BBTK_DEL_PACKAGE_FUNCTION_NAME);
424 delpack = (DLDeletePackageFunction)(dlsym(handler, delpackname.c_str()));
427 bbtkMessage("package",2,
428 "Shared library ["<<libname
429 <<"] is not a valid bbtk package."
430 <<" Symbol ["<<delpackname<<"] :"<<dlerror()<< std::endl);
434 bbtkDebugMessage("package",3,"* Symbol ["<<delpackname<<"] found"<<std::endl);
435 #elif defined(_WIN32)
441 handler = LoadLibrary(libname.c_str());
444 bbtkMessage("package",2,
445 "Could not open shared library [" <<libname<<"]"
447 DWORD dwErrorCode = 0;
448 dwErrorCode = GetLastError();
449 bbtkMessage("package",2,
450 "Windows Error: [" << dwErrorCode <<"]"
456 // Loads the Package bbtk version function
457 std::string getvername(package_name);
459 BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME);
460 DLGetPackageBBTKVersionFunction getbbtkversion
461 = (DLGetPackageBBTKVersionFunction)(GetProcAddress(handler,
462 getvername.c_str()));
465 FreeLibrary(handler);
466 bbtkMessage("package",2,
467 "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",2,
478 "Shared library ["<<libname
479 <<"] was build with bbtk version "
481 <<" but the current program runs with version "
482 <<bbtk::GetVersion()<<" : cannot load it"<<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",2,
495 "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",2,
509 "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))
573 std::string packname = pack.lock()->GetName();
574 bbtkDebugMessage("package",5,"==> Package::UnLoadDynamicLibrary('"
578 if (!pack.lock()->GetBlackBoxMap().empty())
581 bbtkDebugMessage("package",5," Package not empty ... abort"
585 bbtkGlobalError("Package::UnLoadDynamicLibrary('"<<packname<<") : "
586 <<"BlackBoxMap not empty "
587 <<BBTK_INTERNAL_ERROR_MESSAGE);
592 if (pack.use_count()!=1)
594 bbtkGlobalError("Package::UnLoadDynamicLibrary('"<<packname<<") : "
595 <<"empty dl package with external refs"
596 <<BBTK_INTERNAL_ERROR_MESSAGE);
602 bbtkDebugMessage("package",5,"==> dynamic library for package '"
603 <<packname<<"' closed"
608 mReleasedDynamicallyLoadedPackages.insert(pack);
609 bbtkDebugMessage("package",1,"==> package '"<<packname
610 <<"' put in the 'to unload' list"
615 bbtkDebugMessage("package",5,"<== Package::UnLoadDynamicLibrary('"
620 //==========================================================================
622 //==========================================================================
623 /// UnLoads released packages that were loaded dynamically
624 /// see UnLoadDynamicLibrary and ReleaseBlackBoxDescriptor
625 void Package::UnLoadReleasedDynamicallyLoadedPackages()
627 bbtkDebugMessage("package",5,"==> Package::UnLoadReleasedDynamicallyLoadedPackages()"<<std::endl);
629 std::set<Package::WeakPointer>::iterator i;
630 for (i=mReleasedDynamicallyLoadedPackages.begin();
631 i!=mReleasedDynamicallyLoadedPackages.end();
634 if (!i->expired()) UnLoad(*i);
636 bbtkDebugMessage("package",5,"<== Package::UnLoadReleasedDynamicallyLoadedPackages()"<<std::endl);
638 //==========================================================================
640 //==========================================================================
641 void Package::UnLoad(Package::WeakPointer pack)
643 std::string packname = pack.lock()->GetName();
644 bbtkDebugMessage("package",6,"==> Package::UnLoad("<<packname<<")"<<std::endl);
646 Package* p = pack.lock().get();
648 DynamicLibraryHandler h = p->mDynamicLibraryHandler;
650 // deletes the package
651 p->mDLDeletePackageFunction();
653 // closes the dl handler
654 #if defined(__GNUC__)
656 #elif defined(_WIN32)
660 bbtkDebugMessage("package",1,"==> dynamic library for package '"
661 <<packname<<"' closed"
663 bbtkDebugMessage("package",6," ... dynamic library unloaded"<<std::endl);
665 //==========================================================================
667 //==========================================================================
668 /// Creates an instance of a black box of type <type> with name <name>
669 BlackBox::Pointer Package::NewBlackBox(const std::string& type,
670 const std::string& name) const
672 bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::NewBlackBox(\""<<type<<"\",\""<<name<<"\")"<<bbtkendl);
674 BlackBoxMapType::const_iterator i = mBlackBoxMap.find(type);
675 if (i == mBlackBoxMap.end())
677 bbtkDebugDecTab("Kernel",8);
678 return BlackBox::Pointer();
680 BlackBox::Pointer bb =i->second->NewBlackBox(name);
681 bbtkDebugDecTab("Kernel",8);
685 //==========================================================================
689 //==========================================================================
690 /// Creates an instance of an adaptor of input type <typein> and
691 /// output type <typeout> with name <name>
692 BlackBox::Pointer Package::NewAdaptor(const DataInfo& typein,
693 const DataInfo& typeout,
694 const std::string& name) const
696 bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<
700 <<name<<"\")"<<bbtkendl);
702 AdaptorKey key(typein,typeout,
703 BlackBoxDescriptor::DEFAULT_ADAPTOR);
704 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
705 if (i == mAdaptorMap.end())
707 bbtkDebugDecTab("Kernel",8);
708 return BlackBox::Pointer();
710 BlackBox::Pointer bb =i->second.lock()->NewBlackBox(name);
711 bbtkDebugDecTab("Kernel",8);
715 //==========================================================================
717 //==========================================================================
718 /// Creates an instance of an adaptor of input type <typein> and
719 /// output type <typeout> with name <name>
720 BlackBox::Pointer Package::NewWidgetAdaptor(const DataInfo& typein,
721 const DataInfo& typeout,
722 const std::string& name) const
724 bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<
725 ">::NewWidgetAdaptor("
728 <<name<<"\")"<<bbtkendl);
730 AdaptorKey key(typein,typeout,
731 BlackBoxDescriptor::DEFAULT_GUI);
732 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
733 if (i == mAdaptorMap.end())
735 bbtkDebugDecTab("Kernel",8);
736 return BlackBox::Pointer();
738 BlackBox::Pointer bb =i->second.lock()->NewBlackBox(name);
739 bbtkDebugDecTab("Kernel",8);
743 //==========================================================================
747 //==========================================================================
748 /// Returns true is the package contains
749 /// an adaptor of input type <typein> and
750 /// output type <typeout>
751 /// If successfull then adaptor contains the black box type name
752 bool Package::FindWidgetAdaptor(const DataInfo& typein,
753 const DataInfo& typeout,
754 std::string& adaptor) const
756 bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<
757 ">::FindWidgetAdaptor("
759 <<typeout<<")"<<bbtkendl);
761 AdaptorKey key(/*typein*/
762 DataInfo(typeid(void),""),
764 BlackBoxDescriptor::DEFAULT_GUI);
765 // First try to find a single widget adaptor
766 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
767 if (i == mAdaptorMap.end())
769 bbtkDebugDecTab("Kernel",8);
772 adaptor = i->second.lock()->GetTypeName();
773 bbtkDebugDecTab("Kernel",8);
777 //==========================================================================
781 //==========================================================================
782 /// Returns true is the package contains
783 /// an adaptor of input type <typein> and
784 /// output type <typeout>
785 /// If successfull then adaptor contains the black box type name
786 bool Package::FindAdaptor(const DataInfo& typein,
787 const DataInfo& typeout,
788 std::string& adaptor) const
790 bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<
793 <<typeout<<")"<<bbtkendl);
795 AdaptorKey key(typein,typeout,
796 BlackBoxDescriptor::DEFAULT_ADAPTOR);
797 AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
798 if (i == mAdaptorMap.end())
800 bbtkDebugDecTab("Kernel",8);
803 adaptor = i->second.lock()->GetTypeName();
804 bbtkDebugDecTab("Kernel",8);
808 //==========================================================================
811 //==========================================================================
812 /// Registers a black box descriptor in the package
813 bool Package::RegisterBlackBox(BlackBoxDescriptor::Pointer d)
815 bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::RegisterBlackBox(\""<<d->GetTypeName()<<"\")"<<std::endl);
817 BlackBoxMapType::iterator i = mBlackBoxMap.find(d->GetTypeName());
818 if (i!=mBlackBoxMap.end())
820 bbtkWarning("Package<"<<GetName()<<"> : Trying to register box type <"
821 <<d->GetTypeName()<<"> which is already in the package");
825 mBlackBoxMap[d->GetTypeName()] = d;
827 d->SetPackage(GetThisPointer<Package>());
829 // If it is a default adaptor, also register it in the adaptors map
830 if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_ADAPTOR )
832 bbtkDebugMessage("Kernel",8,"Package<"<<GetName()<<">::RegisterBlackBox(\""<<d->GetTypeName()<<"\") : The box is an adaptor, inserting it in adaptors map ..."<<std::endl);
834 TypeInfo typein = d->GetInputDescriptor("In")->GetTypeInfo();
835 TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
836 DataInfo infoin(typein,d->GetInputDescriptor("In")->GetNature());
837 DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
838 AdaptorKey key(infoin,infoout,d->GetKind());
840 AdaptorMapType::const_iterator i;
841 i = mAdaptorMap.find(key);
842 if (i == mAdaptorMap.end())
844 mAdaptorMap[key] = d;
846 // If already an adaptor registered : error
849 if (i->second.lock()->GetTypeName() != d->GetTypeName())
851 bbtkError("Package <"<<GetName()<<
852 "> : trying to register black box <"
854 <<"> as default adaptor but there is already a default adaptor registered (<"
855 <<i->second.lock()->GetTypeName()<<">)");
859 // If it is a default adaptor, also register it in the adaptors map
860 else if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_GUI)
862 bbtkDebugMessage("Kernel",8,"Package<"<<GetName()<<">::RegisterBlackBox(\""<<d->GetTypeName()<<"\") : The box is a widget adaptor, inserting it in adaptors map ..."<<std::endl);
864 TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
865 DataInfo infoin(typeid(void),"");
866 DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
867 AdaptorKey key(infoin,infoout,d->GetKind());
869 AdaptorMapType::const_iterator i;
870 i = mAdaptorMap.find(key);
871 if (i == mAdaptorMap.end())
873 mAdaptorMap[key] = d;
875 // If already an adaptor registered : error
878 if (i->second.lock()->GetTypeName() != d->GetTypeName())
880 bbtkError("Package <"<<GetName()<<
881 "> : trying to register black box <"
883 <<"> as default widget adaptor but there is already a default adaptor registered (<"
884 <<i->second.lock()->GetTypeName()<<">)");
890 bbtkDebugDecTab("Kernel",8);
894 //==========================================================================
896 //===================================================================
897 void Package::CheckBoxes() const
899 bbtkMessage("debug",1,"****** Checking Package "<<(void*)this
900 <<" ["<<GetName()<<"]"<<std::endl);
901 BlackBoxMapType::const_iterator i;
902 for (i=mBlackBoxMap.begin();
903 i!=mBlackBoxMap.end();
906 i->second->Check(true);
908 bbtkMessage("debug",1,"****** Checking Package "<<(void*)this
909 <<" ["<<GetName()<<"] ... OK"<<std::endl);
911 //===================================================================
914 //==========================================================================
915 /// Changes the name of a black box type
916 void Package::ChangeBlackBoxName( const std::string& oldname, const std::string& newname )
918 bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::ChangeBlackBoxName(\""<<oldname<<"\",\""<<newname<<"\")"<<std::endl);
919 // Looking into the bb map
920 BlackBoxMapType::iterator i = mBlackBoxMap.find(oldname);
921 if (i == mBlackBoxMap.end())
923 bbtkDebugDecTab("Kernel",8);
924 bbtkError("ChangeBlackBoxName : The package <"<<GetName()<<"> does not contains the black box <"<<oldname<<">");
927 i->second->SetTypeName(newname);
928 mBlackBoxMap[newname] = i->second;
929 mBlackBoxMap.erase(i);
931 bbtkDebugDecTab("Kernel",8);
933 //==========================================================================
937 //==========================================================================
938 /// Displays the list of black boxes of the package
939 void Package::PrintBlackBoxes(bool description, bool adaptors) const
941 unsigned int lmax = 0;
942 std::vector<std::string> names;
943 std::vector<std::string> kinds;
944 std::vector<std::string> descrs;
946 BlackBoxMapType::const_iterator i;
947 for (i=mBlackBoxMap.begin();
948 i!=mBlackBoxMap.end();
952 ( i->second->GetKind() == BlackBoxDescriptor::STANDARD) )
954 std::string name(" ");
955 name += i->second->GetTypeName();
956 names.push_back(name);
959 if ( i->second->GetKind() == BlackBoxDescriptor::ADAPTOR )
961 kind = std::string("[A]");
963 else if ( i->second->GetKind() ==
964 BlackBoxDescriptor::DEFAULT_ADAPTOR )
966 kind = std::string("[DA]");
968 kinds.push_back(kind);
970 unsigned int l = name.size()+kind.size();
971 if (l>lmax) lmax = l;
977 descr += i->second->GetDescription();
979 descrs.push_back(descr);
985 offs.append(lmax+3,' ');
986 std::vector<std::string>::iterator ni,ci,di;
987 for (ni = names.begin(), ci = kinds.begin(), di = descrs.begin();
988 ni != names.end(); ++ni, ++ci, ++di)
991 space.append(lmax - ni->size() - ci->size(),' ');
992 bbtkMessage("Help",1,*ni << space << *ci );
994 unsigned int dmax = 75 - lmax;
995 // while (d.size() > dmax )
998 bbtkMessage("Help",1,d.substr(0,dmax) << "..." << std::endl);
1000 bbtkMessage("Help",1,d << std::endl);
1001 // d = d.substr(dmax,d.size());
1006 //==========================================================================
1008 //==========================================================================
1009 /// Displays the list of adaptors of the package
1010 void Package::PrintAdaptors(bool description) const
1012 BlackBoxMapType::const_iterator i;
1013 for (i=mBlackBoxMap.begin();
1014 i!=mBlackBoxMap.end();
1017 if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD )
1019 bbtkMessage("Help",1,
1020 " "<<i->second->GetTypeName());
1021 if ( i->second->GetKind() ==
1022 BlackBoxDescriptor::DEFAULT_ADAPTOR )
1024 bbtkMessage("Help",1,
1029 bbtkMessage("Help",1,
1030 " : "<<i->second->GetDescription());
1033 bbtkMessage("Help",1,std::endl);
1037 AdaptorMapType::const_iterator i;
1038 for (i=mAdaptorMap.begin();
1039 i!=mAdaptorMap.end();
1042 bbtkMessage("Help",1,
1043 " "<<i->second->GetTypeName());
1046 bbtkMessage("Help",1,
1047 " : "<<i->second->GetDescription());
1050 bbtkMessage("Help",1,std::endl);
1054 //==========================================================================
1056 //==========================================================================
1057 /// Prints help on a black box
1058 void Package::HelpBlackBox(const std::string& name, bool full) const
1060 bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::HelpBlackBox(\""
1061 <<name<<"\")"<<bbtkendl);
1063 BlackBoxMapType::const_iterator i = mBlackBoxMap.find(name);
1064 if (i == mBlackBoxMap.end())
1066 bbtkDebugDecTab("Kernel",8);
1067 bbtkError("The package <"<<GetName()<<"> does not contains the black box <"<<name<<">");
1069 // bbtkMessage("Help",1,"["<<GetName()<<"] ");
1070 i->second->GetHelp(full);
1071 bbtkDebugDecTab("Kernel",8);
1074 //==========================================================================
1077 //==========================================================================
1078 /// Returns true iff the package contains the box of name boxname
1079 bool Package::ContainsBlackBox(const std::string& name) const
1081 bbtkDebugMessageInc("Kernel",8,"Package<"<<GetName()<<">::HelpBlackBox(\""
1082 <<name<<"\")"<<bbtkendl);
1084 BlackBoxMapType::const_iterator i = mBlackBoxMap.find(name);
1085 if (i == mBlackBoxMap.end())
1087 bbtkDebugDecTab("Kernel",8);
1090 bbtkDebugDecTab("Kernel",8);
1093 //==========================================================================
1097 //==========================================================================
1098 void Package::CreateHtmlPage(const std::string& filename,
1099 const std::string& caller,
1100 const std::string& source,
1101 const std::string& custom_header,
1102 const std::string& custom_title,
1105 bool relative_link ) const
1107 bbtkDebugMessageInc("Kernel",9,"Package<"<<GetName()<<">::CreateHtmlPage(\""
1108 <<filename<<"\")"<<bbtkendl);
1110 //---------------------
1113 s.open(filename.c_str());
1116 bbtkError("Package "<<GetName()<<" : CreateHtmlPage : could not open file '"<<filename<<"'");
1119 //----------------------
1121 std::string title = "BBTK Package "+GetName()+" "+GetVersion();
1123 if (custom_title.length() != 0) title = custom_title;
1125 s << "<html lang=\"en\">\n";
1127 s << "<title>" << title << "</title>\n";
1128 s << "<meta http-equiv=\"Content-Type\" content=\"text/html\">\n";
1129 s << "<meta name=\"description\" content=\""<<title<<"\">\n";
1130 s << "<meta name=\"generator\" content=\"\">\n";
1131 s << "<link title=\"Top\" rel=\"top\" href=\"#Top\">\n";
1132 //<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
1133 s << "<meta http-equiv=\"Content-Style-Type\" content=\"text/css\"><style type=\"text/css\"><!--\n";
1134 s << "pre.display { font-family:inherit }\n";
1135 s << "pre.format { font-family:inherit }\n";
1136 s << "pre.smalldisplay { font-family:inherit; font-size:smaller }\n";
1137 s << "pre.smallformat { font-family:inherit; font-size:smaller }\n";
1138 s << "pre.smallexample { font-size:smaller }\n";
1139 s << "pre.smalllisp { font-size:smaller }\n";
1140 s << "span.sc { font-variant:small-caps }\n";
1141 s << "span.roman { font-family:serif; font-weight:normal; } \n";
1142 s << "span.sansserif { font-family:sans-serif; font-weight:normal; }\n";
1143 s << "--></style>\n";
1145 //----------------------
1147 //----------------------
1150 s << "<a name=\"Top\"></a>\n";
1152 //----------------------
1154 if ( custom_header.length() != 0)
1156 if ( custom_header != "none" )
1159 in.open(custom_header.c_str());
1162 bbtkError("Could not open file \""<<custom_header<<"\"");
1167 in.getline(buffer,512);
1168 std::string line(buffer);
1175 s << "<object data=\"" << custom_header
1176 << "\" type = \"text/html\"\"style=\"width: 1200px; height: 400px;\"> Warning: "
1177 << custom_header <<" could not be embedded.</object>\n";
1186 s << "<h1 class=\"settitle\">"<<title<<"</h1>\n";
1187 s << "<p><TABLE cellspacing=0 cellpadding=3>\n";
1188 s << "<TR><TD style='vertical-align: top;'><b> Description </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1189 << GetDescription() << "</TD></TR>\n";
1190 s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1191 << GetAuthor() << "</TD></TR>\n";
1192 s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1193 << GetCategory() << "</TD></TR>\n";
1194 s << "<TR><TD style='vertical-align: top;'><b> Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1195 << GetVersion() << "</TD></TR>\n";
1196 s << "<TR><TD style='vertical-align: top;'><b> bbtk Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> "
1197 << bbtk::GetVersion() << "</TD></TR>\n";
1201 //-------------------
1202 // Table of contents
1204 // s << "<div class=\"contents\">\n";
1205 s << "<p><b> Black Boxes : </b>\n";
1208 s << "<p><TABLE cellspacing=0 cellpadding=3>\n";
1210 BlackBoxMapType::const_iterator i;
1211 for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end(); ++i)
1213 if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD)
1216 std::string name = i->second->GetTypeName();
1217 Utilities::html_format(name);
1218 std::string descr = i->second->GetDescription();
1219 //Utilities::html_format(descr);
1222 s << "<TD style='vertical-align: top;'>";
1223 s << " <a name=\"toc_"<<name
1224 <<"\" href=\"#"<<name<<"\">"
1227 s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
1236 //-------------------
1238 if (mAdaptorMap.size()>0)
1240 // s << "<div class=\"contents\">\n";
1241 s << "<p><b> Adaptors : </b>\n";
1244 // BlackBoxMapType::const_iterator i;
1245 s << "<p><TABLE cellspacing=0 cellpadding=3>\n";
1246 for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end();++i)
1248 if ( i->second->GetKind() == BlackBoxDescriptor::STANDARD)
1251 std::string name = i->second->GetTypeName();
1252 Utilities::html_format(name);
1253 std::string descr = i->second->GetDescription();
1256 s << "<TD style='vertical-align: top;'>";
1257 s << " <a name=\"toc_"<<name
1258 <<"\" href=\"#"<<name<<"\">"
1261 s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
1271 // s << "<div class=\"node\">\n";
1273 // s << "<p><hr>\n";
1274 // s << "<a name=\"Top\"></a>\n";
1275 // s << "Top: <a rel=\"top\" accesskey=\"t\" href=\"#Top\">Top</a>\n";
1276 // s << "Previous: <a rel="previous" accesskey="p" href="#dir">(dir)</a>,
1277 // s << "Up: <a rel="up" accesskey="u" href="#dir">(dir)</a>
1281 //----------------------
1284 //-------------------
1285 // Computes output directory from filename to pass it to
1286 // BlackBoxDescriptor::InsertHtmlHelp
1289 std::string::size_type slash_position = filename.find_last_of("/\\");
1292 if (slash_position != std::string::npos) {
1293 if (slash_position == 0)
1295 dir = filename.substr(0,slash_position);
1298 for (i=mBlackBoxMap.begin();
1299 i!=mBlackBoxMap.end();
1302 i->second->InsertHtmlHelp(s,detail,level,dir,relative_link);
1305 //----------------------
1310 ptm = gmtime ( &rawtime );
1313 s << "Automatically generated by <b>"<<caller<<"</b> "//from <b>"
1316 << ptm->tm_mday << "/" << ptm->tm_mon << "/" << ptm->tm_year+1900
1317 << " - " << ptm->tm_hour << ":" << ptm->tm_min << " GMT\n";
1318 s << "</body></html>\n";
1320 //----------------------
1323 bbtkDebugDecTab("Kernel",9);
1325 //==========================================================================
1327 //==========================================================================
1328 std::string Package::GetObjectName() const
1330 return std::string("Package '")+mName+std::string("'");
1332 //==========================================================================
1334 //==========================================================================
1335 std::string Package::GetObjectInfo() const
1337 std::stringstream i;
1338 i << " - "<<mBlackBoxMap.size() << " boxes" << std::endl;
1339 if (mDynamicLibraryHandler)
1341 i<< " - Loaded from dynamic library"<<std::endl;
1345 //==========================================================================
1348 //==========================================================================
1349 size_t Package::GetObjectSize() const
1351 size_t s = Superclass::GetObjectSize();
1352 s += Package::GetObjectInternalSize();
1355 //==========================================================================
1356 //==========================================================================
1357 size_t Package::GetObjectInternalSize() const
1359 size_t s = sizeof(Package);
1362 //==========================================================================
1363 //==========================================================================
1364 size_t Package::GetObjectRecursiveSize() const
1366 size_t s = Superclass::GetObjectRecursiveSize();
1367 s += Package::GetObjectInternalSize();
1369 BlackBoxMapType::const_iterator i;
1370 for (i = mBlackBoxMap.begin(); i!=mBlackBoxMap.end(); ++i )
1372 s += i->second->GetObjectRecursiveSize();
1376 //==========================================================================
1378 //==========================================================================
1379 std::set<Package::WeakPointer>
1380 Package::mReleasedDynamicallyLoadedPackages;
1381 //==========================================================================