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
00036 #include "bbtkConnection.h"
00037 #include "bbtkFactory.h"
00038 #include "bbtkBlackBox.h"
00039 #include "bbtkMessageManager.h"
00040
00041 namespace bbtk
00042 {
00043
00044 Connection::Pointer Connection::New(BlackBox::Pointer from,
00045 const std::string& output,
00046 BlackBox::Pointer to,
00047 const std::string& input ,
00048 const Factory::Pointer f )
00049 {
00050 bbtkDebugMessage("object",1,"##> Connection::Connection(\""
00051 <<from->bbGetName()<<"\",\""<<output<<"\",\""
00052 <<to->bbGetName()<<"\",\""<<input<<"\")"
00053 <<std::endl);
00054 Connection::Pointer p =
00055 MakePointer(new Connection(from,output,to,input,f));
00056 bbtkDebugMessage("object",1,"<## Connection::Connection(\""
00057 <<from->bbGetName()<<"\",\""<<output<<"\",\""
00058 <<to->bbGetName()<<"\",\""<<input<<"\")"
00059 <<std::endl);
00060 return p;
00061 }
00062
00063
00064
00067 Connection::Connection(BlackBox::Pointer from, const std::string& output,
00068 BlackBox::Pointer to, const std::string& input ,
00069 const Factory::Pointer f )
00070 : mAdaptor(),
00071 mFactory(f),
00072 mFromAny(false),
00073 mToAny(false)
00074 {
00075 bbtkDebugMessage("object",2,"==> Connection::Connection(\""
00076 <<from->bbGetName()<<"\",\""<<output<<"\",\""
00077 <<to->bbGetName()<<"\",\""<<input<<"\")"
00078 <<std::endl);
00079
00080 bbtkDebugMessage("connection",1,"==> Connection::Connection(\""
00081 <<from->bbGetFullName()<<"\",\""<<output<<"\",\""
00082 <<to->bbGetFullName()<<"\",\""<<input<<"\")"
00083 <<std::endl);
00084
00085
00086
00087 if (! from->bbHasOutput(output) )
00088 {
00089 bbtkError("The box \""<<from->bbGetTypeName()<<
00090 "\" has no output \""<<output<<"\"");
00091 }
00092 if (! to->bbHasInput(input) )
00093 {
00094 bbtkError("The box \""<<to->bbGetTypeName()<<
00095 "\" has no input \""<<input<<"\"");
00096 }
00097
00098 if (to->bbGetInputConnectorMap().find(input)->second->IsConnected())
00099 {
00100 bbtkError("The input \""<<input<<"\" of the box \""<<to->bbGetName()
00101 <<"\" is already connected");
00102 }
00103
00104
00105
00106
00107 if ( from->bbGetOutputType(output) !=
00108 to->bbGetInputType(input) )
00109 {
00110 if ( from->bbGetOutputType(output) == typeid(Data) )
00111 {
00112 bbtkWarning("Connection '"
00113 <<GetFullName()
00114 <<"' : '"<<from->bbGetName()<<"."<<output
00115 <<"' is of type <"
00116 <<HumanTypeName<Data>()
00117 <<"> : type compatibility with '"
00118 <<to->bbGetName()<<"."<<input
00119 <<"' will be resolved at run time"
00120 );
00121 mFromAny = true;
00122 }
00123 else if ( to->bbGetInputType(input) == typeid(Data) )
00124 {
00125 bbtkDebugMessage("Kernel",8," -> '"<<input<<"' type is "
00126 <<TypeName<Data>()<<" : can receive any data"
00127 <<std::endl);
00128 mToAny = true;
00129 }
00130 else
00131 {
00132
00133 std::string name;
00134 name = from->bbGetName() + "." + output + "-"
00135 + to->bbGetName() + "." + input;
00136 mAdaptor = mFactory.lock()
00137 ->NewAdaptor(from->bbGetOutputType(output),
00138 to->bbGetInputType(input),
00139 name);
00140 if (!mAdaptor)
00141 {
00142 bbtkError("did not find any <"
00143 <<TypeName(from->bbGetOutputType(output))
00144 <<"> to <"
00145 <<TypeName(to->bbGetInputType(input))
00146 <<"> adaptor");
00147 }
00148 }
00149 }
00150
00151
00152 mFrom = from;
00153 mOriginalFrom = from;
00154 mTo = to;
00155 mOriginalTo = to;
00156 mInput = mOriginalInput = input;
00157 mOutput = mOriginalOutput = output;
00158
00159
00160
00161 from->bbConnectOutput(output,this);
00162 to->bbConnectInput(input,this);
00163
00164
00165 bbtkDebugMessage("connection",1,"<== Connection::Connection(\""
00166 <<from->bbGetFullName()<<"\",\""<<output<<"\",\""
00167 <<to->bbGetFullName()<<"\",\""<<input<<"\")"
00168 <<std::endl);
00169
00170 bbtkDebugMessage("object",2,"==> Connection::Connection(\""
00171 <<from->bbGetName()<<"\",\""<<output<<"\",\""
00172 <<to->bbGetName()<<"\",\""<<input<<"\")"
00173 <<std::endl);
00174 }
00175
00176
00177
00178 Connection::Pointer Connection::New(BlackBox::Pointer from,
00179 const std::string& output,
00180 BlackBox::Pointer to,
00181 const std::string& input )
00182 {
00183 bbtkDebugMessage("object",1,"##> Connection::Connection(\""
00184 <<from->bbGetName()<<"\",\""<<output<<"\",\""
00185 <<to->bbGetName()<<"\",\""<<input<<"\")"
00186 <<std::endl);
00187 Connection::Pointer p =
00188 MakePointer(new Connection(from,output,to,input));
00189 bbtkDebugMessage("object",1,"<## Connection::Connection(\""
00190 <<from->bbGetName()<<"\",\""<<output<<"\",\""
00191 <<to->bbGetName()<<"\",\""<<input<<"\")"
00192 <<std::endl);
00193 return p;
00194 }
00195
00196
00197
00200 Connection::Connection(BlackBox::Pointer from, const std::string& output,
00201 BlackBox::Pointer to, const std::string& input )
00202 : mAdaptor(),
00203 mFactory(),
00204 mFromAny(false),
00205 mToAny(false)
00206 {
00207 bbtkDebugMessage("object",2,"==> Connection::Connection(\""
00208 <<from->bbGetName()<<"\",\""<<output<<"\",\""
00209 <<to->bbGetName()<<"\",\""<<input<<"\")"
00210 <<std::endl);
00211
00212 bbtkDebugMessage("connection",1,"==> Connection::Connection(\""
00213 <<from->bbGetFullName()<<"\",\""<<output<<"\",\""
00214 <<to->bbGetFullName()<<"\",\""<<input<<"\")"
00215 <<std::endl);
00216
00217
00218
00219 if (! from->bbHasOutput(output) )
00220 {
00221 bbtkError("The box \""<<from->bbGetTypeName()<<
00222 "\" has no output \""<<output<<"\"");
00223 }
00224 if (! to->bbHasInput(input) )
00225 {
00226 bbtkError("The box \""<<to->bbGetTypeName()<<
00227 "\" has no input \""<<input<<"\"");
00228 }
00229
00230 if (to->bbGetInputConnectorMap().find(input)->second->IsConnected())
00231 {
00232 bbtkError("The input \""<<input<<"\" of the box \""<<to->bbGetName()
00233 <<"\" is already connected");
00234 }
00235
00236
00237
00238
00239 if ( from->bbGetOutputType(output) !=
00240 to->bbGetInputType(input) )
00241 {
00242 if ( from->bbGetOutputType(output) == typeid(Data) )
00243 {
00244 bbtkWarning("Connection '"
00245 <<GetFullName()
00246 <<"' : '"<<from->bbGetName()<<"."<<output
00247 <<"' is of type <"
00248 <<HumanTypeName<Data>()
00249 <<"> : type compatibility with '"
00250 <<to->bbGetName()<<"."<<input
00251 <<"' will be resolved at run time"
00252 );
00253 mFromAny = true;
00254 }
00255 else if ( to->bbGetInputType(input) == typeid(Data) )
00256 {
00257 bbtkDebugMessage("Kernel",8," -> '"<<input<<"' type is "
00258 <<TypeName<Data>()<<" : can receive any data"
00259 <<std::endl);
00260 mToAny = true;
00261 }
00262 else
00263 {
00264 bbtkError("Connection created between different types without Factory provided");
00265 }
00266 }
00267
00268
00269 mFrom = from;
00270 mOriginalFrom = from;
00271 mTo = to;
00272 mOriginalTo = to;
00273 mInput = mOriginalInput = input;
00274 mOutput = mOriginalOutput = output;
00275
00276
00277
00278 from->bbConnectOutput(output,this);
00279 to->bbConnectInput(input,this);
00280
00281
00282 bbtkDebugMessage("connection",1,"<== Connection::Connection(\""
00283 <<from->bbGetFullName()<<"\",\""<<output<<"\",\""
00284 <<to->bbGetFullName()<<"\",\""<<input<<"\")"
00285 <<std::endl);
00286
00287 bbtkDebugMessage("object",2,"==> Connection::Connection(\""
00288 <<from->bbGetName()<<"\",\""<<output<<"\",\""
00289 <<to->bbGetName()<<"\",\""<<input<<"\")"
00290 <<std::endl);
00291 }
00292
00293
00294
00296 Connection::~Connection()
00297 {
00298 bbtkDebugMessage("object",2,
00299 "==> Connection::~Connection() ["
00300 <<GetFullName()<<"]"<<std::endl);
00301
00302 if (mAdaptor) mAdaptor.reset();
00303 if (mFrom!=0)
00304 {
00305 mFrom->bbDisconnectOutput(mOutput,this);
00306
00307 mFrom.reset();
00308 }
00309 else
00310 {
00311 bbtkInternalError("Connection::~Connection() : invalid initial box pointer");
00312 }
00313 if (mTo!=0)
00314 {
00315 mTo->bbDisconnectInput(mInput,this);
00316 mTo.reset();
00317 }
00318 else
00319 {
00320 bbtkInternalError("Connection::~Connection() : invalid final box pointer");
00321 }
00322
00323
00324 bbtkDebugMessage("object",2,
00325 "<== Connection::~Connection() ["
00326 <<GetFullName()<<"]"<<std::endl);
00327 }
00328
00329
00330
00332 IOStatus Connection::BackwardUpdate()
00333 {
00334 bbtkDebugMessage("process",5,
00335 "===> Connection::BackwardUpdate() ["
00336 <<GetFullName()<<"]"<<std::endl);
00337
00338 IOStatus s = UPTODATE;
00339 s = mFrom->bbBackwardUpdate(GetThisPointer<Connection>());
00340
00341 TransferData();
00342
00343 if (mAdaptor && (s==MODIFIED)) mAdaptor->bbSetModifiedStatus();
00344
00345 bbtkDebugMessage("process",5,
00346 "<=== Connection::BackwardUpdate() ["
00347 <<GetFullName()<<"]"<<std::endl);
00348 return s;
00349 }
00350
00351
00352
00353
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00374 void Connection::TransferData()
00375 {
00376 bbtkDebugMessageInc("data",3,
00377 "Connection::TransferData() ["
00378 <<GetFullName()<<"]"<<std::endl);
00379
00380
00381
00382 if (mAdaptor)
00383 {
00384 mAdaptor->bbSetInput("In",mFrom->bbGetOutput(mOutput),false);
00385 mAdaptor->bbExecute();
00386
00387 mTo->bbSetInput(mInput, mAdaptor->bbGetOutput("Out"),false);
00388
00389 }
00390
00391 else if ( mFromAny && (! mToAny) )
00392 {
00393 bbtkDebugMessage("data",3,
00394 " * Source type is an "
00395 <<HumanTypeName<Data>()
00396 <<" which contains a <"
00397 <<HumanTypeName(mFrom->bbGetOutput(mOutput).type())
00398 <<">"<<std::endl);
00399 bbtkDebugMessage("data",3,
00400 " * Target type is <"
00401 <<HumanTypeName(mTo->bbGetInputType(mInput))
00402 <<">"<<std::endl);
00403
00404
00405 if (mFrom->bbGetOutput(mOutput)
00406 .contains( mTo->bbGetInputType(mInput) ) )
00407 {
00408 bbtkDebugMessage("data",3,
00409 " -> Equal types : transfer ok"<<std::endl);
00410 mTo->bbSetInput( mInput,
00411 mFrom->bbGetOutput(mOutput),
00412 false);
00413 }
00414 else
00415 {
00416
00417 bbtk::BlackBox::Pointer adaptor;
00418 try
00419 {
00420 adaptor = mFactory.lock()
00421 ->NewAdaptor(mFrom->bbGetOutput(mOutput).type(),
00422 mTo->bbGetInputType(mInput),
00423 "");
00424 }
00425 catch (...)
00426 {
00427 }
00428 if (adaptor)
00429 {
00430 bbtkDebugMessage("data",3," -> Adaptor found : using it"
00431 <<std::endl);
00432 adaptor->bbSetInput("In",mFrom->bbGetOutput(mOutput),false);
00433 adaptor->bbExecute();
00434
00435 mTo->bbSetInput(mInput, adaptor->bbGetOutput("Out"),false);
00436
00437 }
00438
00439
00440 else if ( (mFrom->bbGetOutput(mOutput).contains_pointer()) &&
00441 (mTo->bbGetDescriptor()->GetInputDescriptor(mInput)
00442 ->IsPointerType()) )
00443 {
00444 bbtkDebugMessage("data",3,
00445 " -> No adaptor found but source and target types are both pointers : trying up or down cast"<<std::endl);
00446
00447 void* nptr =
00448 mFrom->bbGetOutput(mOutput)
00449 .get_pointer_to(mTo->bbGetInput(mInput).pointed_type());
00450 if (!nptr)
00451 {
00452 bbtkError("Connection '"
00453 <<GetFullName()
00454 <<"' : <"
00455 <<HumanTypeName(mFrom->bbGetOutput(mOutput).type())
00456 <<"> to <"
00457 <<HumanTypeName(mTo->bbGetInputType(mInput))
00458 <<"> : no adaptor available and run-time up and down cast failed");
00459 }
00460 mTo->bbBruteForceSetInputPointer(mInput, nptr, false);
00461 }
00462
00463 else
00464 {
00465 bbtkError("Connection '"<<GetFullName()<<"' "
00466 <<"no adaptor found to convert <"
00467 <<HumanTypeName(mFrom->bbGetOutput(mOutput).type())
00468 <<"> to <"
00469 <<HumanTypeName(mTo->bbGetInputType(mInput))<<">");
00470 }
00471 }
00472 }
00473
00474
00475 else
00476 {
00477
00478 mTo->bbSetInput(mInput, mFrom->bbGetOutput(mOutput),false);
00479 }
00480
00481 }
00482
00483
00484
00486 void Connection::SetModifiedStatus()
00487 {
00488 bbtkDebugMessage("modified",2,
00489 "==> Connection::SetModifiedStatus() ["
00490 <<GetFullName()<<"]"<<std::endl);
00491
00492 if (mAdaptor) mAdaptor->bbSetModifiedStatus();
00493
00494 mTo->bbSetModifiedStatus( mTo->bbGetInputConnectorMap().find(mInput)->second );
00495
00496
00497
00498
00499
00500
00501 }
00502
00503
00504
00505
00506 std::string Connection::GetFullName() const {
00507 if (mFrom && mTo)
00508 {
00509 std::string res = mFrom->bbGetName()+"."+mOutput+"--"
00510 +mTo->bbGetName()+"."+mInput;
00511 if ((!mOriginalFrom.expired()) && (!mOriginalTo.expired()) &&
00512 ((mFrom!=mOriginalFrom.lock())||(mTo!=mOriginalTo.lock())))
00513 {
00514 res += "("+mOriginalFrom.lock()->bbGetName()
00515 +"."+mOriginalOutput+"--"
00516 + mOriginalTo.lock()->bbGetName()+"."+mOriginalInput+")";
00517 }
00518 return res;
00519 }
00520 return "***Invalid Connection***";
00521 }
00522
00523
00524
00525 void Connection::Check() const
00526 {
00527 bbtkMessage("debug",1,"** Checking Connection "<<(void*)this<<" ["<<GetFullName()<<"]"
00528 <<std::endl);
00529 if (mFrom==0)
00530 {
00531 bbtkMessage("debug",2," - From = 0"<<std::endl);
00532 }
00533 else
00534 {
00535 bbtkMessage("debug",2," - From : "<<mFrom->bbGetFullName()<<std::endl);
00536 if (!mFrom->bbHasOutput(mOutput))
00537 {
00538 bbtkError("** Checking Connection "<<(void*)this
00539 <<" ["<<GetFullName()<<"] : "
00540 << mFrom->bbGetFullName()<<" does not have output '"
00541 <<mOutput<<"'");
00542 }
00543 bbtkMessage("debug",2," - From : Output '"<<mOutput<<"' exists"<<std::endl);
00544 BlackBox::OutputConnectorMapType::const_iterator i
00545 = mFrom->bbGetOutputConnectorMap().find(mOutput);
00546 if (i== mFrom->bbGetOutputConnectorMap().end())
00547 {
00548 bbtkError("** Checking Connection "<<(void*)this
00549 <<" ["<<GetFullName()<<"] : "
00550 <<mFrom->bbGetFullName()<<" output '"
00551 <<mOutput<<"' is not in OutputConnectorMap");
00552 }
00553 bbtkMessage("debug",2," - From : Output '"<<mOutput
00554 <<"' is in OutputConnectorMap"<<std::endl);
00555
00556 std::vector< Connection* >::const_iterator j;
00557
00558
00559
00560
00561
00562
00563
00564
00565 j = find(i->second->GetConnectionVector().begin(),
00566 i->second->GetConnectionVector().end(),
00567 this);
00568
00569 if (j==i->second->GetConnectionVector().end())
00570 {
00571 bbtkError("** Checking Connection "<<(void*)this
00572 <<" ["<<GetFullName()<<"] : "
00573 << "Connection ["<<GetFullName()<<"] : "
00574 <<" OutputConnector '"
00575 <<mOutput<<"' of "<<mFrom->bbGetFullName()
00576 <<" does not point to this connection");
00577
00578 }
00579 bbtkMessage("debug",2," - From : This connection is in OutputConnector connection vector"<<std::endl);
00580 bbtkMessage("debug",2," * Box from : Check successfull"<<std::endl);
00581
00582 }
00583
00584 if (mTo==0)
00585 {
00586 bbtkMessage("debug",2," - To = 0"<<std::endl);
00587 }
00588 else
00589 {
00590 bbtkMessage("debug",2," - To : "<<mTo->bbGetName()<<std::endl);
00591
00592
00593
00594
00595 bbtkMessage("debug",2," - To : "<<mTo->bbGetFullName()<<std::endl);
00596 if (!mTo->bbHasInput(mInput))
00597 {
00598 bbtkError("** Checking Connection "<<(void*)this
00599 <<" ["<<GetFullName()<<"] : "
00600 <<mTo->bbGetFullName()<<" does not have input '"
00601 <<mInput<<"'");
00602 }
00603 bbtkMessage("debug",2," - To : Input '"<<mInput<<"' exists"<<std::endl);
00604 BlackBox::InputConnectorMapType::const_iterator i
00605 = mTo->bbGetInputConnectorMap().find(mInput);
00606 if (i== mTo->bbGetInputConnectorMap().end())
00607 {
00608 bbtkError("** Checking Connection "<<(void*)this
00609 <<" ["<<GetFullName()<<"] : "
00610 <<mTo->bbGetFullName()<<" input '"
00611 <<mInput<<"' is not in InputConnectorMap");
00612 }
00613 bbtkMessage("debug",2," - To : Input '"<<mInput
00614 <<"' is in InputConnectorMap"<<std::endl);
00615
00616 if (i->second->GetConnection()==0)
00617 {
00618 bbtkError("** Checking Connection "<<(void*)this
00619 <<" ["<<GetFullName()<<"] : "
00620 <<"Connection "<<GetFullName()<<" : "
00621 <<" InputConnector '"
00622 <<mInput<<"' of "<<mTo->bbGetFullName()
00623 <<" does not point to this connection");
00624
00625 }
00626 bbtkMessage("debug",2," - To : This connection is in InputConnector connection vector"<<std::endl);
00627 bbtkMessage("debug",2," * Box to : Check successfull"<<std::endl);
00628
00629 }
00630 }
00631
00632
00633 std::string Connection::GetObjectName() const
00634 {
00635 std::string s("Connection '");
00636 s += GetFullName();
00637 s += "'";
00638 return s;
00639 }
00640
00641
00642
00643 std::string Connection::GetObjectInfo() const
00644 {
00645 std::stringstream i;
00646 return i.str();
00647 }
00648
00649
00650
00651 size_t Connection::GetObjectSize() const
00652 {
00653 size_t s = Superclass::GetObjectSize();
00654 s += Connection::GetObjectInternalSize();
00655 return s;
00656 }
00657
00658
00659 size_t Connection::GetObjectInternalSize() const
00660 {
00661 size_t s = sizeof(Connection);
00662 return s;
00663 }
00664
00665
00666 size_t Connection::GetObjectRecursiveSize() const
00667 {
00668 size_t s = Superclass::GetObjectRecursiveSize();
00669 s += Connection::GetObjectInternalSize();
00670 return s;
00671 }
00672
00673
00674 }
00675
00676
00677
00678
00679