00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00035 #include "bbtkBlackBox.h"
00036 #include "bbtkPackage.h"
00037 #include "bbtkMessageManager.h"
00038 #include "bbtkFactory.h"
00039 #include "bbtkBlackBoxOutputConnector.h"
00040
00041 #include "bbtkConfigurationFile.h"
00042 #include "bbtkWxBlackBox.h"
00043 #include "bbtkWx.h"
00044
00045 #include <fstream>
00046
00047
00048
00049 namespace bbtk
00050 {
00051 static bool bbmgSomeBoxExecuting = false;
00052 static bool bbmgFreezeExecution = false;
00053 static std::set<BlackBox::WeakPointer> bbmgExecutionList;
00054
00055
00056
00057 BlackBox::Deleter::Deleter()
00058 {
00059 }
00060
00061
00062
00063 int BlackBox::Deleter::Delete(Object* p)
00064 {
00065 BlackBox* b = dynamic_cast<BlackBox*>(p);
00066 if (!b)
00067 {
00068 bbtkInternalError("BlackBox::Deleter::Delete("<<p->GetObjectName()
00069 <<"["<<p<<"]) : "
00070 <<"dynamic cast to BlackBox* failed !");
00071 }
00072 std::string name = p->GetObjectName();
00073 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\")"<<std::endl);
00074
00075
00076 BlackBoxDescriptor::WeakPointer desc = b->bbGetDescriptor();
00077 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : deleting black box"<<std::endl);
00078
00079 int refs = b->bbDelete();
00080
00081 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : releasing descriptor"<<std::endl);
00082
00083 if (!desc.expired())
00084 {
00085 Package::WeakPointer pack = desc.lock()->GetPackage();
00086 if (!pack.expired())
00087 {
00088 Package::ReleaseBlackBoxDescriptor(pack,desc);
00089 }
00090 else
00091 {
00092 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : descriptor package expired (was not held by a package and the box was the last instance)"<<std::endl);
00093 }
00094 }
00095 else
00096 {
00097 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : descriptor expired : nothing to do (was not held by a package or the box is a complex black box prototype)"<<std::endl);
00098 }
00099 bbtkDebugMessage("object",2,"<## BlackBox::Deleter(\""<<name<<"\")"<<std::endl);
00100 return refs;
00101 }
00102
00103
00104
00105 BlackBox::BlackBox(const std::string &name)
00106 :
00107
00108 bbmInitialized(false),
00109 bbmExecuting(false),
00110 bbmName(name),
00111 bbmBoxProcessMode("Pipeline"),
00112 bbmParent()
00113
00114 {
00115
00116
00117
00118
00119 bbtkBlackBoxDebugMessage("object",4,"==> BlackBox::BlackBox(\""
00120 <<name<<"\")"<<std::endl);
00121 bbtkBlackBoxDebugMessage("object",4,"<== BlackBox::BlackBox(\""
00122 <<name<<"\")"<<std::endl);
00123 }
00124
00125
00126
00127 BlackBox::BlackBox(const BlackBox&)
00128 {}
00129
00130
00131 BlackBox::BlackBox(BlackBox& from, const std::string &name)
00132 :
00133
00134 bbmInitialized(false),
00135 bbmExecuting(false),
00136 bbmName(name),
00137 bbmBoxProcessMode(from.bbmBoxProcessMode),
00138 bbmParent()
00139
00140 {
00141
00142
00143
00144
00145 bbtkBlackBoxDebugMessage("object",4,"==> BlackBox::BlackBox("
00146 <<from.bbGetFullName()<<",\""
00147 <<name<<"\")"<<std::endl);
00148 bbtkBlackBoxDebugMessage("object",4,"<== BlackBox::BlackBox("
00149 <<from.bbGetFullName()<<",\""
00150 <<name<<"\")"<<std::endl);
00151 }
00152
00153
00154
00155
00156 BlackBox::~BlackBox()
00157 {
00158 bbtkBlackBoxDebugMessage("object",4,"==> BlackBox::~BlackBox() ["<<bbmName
00159 <<"]"<<std::endl);
00160 this->bbDesallocateConnectors();
00161 bbtkBlackBoxDebugMessage("object",4,"<== BlackBox::~BlackBox() ["<<bbmName
00162 <<"]"<<std::endl);
00163 }
00164
00165
00166
00167
00168
00169 std::string BlackBox::bbGetFullName() const
00170 {
00171 return this->bbGetNameWithParent()+"<"+this->bbGetDescriptor()->GetTypeName()+">";
00172 }
00173
00174
00175
00176
00177
00178 std::string BlackBox::bbGetNameWithParent() const
00179 {
00180 if (bbmParent.lock())
00181 {
00182 return bbmParent.lock()->bbGetNameWithParent() + ":" + bbmName;
00183 }
00184 else
00185 {
00186 return bbmName;
00187 }
00188 }
00189
00190
00191
00192 void BlackBox::bbGetHelp(bool full) const
00193 {
00194 bbGetDescriptor()->GetHelp(full);
00195 }
00196
00197
00198
00199
00200 bool BlackBox::bbHasInput(const std::string& name) const
00201 {
00202 bbtkBlackBoxDebugMessage("kernel",8,
00203 "BlackBox::bbHasInput(\""
00204 <<name<<"\")"
00205 <<std::endl);
00206 bool r = ( bbGetDescriptor()->GetInputDescriptorMap().find(name)
00207 != bbGetDescriptor()->GetInputDescriptorMap().end());
00208 bbtkDebugDecTab("kernel",8);
00209 return r;
00210 }
00211
00212
00213
00214
00215 bool BlackBox::bbHasOutput(const std::string& name) const
00216 {
00217 bbtkBlackBoxDebugMessage("kernel",8,"BlackBox::bbHasOutput(\""
00218 <<name<<"\")"
00219 <<std::endl);
00220 bool r = ( bbGetDescriptor()->GetOutputDescriptorMap().find(name)
00221 != bbGetDescriptor()->GetOutputDescriptorMap().end());
00222 bbtkDebugDecTab("kernel",8);
00223 return r;
00224 }
00225
00226
00227
00228
00229 TypeInfo BlackBox::bbGetOutputType( const std::string &name ) const
00230 {
00231 bbtkBlackBoxDebugMessage("kernel",8,
00232 "BlackBox::bbGetOutputType(\""
00233 <<name<<"\")"
00234 <<std::endl);
00235 TypeInfo r = bbGetDescriptor()->GetOutputDescriptor(name)->GetTypeInfo();
00236 bbtkDebugDecTab("kernel",8);
00237 return r;
00238 }
00239
00240
00241
00242 TypeInfo BlackBox::bbGetInputType( const std::string &name ) const
00243 {
00244 bbtkBlackBoxDebugMessage("kernel",8,
00245 "BlackBox::bbGetInputType(\""
00246 <<name<<"\")"
00247 <<std::endl);
00248 TypeInfo r = bbGetDescriptor()->GetInputDescriptor(name)->GetTypeInfo();
00249 bbtkDebugDecTab("kernel",8);
00250 return r;
00251 }
00252
00253
00254
00255
00256 void BlackBox::bbAllocateConnectors()
00257 {
00258 bbtkBlackBoxDebugMessage("kernel",8,
00259 "BlackBox::bbAllocateConnectors()"
00260 <<std::endl);
00261
00262 MakeBlackBoxPointer(this,true);
00263
00264 const BlackBoxDescriptor::InputDescriptorMapType& imap
00265 = bbGetDescriptor()->GetInputDescriptorMap();
00266 BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;
00267 for ( i = imap.begin(); i != imap.end(); ++i )
00268 {
00269 bbtkBlackBoxDebugMessage("kernel",8,"* Allocate \""<<i->first<<"\""<<std::endl);
00270 bbGetInputConnectorMap()[i->second->GetName()]
00271 = new BlackBoxInputConnector(GetThisPointer<BlackBox>());
00272 }
00273 const BlackBoxDescriptor::OutputDescriptorMapType& omap
00274 = bbGetDescriptor()->GetOutputDescriptorMap();
00275 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
00276 for ( o = omap.begin(); o != omap.end(); ++o )
00277 {
00278 bbtkBlackBoxDebugMessage("kernel",8,"* Allocate \""<<o->first<<"\""<<std::endl);
00279 bbGetOutputConnectorMap()[o->second->GetName()]
00280 = new BlackBoxOutputConnector(GetThisPointer<BlackBox>());
00281 }
00282 }
00283
00284
00285
00286
00287 void BlackBox::bbDesallocateConnectors()
00288 {
00289 bbtkBlackBoxDebugMessage("kernel",8,
00290 "BlackBox::bbDesallocateConnectors()"
00291 <<std::endl);
00292
00293 InputConnectorMapType::const_iterator i;
00294 for ( i = bbGetInputConnectorMap().begin();
00295 i != bbGetInputConnectorMap().end(); ++i )
00296 {
00297 bbtkBlackBoxDebugMessage("kernel",8,"* Delete \""<<i->first<<"\""<<std::endl);
00298 delete (i->second);
00299 }
00300 OutputConnectorMapType::const_iterator o;
00301 for ( o = bbGetOutputConnectorMap().begin();
00302 o != bbGetOutputConnectorMap().end(); ++o )
00303 {
00304 bbtkBlackBoxDebugMessage("kernel",8,"* Delete \""<<o->first<<"\""<<std::endl);
00305 delete (o->second);
00306 }
00307
00308 bbtkDebugDecTab("kernel",8);
00309 }
00310
00311
00312
00313
00314 void BlackBox::bbCopyIOValues(BlackBox& from)
00315 {
00316 bbtkBlackBoxDebugMessage("kernel",1,
00317 "BlackBox::bbCopyIOValues("
00318 <<from.bbGetFullName()<<")"
00319 <<std::endl);
00320
00321 const BlackBoxDescriptor::InputDescriptorMapType& imap
00322 = bbGetDescriptor()->GetInputDescriptorMap();
00323 BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;
00324 for ( i = imap.begin(); i != imap.end(); ++i )
00325 {
00326 if (! i->second->GetCopyConstruct() ) continue;
00327 std::string input = i->second->GetName();
00328 bbtkBlackBoxDebugMessage("kernel",2,"* Copying input "<<input<<std::endl);
00329 this->bbSetInput(input, from.bbGetInput(input) );
00330 }
00331
00332 const BlackBoxDescriptor::OutputDescriptorMapType& omap
00333 = bbGetDescriptor()->GetOutputDescriptorMap();
00334 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
00335 for ( o = omap.begin(); o != omap.end(); ++o )
00336 {
00337 if (! o->second->GetCopyConstruct() ) continue;
00338 std::string output = o->second->GetName();
00339 bbtkBlackBoxDebugMessage("kernel",2,"* Copying output "<<output<<std::endl);
00340 this->bbSetOutput(output, from.bbGetOutput(output) );
00341 }
00342
00343 bbtkDebugDecTab("kernel",9);
00344 }
00345
00346
00347
00348
00349
00350 bool BlackBox::bbCanReact() const
00351 {
00352 return ( bbGlobalGetSomeBoxExecuting()
00353 #ifdef USE_WXWIDGETS
00354 || Wx::IsSomeWindowAlive()
00355 #endif
00356 );
00357 }
00358
00359
00360
00361
00362
00363 BlackBox::BoxProcessModeValue BlackBox::bbGetBoxProcessModeValue() const
00364 {
00365 const std::string& p = bbmBoxProcessMode;
00366 if ( (p == "0") ||
00367 (p == "P") || (p == "p") ||
00368 (p == "Pipeline") || (p == "pipeline") ) return bbPipeline;
00369 if ( (p == "1") ||
00370 (p == "A") || (p == "a") ||
00371 (p == "Always") || (p == "always") ) return bbAlways;
00372 if ( (p == "2") ||
00373 (p == "R") || (p == "r") ||
00374 (p == "Reactive") || (p == "reactive") )
00375 return bbReactive;
00376
00377
00378
00379
00380
00381 bbtkError(bbGetFullName()<<" : BoxProcessMode value '"<<p
00382 <<"' unknown. Possible values : "
00383 <<"'0'/'P'/'p'/'Pipeline'/'pipeline' | "
00384 <<"'1'/'A'/'a'/'Always'/'always' | "
00385 <<"'2'/'R'/'r'/'Reactive'/'reactive'"
00386
00387 <<std::endl);
00388 }
00389
00390
00391
00392 bool BlackBox::bbBoxProcessModeIsReactive() const
00393 {
00394 return (bbGetBoxProcessModeValue() == bbReactive);
00395 }
00396
00397
00398
00399 bool BlackBox::bbBoxProcessModeIsAlways() const
00400 {
00401 return (bbGetBoxProcessModeValue() == bbAlways);
00402 }
00403
00404
00405
00406
00407
00408
00409 void BlackBox::bbAddOutputObserver(const std::string& output,
00410 OutputChangeCallbackType f)
00411 {
00412 bbGetOutputConnector(output).AddChangeObserver(f);
00413 }
00414
00415
00416
00417 void BlackBox::bbRemoveOutputObserver(const std::string& output_name,
00418 OutputChangeCallbackType f)
00419 {
00420 bbtkError("BlackBox::RemoveChangeObserver NOT IMPLEMENTED");
00421 }
00422
00423
00424
00425
00426 void BlackBox::bbSetStatusAndPropagate(BlackBoxInputConnector* c,
00427 IOStatus s)
00428 {
00429 bbtkBlackBoxDebugMessage("change",5,
00430 "=> BlackBox::bbSetStatusAndPropagate(input,"
00431 <<GetIOStatusString(s)<<")"
00432 <<std::endl);
00433
00434 if (s==UPTODATE) bbtkError("bbSetStatusAndPropagate with status UPTODATE!");
00435 c->SetStatus(s);
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 OutputConnectorMapType::const_iterator o;
00446 for ( o = bbGetOutputConnectorMap().begin();
00447 o != bbGetOutputConnectorMap().end(); ++o )
00448 {
00449 if (o->second->GetStatus()==UPTODATE)
00450 {
00451 o->second->SetStatus(OUTOFDATE);
00452 o->second->SignalChange(GetThisPointer<BlackBox>(),o->first);
00453 }
00454 }
00455
00456 if ( ( bbBoxProcessModeIsReactive()
00457 || (c==bbGetInputConnectorMap().find("BoxExecute")->second))
00458 && (bbCanReact() ) )
00459 {
00460 bbtkBlackBoxDebugMessage("change",2,
00461 "-> Execution triggered by Reactive mode or BoxExecute input change"<<std::endl);
00462 bbGlobalAddToExecutionList( GetThisPointer<BlackBox>() );
00463 }
00464 bbtkBlackBoxDebugMessage("change",5,
00465 "<= BlackBox::bbSetStatusAndPropagate(input)"
00466 <<std::endl);
00467 }
00468
00469
00470
00471
00472 void BlackBox::bbSignalOutputModification(bool reaction)
00473 {
00474 bbtkBlackBoxDebugMessage("change",5,
00475 "=> BlackBox::bbSignalOutputModification("
00476 <<reaction<<")"
00477 <<"]"<<std::endl);
00478
00479 OutputConnectorMapType::iterator i;
00480 for ( i = bbGetOutputConnectorMap().begin();
00481 i != bbGetOutputConnectorMap().end(); ++i)
00482 {
00483
00484
00485
00486
00487
00488
00489
00490 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
00491
00492 }
00493
00494 if (reaction) bbGlobalProcessExecutionList();
00495
00496 bbtkBlackBoxDebugMessage("change",5,
00497 "<= BlackBox::bbSignalOutputModification()"
00498 <<std::endl);
00499 }
00500
00501
00502
00503
00504 void BlackBox::bbSignalOutputModification(const std::string& output,
00505 bool reaction)
00506 {
00507 bbtkBlackBoxDebugMessage("change",5,
00508 "=> BlackBox::bbSignalOutputModification("
00509 <<output<<","<<reaction<<")"
00510 <<std::endl);
00511
00512 OutputConnectorMapType::iterator i =
00513 bbGetOutputConnectorMap().find(output);
00514
00515
00516 if ( i == bbGetOutputConnectorMap().end() )
00517 {
00518 bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<output<<") : unknown output");
00519 }
00520
00521
00522
00523 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
00524
00525 if (output != "BoxChange")
00526 {
00527 i = bbGetOutputConnectorMap().find("BoxChange");
00528 if ( i != bbGetOutputConnectorMap().end() )
00529 {
00530 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
00531 }
00532 }
00533 if (reaction) bbGlobalProcessExecutionList();
00534
00535
00536 bbtkBlackBoxDebugMessage("change",5,
00537 "<= BlackBox::bbSignalOutputModification("
00538 <<output<<")"
00539 <<std::endl);
00540 }
00541
00542
00543 void BlackBox::bbSignalOutputModification(const std::vector<std::string>& output,
00544 bool reaction)
00545 {
00546 bbtkBlackBoxDebugMessage("change",5,
00547 "=> BlackBox::bbSignalOutputModification(vector of outputs)"
00548 <<std::endl);
00549 OutputConnectorMapType::iterator i;
00550 std::vector<std::string>::const_iterator o;
00551 bool changed = false;
00552 for (o=output.begin();o!=output.end();++o)
00553 {
00554
00555 if (*o == "BoxChange") continue;
00556
00557 i = bbGetOutputConnectorMap().find(*o);
00558 if ( i == bbGetOutputConnectorMap().end() )
00559 {
00560 bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<*o<<") : unknown output");
00561 }
00562
00563
00564
00565 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
00566 changed = true;
00567
00568 }
00569
00570 i = bbGetOutputConnectorMap().find("BoxChange");
00571 if ( changed && (i != bbGetOutputConnectorMap().end()))
00572 {
00573
00574
00575 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
00576 if (reaction) bbGlobalProcessExecutionList();
00577
00578 }
00579
00580 bbtkBlackBoxDebugMessage("change",5,
00581 "<= BlackBox::bbSignalOutputModification(vector of outputs)"
00582 <<std::endl);
00583 }
00584
00585
00586
00587
00588
00589
00590
00591
00592
00594 void BlackBox::bbExecute(bool force)
00595 {
00596 bbtkBlackBoxDebugMessage("process",2,
00597 "=> BlackBox::bbExecute("<<(int)force<<")"
00598 <<std::endl);
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611 if (bbGlobalGetFreezeExecution())
00612 {
00613 bbtkBlackBoxDebugMessage("process",2,
00614 " -> FreezeExecution global flag is 'true' : abort execution"<<std::endl);
00615 }
00616
00617 BBTK_BUSY_CURSOR;
00618
00619
00620
00621
00622
00623 bbRecursiveExecute(Connection::Pointer());
00624
00625 bbtkBlackBoxDebugMessage("process",2,
00626 "<= BlackBox::bbExecute()"
00627 <<std::endl);
00628 }
00629
00630
00631
00632 void BlackBox::bbInitializeProcessing()
00633 {
00634 if (!bbmInitialized)
00635 {
00636 bbtkBlackBoxDebugMessage("process",2,"** Initialize processing"
00637 <<std::endl);
00638 this->bbRecursiveInitializeProcessing();
00639 bbmInitialized = true;
00640 }
00641 }
00642
00643
00644
00645 void BlackBox::bbFinalizeProcessing()
00646 {
00647 if (bbmInitialized)
00648 {
00649 bbtkBlackBoxDebugMessage("process",2,"** Finalize processing"
00650 <<std::endl);
00651 this->bbRecursiveFinalizeProcessing();
00652 bbmInitialized = false;
00653 }
00654 }
00655
00656
00657
00658
00659 void BlackBox::bbRecursiveExecute( Connection::Pointer caller )
00660 {
00661 bbtkBlackBoxDebugMessage("process",3,
00662 "=> BlackBox::bbRecursiveExecute("
00663 <<(caller?caller->GetFullName():"0")<<")"
00664 <<std::endl);
00665
00666
00667 if (bbGetExecuting())
00668 {
00669 bbtkBlackBoxDebugMessage("process",3,
00670 " -> already executing : abort"<<std::endl);
00671 return;
00672 }
00673
00674
00675 bbInitializeProcessing();
00676
00677 bbSetExecuting(true);
00678 bool wasExecuting = bbGlobalGetSomeBoxExecuting();
00679 bbGlobalSetSomeBoxExecuting(true);
00680
00681
00682 this->bbCreateWindow();
00683
00684
00685 IOStatus s = bbUpdateInputs();
00686
00687 if ( (s != UPTODATE) ||
00688 bbBoxProcessModeIsAlways() )
00689 {
00690
00691
00692
00693
00694 this->bbProcess();
00695
00696
00697
00698 bbComputePostProcessStatus();
00699 }
00700 else
00701 {
00702
00703 OutputConnectorMapType::iterator o;
00704 for ( o = bbGetOutputConnectorMap().begin();
00705 o!= bbGetOutputConnectorMap().end(); ++o)
00706 {
00707 if (o->second->GetStatus() != UPTODATE)
00708 {
00709 bbtkWarning("BlackBox::bbRecursiveExecute: "
00710 <<"all inputs are Up-to-date but output '"
00711 <<o->first<<"' is Out-of-date ???");
00712 }
00713 }
00714
00715 bbtkBlackBoxDebugMessage("process",3," -> Up-to-date : nothing to do"
00716 <<std::endl);
00717 }
00718
00719
00720 this->bbShowWindow();
00721
00722
00723 bbtkBlackBoxDebugMessage("process",3,
00724 "<= BlackBox::bbRecursiveExecute()"
00725 <<std::endl);
00726
00727 bbSetExecuting(false);
00728 bbGlobalSetSomeBoxExecuting(wasExecuting);
00729
00730 return;
00731 }
00732
00733
00734
00735
00736
00737
00738
00739 IOStatus BlackBox::bbUpdateInputs()
00740 {
00741 bbtkBlackBoxDebugMessage("process",4,
00742 "=> BlackBox::bbUpdateInputs()"
00743 <<std::endl);
00744
00745 IOStatus s = UPTODATE;
00746
00747 InputConnectorMapType::iterator i;
00748 for ( i = bbGetInputConnectorMap().begin();
00749 i!= bbGetInputConnectorMap().end(); ++i)
00750 {
00751
00752
00753
00754
00755
00756 bbtkBlackBoxDebugMessage("change",2,
00757 "Input '"<<i->first
00758 <<"': status before update = '"
00759 <<GetIOStatusString(i->second->GetStatus())
00760 <<"'"<<std::endl);
00761 i->second->RecursiveExecute();
00762 IOStatus t = i->second->GetStatus();
00763 if (t > s) s = t;
00764 bbtkBlackBoxDebugMessage("change",2,
00765 "Input '"<<i->first
00766 <<"': status before process = '"
00767 <<GetIOStatusString(i->second->GetStatus())
00768 <<"'"<<std::endl);
00769 }
00770
00771 bbtkBlackBoxDebugMessage("process",4,
00772 "<= BlackBox::bbUpdateInputs()"
00773 <<std::endl);
00774 return s;
00775 }
00776
00777
00778
00779 void BlackBox::bbComputePostProcessStatus()
00780 {
00781 bbtkBlackBoxDebugMessage("process",4,
00782 "=> BlackBox::bbComputePostProcessStatus()"
00783 <<std::endl);
00784
00785 IOStatus new_output_status = UPTODATE;
00786 if (bbBoxProcessModeIsAlways()) new_output_status = OUTOFDATE;
00787
00788
00789 InputConnectorMapType::iterator i;
00790 for ( i = bbGetInputConnectorMap().begin();
00791 i!= bbGetInputConnectorMap().end(); ++i)
00792 {
00793 IOStatus t = i->second->GetStatus();
00794 if (t == OUTOFDATE) new_output_status = OUTOFDATE;
00795
00796 if (t==MODIFIED) i->second->SetStatus(UPTODATE);
00797 bbtkBlackBoxDebugMessage("change",2,
00798 "Input '"<<i->first<<"' : "
00799 << GetIOStatusString(t) << " -> "
00800 << GetIOStatusString(i->second->GetStatus())
00801 << std::endl);
00802 }
00803 bbtkBlackBoxDebugMessage("change",2,
00804 "New output status : "
00805 << GetIOStatusString(new_output_status)
00806 <<std::endl);
00807
00808 OutputConnectorMapType::iterator o;
00809 for ( o = bbGetOutputConnectorMap().begin();
00810 o!= bbGetOutputConnectorMap().end(); ++o)
00811 {
00812 o->second->SetStatus(new_output_status);
00813 }
00814
00815 bbtkBlackBoxDebugMessage("process",4,
00816 "<= BlackBox::bbComputePostProcessStatus()"
00817 <<std::endl);
00818 }
00819
00820
00821
00822 void BlackBox::bbConnectInput( const std::string& name, Connection* c)
00823 {
00824 bbtkBlackBoxDebugMessage("connection",2,
00825 "==> BlackBox::bbConnectInput(\""
00826 <<name<<"\","<<c->GetFullName()<<")"
00827 <<std::endl);
00828
00829 InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
00830 if (i==bbGetInputConnectorMap().end())
00831 {
00832 bbtkError("no input called '"<<name<<"'");
00833 }
00834 i->second->SetConnection(c);
00835
00836 bbSetStatusAndPropagate(i->second,OUTOFDATE);
00837
00838 bbtkBlackBoxDebugMessage("connection",2,
00839 "<== BlackBox::bbConnectInput(\""
00840 <<name<<"\","<<c->GetFullName()<<")"
00841 <<std::endl);
00842 }
00843
00844
00845
00846
00847 void BlackBox::bbConnectOutput( const std::string& name, Connection* c)
00848 {
00849 bbtkBlackBoxDebugMessage("connection",2,
00850 "==> BlackBox::bbConnectOutput(\""<<name<<"\","
00851 <<c->GetFullName()<<")"
00852 <<std::endl);
00853
00854 OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
00855 if (i==bbGetOutputConnectorMap().end())
00856 {
00857 bbtkError("no output called '"<<name<<"'");
00858 }
00859 i->second->SetConnection(c);
00860
00861 bbtkBlackBoxDebugMessage("connection",2,
00862 "<== BlackBox::bbConnectOutput(\""<<name<<"\","
00863 <<c->GetFullName()<<")"
00864 <<std::endl);
00865 }
00866
00867
00868
00869
00870 void BlackBox::bbDisconnectInput( const std::string& name, Connection* c)
00871 {
00872
00873 bbtkBlackBoxDebugMessage("connection",2,
00874 "==> BlackBox::bbDisconnectInput(\""<<name
00875 <<"\","<<c->GetFullName()<<")"
00876 <<std::endl);
00877 if (!c)
00878 {
00879
00880 bbtkBlackBoxDebugMessage("connection",2,"c==0"<<std::endl);
00881 return;
00882 }
00883
00884 InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
00885 if (i==bbGetInputConnectorMap().end())
00886 {
00887 bbtkError("no input called '"<<name<<"'");
00888 }
00889 i->second->UnsetConnection(c);
00890
00891 bbtkBlackBoxDebugMessage("connection",2,
00892 "<== BlackBox::bbDisconnectInput(\""<<name
00893 <<"\","<<c->GetFullName()<<")"
00894 <<std::endl);
00895
00896 }
00897
00898
00899
00900
00901 void BlackBox::bbDisconnectOutput( const std::string& name, Connection* c)
00902 {
00903 bbtkBlackBoxDebugMessage("connection",2,
00904 "==> BlackBox::bbDisconnectOutput(\""<<name
00905 <<"\","<<c->GetFullName()<<")"
00906 <<std::endl);
00907 if (!c)
00908 {
00909
00910 bbtkBlackBoxDebugMessage("connection",2,"c==0"<<std::endl);
00911 return;
00912 }
00913
00914 OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
00915 if (i==bbGetOutputConnectorMap().end())
00916 {
00917 bbtkError("no output called '"<<name<<"'");
00918 }
00919 i->second->UnsetConnection(c);
00920
00921 bbtkBlackBoxDebugMessage("connection",2,
00922 "<== BlackBox::bbDisconnectOutput(\""<<name
00923 <<"\","<<c->GetFullName()<<")"
00924 <<std::endl);
00925 }
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951 void BlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level)
00952 {
00953 fprintf(ff,"%s%p",bbGetTypeName().c_str(),this);
00954 }
00955
00956
00957
00958
00959 std::string BlackBox::bbGetOutputAsString( const std::string &output )
00960 {
00961 std::string v;
00962
00963 if (bbGetOutputType(output).name() != typeid(std::string).name() )
00964 {
00965
00966 Package::Pointer p = bbGetDescriptor()->GetPackage();
00967 if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
00968 {
00969 Factory::Pointer f = p->GetFactorySet().begin()->lock();
00970 BlackBox::Pointer a;
00971 try
00972 {
00973 a = f->NewAdaptor(
00974 bbGetOutputType(output),
00975 typeid(std::string),
00976 "");
00977 } catch (bbtk::Exception e)
00978 {
00979 }
00980 if (a){
00981
00982 a->bbSetInput("In",bbGetOutput(output));
00983 a->bbExecute();
00984 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
00985 } else {
00986 v="? (no adaptor found)";
00987 }
00988 }
00989 else
00990 {
00991 v="? (no factory found)";
00992 }
00993 }
00994 else
00995 {
00996
00997 v = bbGetOutput(output).unsafe_get<std::string>() ;
00998 }
00999 return v;
01000 }
01001
01002
01003
01004 std::string BlackBox::bbGetInputAsString( const std::string &input )
01005 {
01006 std::string v;
01007
01008 if (bbGetInputType(input) != typeid(std::string))
01009 {
01010
01011 Package::Pointer p = bbGetDescriptor()->GetPackage();
01012 if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
01013 {
01014 Factory::Pointer f = p->GetFactorySet().begin()->lock();
01015 BlackBox::Pointer a;
01016 try
01017 {
01018 a = f->NewAdaptor(
01019 bbGetInputType(input),
01020 typeid(std::string),
01021 "");
01022 }catch (bbtk::Exception e)
01023 {
01024 }
01025 if (a)
01026 {
01027
01028 a->bbSetInput("In",bbGetInput(input));
01029 a->bbExecute();
01030 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
01031 }
01032 else
01033 {
01034 v="? (no adaptor found)";
01035 }
01036 }
01037 else
01038 {
01039 v="? (no factory found)";
01040 }
01041 }
01042 else
01043 {
01044 v = bbGetInput(input).unsafe_get<std::string>() ;
01045 }
01046 return v;
01047 }
01048
01049
01050
01051
01052 void SubsBrackets ( std::string& s )
01053 {
01054
01055 std::string ss("<");
01056 std::string::size_type pos = 0;
01057 pos = s.find(ss,0);
01058 std::string cr("[");
01059 while ( pos != std::string::npos )
01060 {
01061
01062 s.replace(pos,1,cr.c_str(),1);
01063 pos = s.find(ss, pos);
01064 }
01065 ss = ">";
01066 pos = 0;
01067 pos = s.find(ss,0);
01068 cr = "]";
01069 while ( pos != std::string::npos )
01070 {
01071
01072 s.replace(pos,1,cr.c_str(),1);
01073 pos = s.find(ss, pos);
01074 }
01075 ss = ",";
01076 pos = 0;
01077 pos = s.find(ss,0);
01078 cr = "-";
01079 while ( pos != std::string::npos )
01080 {
01081
01082 s.replace(pos,1,cr.c_str(),1);
01083 pos = s.find(ss, pos);
01084 }
01085 }
01086
01087
01088
01090 void BlackBox::bbWriteDotFileBlackBox(FILE *ff,
01091 BlackBox::Pointer parentblackbox,
01092 int detail, int level,
01093 bool instanceOrtype,
01094 bool relative_link )
01095
01096 {
01097 InputConnectorMapType::iterator i;
01098
01099 std::string labelStr;
01100 std::string valueStr("");
01101
01102 if (detail==0) {
01103 labelStr = bbGetName() ;
01104
01105 labelStr = labelStr + "\\n[" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]";
01106 } else {
01107 labelStr = bbGetName();
01108 labelStr = labelStr + " [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "] ";
01109 }
01110
01111 SubsBrackets(labelStr);
01112 if (detail==1)
01113 {
01114 labelStr = labelStr + " | {{ ";
01115 std::string tempStrTypeName;
01116 bool tmp;
01117 tmp=false;
01118 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
01119 {
01120 if (tmp==true)
01121 {
01122 labelStr=labelStr+" | ";
01123 }
01124 tmp=true;
01125 if (instanceOrtype==true)
01126 {
01127 valueStr = this->bbGetInputAsString(i->first) + " = ";
01128 }
01129 const BlackBoxInputDescriptor* id = bbGetDescriptor()->GetInputDescriptor(i->first);
01130 tempStrTypeName=id->GetTypeName();
01131 SubsBrackets(tempStrTypeName);
01132 std::string Name(i->first);
01133 SubsBrackets(Name);
01134 labelStr=labelStr + "<"+i->first.c_str()+"> " + valueStr + Name.c_str() + " [" + tempStrTypeName.c_str() + "]";
01135 }
01136 labelStr=labelStr+ " } | {";
01137 tmp = false;
01138 OutputConnectorMapType::iterator ii;
01139 for ( ii = mOutputConnectorMap.begin(); ii != mOutputConnectorMap.end(); ++ii )
01140 {
01141 if (tmp==true)
01142 {
01143 labelStr=labelStr+" | ";
01144 }
01145 tmp = true;
01146 if (instanceOrtype==true)
01147 {
01148 valueStr = this->bbGetOutputAsString(ii->first) + " = ";
01149 }
01150 const BlackBoxOutputDescriptor* id = bbGetDescriptor()->GetOutputDescriptor(ii->first);
01151 tempStrTypeName=id->GetTypeName();
01152 SubsBrackets(tempStrTypeName);
01153 std::string Name(ii->first);
01154 SubsBrackets(Name);
01155 labelStr=labelStr+"<"+ii->first.c_str()+"> " + valueStr + Name.c_str() + " ["+tempStrTypeName+"]";
01156 }
01157 labelStr = labelStr+ " } }" ;
01158 }
01159
01160 fprintf(ff," " );
01161 bbWriteDotInputOutputName(ff,true,detail,level);
01162 std::string tmp ( bbGetTypeName() );
01163 SubsBrackets(tmp);
01164 std::string url;
01165 if (relative_link)
01166 url = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL() + "#" + tmp;
01167 else
01168 url = this->bbGetDescriptor()->GetPackage()->GetDocURL() + "#" + tmp;
01169
01170 fprintf( ff , " [shape=record, URL=\"%s\",label=\"%s\"]%s\n",url.c_str(),labelStr.c_str(),";" );
01171
01172
01173
01174 if (GetThisPointer<BlackBox>()!=parentblackbox){
01175 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
01176 {
01177 if (i->second)
01178 {
01179 Connection* con = i->second->GetConnection();
01180 if (con!=NULL){
01181 BlackBox::Pointer a=con->GetOriginalBlackBoxFrom();
01182 BlackBox::Pointer b=con->GetOriginalBlackBoxTo();
01183 fprintf(ff," ");
01184 a->bbWriteDotInputOutputName(ff,false,detail,level);
01185 if (detail==1)
01186 {
01187 fprintf(ff,":%s",con->GetOriginalBlackBoxFromOutput().c_str());
01188 }
01189 fprintf(ff,"->");
01190 b->bbWriteDotInputOutputName(ff,true,detail,level);
01191 if (detail==1)
01192 {
01193 fprintf(ff,":%s",con->GetOriginalBlackBoxToInput().c_str());
01194 }
01195 fprintf(ff,"%s\n",";");
01196 }
01197 }
01198 }
01199 }
01200 }
01201
01202
01203
01204
01205
01206
01207 void BlackBox::bbPrintHelp(BlackBox::Pointer parentblackbox,
01208 int detail, int level
01209 )
01210 {
01211
01212 if (this->bbGetDescriptor()->GetPackage())
01213 {
01214 bbtkBlackBoxMessage("help",1,"Black Box '"<<bbGetName()<<"' <"<<
01215 this->bbGetDescriptor()->GetPackage()->GetName()
01216 <<"::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
01217 }
01218 else
01219 {
01220 bbtkBlackBoxMessage("help",1,"Black Box <::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
01221 }
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237 std::vector<std::string> iname;
01238 std::vector<std::string> ivalue;
01239 std::vector<std::string> iconn;
01240 std::vector<std::string> istatus;
01241
01242 InputConnectorMapType::iterator i;
01243 unsigned int namelmax = 0;
01244 unsigned int valuelmax = 0;
01245
01246 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
01247 {
01248 iname.push_back(i->first);
01249 if (iname.back().size()>namelmax) namelmax = iname.back().size();
01250 ivalue.push_back(bbGetInputAsString(i->first));
01251 if (ivalue.back().size()>valuelmax) valuelmax = ivalue.back().size();
01252 std::string s("");
01253 Connection* con = i->second->GetConnection();
01254 if (con!=0){
01255 s = con->GetOriginalBlackBoxFrom()->bbGetName();
01256 s += ".";
01257 s += con->GetOriginalBlackBoxFromOutput();
01258 }
01259 iconn.push_back(s);
01260 istatus.push_back(GetIOStatusString(i->second->GetStatus()));
01261 }
01262 OutputConnectorMapType::iterator o;
01263 std::vector<std::string> oname;
01264 std::vector<std::string> ovalue;
01265 std::vector<std::vector<std::string> > oconn;
01266 std::vector<std::string> ostatus;
01267 for ( o = mOutputConnectorMap.begin(); o != mOutputConnectorMap.end(); ++o )
01268 {
01269 oname.push_back(o->first);
01270 if (oname.back().size()>namelmax)
01271 namelmax = oname.back().size();
01272 ovalue.push_back(bbGetOutputAsString(o->first));
01273 if (ovalue.back().size()>valuelmax)
01274 valuelmax = ovalue.back().size();
01275 std::vector<std::string> ss;
01276 const std::vector<Connection*>& con
01277 = o->second->GetConnectionVector();
01278 std::vector<Connection*>::const_iterator c;
01279 for (c=con.begin();c!=con.end();++c)
01280 {
01281 std::string s;
01282 s = (*c)->GetOriginalBlackBoxTo()->bbGetName();
01283 s += ".";
01284 s += (*c)->GetOriginalBlackBoxToInput();
01285 ss.push_back(s);
01286 }
01287 oconn.push_back(ss);
01288 ostatus.push_back(GetIOStatusString(o->second->GetStatus()));
01289 }
01290
01291 if (iname.size())
01292 bbtkBlackBoxMessage("help",1," * Inputs : "<<std::endl);
01293 else
01294 bbtkBlackBoxMessage("help",1," * No inputs"<<std::endl);
01295
01296 std::vector<std::string>::iterator i1,i2,i3,i4;
01297 for (i1=iname.begin(),i2=ivalue.begin(),i3=iconn.begin(),i4=istatus.begin();
01298 i1!=iname.end(),i2!=ivalue.end(),i3!=iconn.end(),i4!=istatus.end();
01299 ++i1,++i2,++i3,++i4)
01300 {
01301 std::string name(*i1);
01302 name += "'";
01303 name.append(1+namelmax-name.size(),' ');
01304 std::string value(*i2);
01305 value += "'";
01306 value.append(1+valuelmax-value.size(),' ');
01307 if (i3->size())
01308 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value<<" <-- '" <<*i3<<"'");
01309 else
01310 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value);
01311 bbtkBlackBoxMessage("help",1," ["<<*i4<<"]"<<std::endl);
01312 }
01313
01314 if (oname.size())
01315 bbtkBlackBoxMessage("help",1," * Outputs : "<<std::endl);
01316 else
01317 bbtkBlackBoxMessage("help",1," * No outputs"<<std::endl);
01318
01319 std::vector<std::vector<std::string> >::iterator i5;
01320
01321 for (i1=oname.begin(),i2=ovalue.begin(),i5=oconn.begin(),i4=ostatus.begin();
01322 i1!=oname.end(),i2!=ovalue.end(),i5!=oconn.end(),i4!=ostatus.end();
01323 ++i1,++i2,++i4,++i5)
01324 {
01325 std::string name(*i1);
01326 name += "'";
01327 name.append(1+namelmax-name.size(),' ');
01328 std::string value(*i2);
01329 value += "'";
01330 value.append(1+valuelmax-value.size(),' ');
01331 if (!(*i5).size())
01332 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value);
01333 else
01334 {
01335 std::string pref = " '"+name+" = '"+value;
01336 for (i3=i5->begin();i3!=i5->end();++i3)
01337 {
01338 bbtkBlackBoxMessage("help",1,pref<<" --> '"<<*i3<<"'");
01339 pref.replace(0,pref.size(),pref.size(),' ');
01340 }
01341 }
01342 bbtkBlackBoxMessage("help",1," ["<<*i4<<"]"<<std::endl);
01343 }
01344
01345 }
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365 static bool bbmgGlobalProcessingExecutionList = false;
01366
01367
01368 void BlackBox::bbGlobalProcessExecutionList()
01369 {
01370 bbtkDebugMessage("process",3,
01371 "=> BlackBox::bbGlobalProcessExecutionList()"
01372 <<std::endl);
01373 if (bbmgGlobalProcessingExecutionList)
01374 {
01375 bbtkDebugMessage("process",3,"BlackBox::bbGlobalProcessExecutionList() reentered !");
01376 return;
01377 }
01378 bbmgGlobalProcessingExecutionList = true;
01379
01380 std::set<BlackBox::WeakPointer>::iterator i;
01381 while (bbmgExecutionList.size()>0)
01382 {
01383 i = bbmgExecutionList.begin();
01384 BlackBox::WeakPointer p = *i;
01385 bbmgExecutionList.erase(i);
01386 if (p.lock())
01387 {
01388 bbtkDebugMessage("process",4,
01389 " -> Executing '"<<
01390 p.lock()->bbGetName()<<"'"<<std::endl);
01391 p.lock()->bbExecute(true);
01392 }
01393 else
01394 {
01395 bbtkGlobalError("Strange error in BlackBox::bbGlobalProcessExecutionList() : Weak bb pointer in bbmgExecutionList is no more valid...");
01396 }
01397 }
01398
01399 bbmgExecutionList.clear();
01400 bbtkDebugMessage("process",3,
01401 "<= BlackBox::bbGlobalProcessExecutionList()"
01402 <<std::endl);
01403
01404 bbmgGlobalProcessingExecutionList = false;
01405
01406 }
01407
01408
01409 bool BlackBox::bbGlobalGetSomeBoxExecuting()
01410 {
01411 return bbmgSomeBoxExecuting;
01412 }
01413
01414 void BlackBox::bbGlobalSetSomeBoxExecuting(bool b)
01415 {
01416 bbmgSomeBoxExecuting = b;
01417 }
01418
01419 void BlackBox::bbGlobalSetFreezeExecution(bool b)
01420 {
01421 bbmgFreezeExecution = b;
01422 }
01423
01424 bool BlackBox::bbGlobalGetFreezeExecution()
01425 {
01426 return bbmgFreezeExecution;
01427 }
01428
01429 void BlackBox::bbGlobalAddToExecutionList( BlackBox::Pointer b )
01430 {
01431 bbtkDebugMessage("process",3,"* bbGlobalAddToExecutionList("<<b->bbGetName()<<")"<<std::endl);
01432 if (bbmgGlobalProcessingExecutionList)
01433 {
01434 bbtkDebugMessage("process",3,"bbGlobalAddToExecutionList called inside bbGlobalProcessExecutionList !");
01435 }
01436 bbmgExecutionList.insert(b);
01437 }
01438
01439
01440
01441
01442
01443 void BlackBox::Check(bool recursive)
01444 {
01445 bbtkBlackBoxMessage("debug",1,"*** Checking"
01446 <<" ... OK"<<std::endl);
01447 }
01448
01449
01450
01451
01452
01453 }
01454
01455
01456