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