1 /*=========================================================================
4 Module: $RCSfile: bbtkConnection.cxx,v $
6 Date: $Date: 2008/04/09 11:16:57 $
7 Version: $Revision: 1.6 $
9 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10 l'Image). All rights reserved. See doc/license.txt or
11 http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
13 This software is distributed WITHOUT ANY WARRANTY; without even
14 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 PURPOSE. See the above copyright notices for more information.
17 =========================================================================*/
20 *\brief Class bbtk::Connection
23 #include "bbtkConnection.h"
24 #include "bbtkFactory.h"
25 #include "bbtkBlackBox.h"
26 #include "bbtkMessageManager.h"
31 //==================================================================
32 /// Ctor with the black box from and to and their input and output.
33 /// Check the input and output compatibility
34 Connection::Connection(BlackBox* from, const std::string& output,
35 BlackBox* to, const std::string& input ,
42 bbtkDebugMessageInc("Kernel",7,"Connection::Connection(\""
43 <<from->bbGetName()<<"\",\""<<output<<"\",\""
44 <<to->bbGetName()<<"\",\""<<input<<"\")"
47 mFrom = mOriginalFrom = from;
48 mTo = mOriginalTo = to;
49 mInput = mOriginalInput = input;
50 mOutput = mOriginalOutput = output;
53 if (! from->bbHasOutput(output) )
55 bbtkError("The box \""<<from->bbGetTypeName()<<
56 "\" has no output \""<<output<<"\"");
58 if (! to->bbHasInput(input) )
60 bbtkError("The box \""<<to->bbGetTypeName()<<
61 "\" has no input \""<<input<<"\"");
64 if (to->bbGetInputConnectorMap().find(input)->second->IsConnected())
66 bbtkError("The input \""<<input<<"\" of the box \""<<to->bbGetName()
67 <<"\" is already connected");
70 // std::string t1 ( from->bbGetOutputType(output).name() );
71 // std::string t2 ( to->bbGetInputType(input).name() );
73 if ( from->bbGetOutputType(output) !=
74 to->bbGetInputType(input) )
76 if ( from->bbGetOutputType(output) == typeid(Data) )
78 bbtkWarning("Connection '"
80 <<"' : '"<<from->bbGetName()<<"."<<output
82 <<HumanTypeName<Data>()
83 <<"> : type compatibility with '"
84 <<to->bbGetName()<<"."<<input
85 <<"' will be resolved at run time"
89 else if ( to->bbGetInputType(input) == typeid(Data) )
91 bbtkDebugMessage("Kernel",8," -> '"<<input<<"' type is "
92 <<TypeName<Data>()<<" : can receive any data"
98 // std::cout << "Adaptive connection "<<std::endl;
100 name = from->bbGetName() + "." + output + "-"
101 + to->bbGetName() + "." + input;
102 mAdaptor = mFactory->NewAdaptor(from->bbGetOutputType(output),
103 to->bbGetInputType(input),
107 bbtkError("did not find any <"
108 <<TypeName(from->bbGetOutputType(output))
110 <<TypeName(to->bbGetInputType(input))
117 from->bbConnectOutput(output,this);
118 to->bbConnectInput(input,this);
120 bbtkDebugDecTab("Kernel",7);
123 //==================================================================
125 void Connection::Clear()
127 mFrom = mOriginalFrom = 0;
128 mTo = mOriginalTo = 0;
132 //==================================================================
134 Connection::~Connection()
136 bbtkDebugMessageInc("Kernel",7,
137 "Connection::~Connection() ["
138 <<GetFullName()<<"]"<<std::endl);
139 std::cout << "~Connection() " << GetFullName() << std::endl;
141 if (mFrom!=0) mFrom->bbDisconnectOutput(mOutput,this);
142 if (mTo!=0) mTo->bbDisconnectInput(mInput,this);
143 if (mAdaptor!=0) mAdaptor->bbDelete();
145 bbtkDebugDecTab("Kernel",7);
147 //==================================================================
149 //==================================================================
151 IOStatus Connection::BackwardUpdate()
153 bbtkDebugMessageInc("Process",2,
154 "Connection::BackwardUpdate() ["
155 <<GetFullName()<<"]"<<std::endl);
157 IOStatus s = UPTODATE;
158 s = mFrom->bbBackwardUpdate(this);
162 if (mAdaptor && (s==MODIFIED)) mAdaptor->bbSetModifiedStatus();
164 bbtkDebugDecTab("Process",2);
168 //==================================================================
171 //==================================================================
173 void Connection::ForwardUpdate()
175 bbtkDebugMessageInc("Process",2,
176 "Connection::ForwardUpdate() ["
177 <<GetFullName()<<"]"<<std::endl);
182 mTo->bbForwardUpdate(this);
184 bbtkDebugDecTab("Process",2);
186 //==================================================================
189 //==================================================================
190 /// Transfers the data from the source output to the target input
191 /// doing necessary conversions (adaptation or pointer cast)
192 void Connection::TransferData()
194 bbtkDebugMessageInc("Process",3,
195 "Connection::TransferData() ["
196 <<GetFullName()<<"]"<<std::endl);
199 // If an adaptor was created we need to adapt the data
202 mAdaptor->bbSetInput("In",mFrom->bbGetOutput(mOutput),false);
203 mAdaptor->bbExecute();
204 // LG : Connection Update does not set mTo as modified
205 mTo->bbSetInput(mInput, mAdaptor->bbGetOutput("Out"),false);
208 // If no adaptor but source type is an any and target is not an any
209 else if ( mFromAny && (! mToAny) )
211 bbtkDebugMessage("Data",3,
212 "Connection::TransferData() ["
213 <<GetFullName()<<"]"<<std::endl);
214 bbtkDebugMessage("Data",3,
215 " * Source type is an "
216 <<HumanTypeName<Data>()
217 <<" which contains a <"
218 <<HumanTypeName(mFrom->bbGetOutput(mOutput).type())
220 bbtkDebugMessage("Data",3,
221 " * Target type is <"
222 <<HumanTypeName(mTo->bbGetInputType(mInput))
225 // 1) Test strict type matching between any content and target
226 if (mFrom->bbGetOutput(mOutput)
227 .contains( mTo->bbGetInputType(mInput) ) )
229 bbtkDebugMessage("Data",3,
230 " -> Equal types : transfer ok"<<std::endl);
231 mTo->bbSetInput( mInput,
232 mFrom->bbGetOutput(mOutput),
237 // 2) Look for an adaptor
238 bbtk::BlackBox* adaptor = 0;
241 adaptor = mFactory->NewAdaptor(mFrom->bbGetOutput(mOutput).type(),
242 mTo->bbGetInputType(mInput),
250 bbtkDebugMessage("Data",3," -> Adaptor found : using it"
252 adaptor->bbSetInput("In",mFrom->bbGetOutput(mOutput),false);
253 adaptor->bbExecute();
254 // LG : Connection Update does not set mTo as modified
255 mTo->bbSetInput(mInput, adaptor->bbGetOutput("Out"),false);
258 // 3) If no adaptor found but the any content is a pointer
259 // and target type is also a pointer : we try run-time cast
260 else if ( (mFrom->bbGetOutput(mOutput).contains_pointer()) &&
261 (mTo->bbGetDescriptor()->GetInputDescriptor(mInput)
264 bbtkDebugMessage("Data",3,
265 " -> No adaptor found but source and target types are both pointers : trying up or down cast"<<std::endl);
268 mFrom->bbGetOutput(mOutput)
269 .get_pointer_to(mTo->bbGetInput(mInput).pointed_type());
272 bbtkError("Connection '"
275 <<HumanTypeName(mFrom->bbGetOutput(mOutput).type())
277 <<HumanTypeName(mTo->bbGetInputType(mInput))
278 <<"> : no adaptor available and run-time up and down cast failed");
280 mTo->bbBruteForceSetInputPointer(mInput, nptr, false);
282 // 4) Nothing worked : error
285 bbtkError("Connection '"<<GetFullName()<<"' "
286 <<"no adaptor found to convert <"
287 <<HumanTypeName(mFrom->bbGetOutput(mOutput).type())
289 <<HumanTypeName(mTo->bbGetInputType(mInput))<<">");
293 // EO : mFromAny && ! mToAny
294 // Default case : types are the same; we use simple get-set
297 // LG : Connection Update does not set mTo as modified
298 mTo->bbSetInput(mInput, mFrom->bbGetOutput(mOutput),false);
301 bbtkDebugDecTab("Process",3);
303 //==================================================================
305 //==================================================================
307 void Connection::SetModifiedStatus()
309 bbtkDebugMessageInc("Process",5,
310 "Connection::SetModifiedStatus() ["
311 <<GetFullName()<<"]"<<std::endl);
313 if (mAdaptor) mAdaptor->bbSetModifiedStatus();
315 mTo->bbSetModifiedStatus( mTo->bbGetInputConnectorMap().find(mInput)->second );
317 bbtkDebugDecTab("Process",5);
319 //==================================================================
322 //==================================================================
323 std::string Connection::GetFullName() const {
326 std::string res = mFrom->bbGetName()+"."+mOutput+"--"
327 +mTo->bbGetName()+"."+mInput;
328 if ((mFrom!=mOriginalFrom)||(mTo!=mOriginalTo))
330 res += "("+mOriginalFrom->bbGetName()+"."+mOriginalOutput+"--"
331 + mOriginalTo->bbGetName()+"."+mOriginalInput+")";
335 return "***Invalid Connection***";
337 //==================================================================
339 //==================================================================
340 void Connection::Check() const
342 bbtkMessage("Debug",1,"** Checking Connection "<<(void*)this<<" ["<<GetFullName()<<"]"
346 bbtkMessage("Debug",2," - From = 0"<<std::endl);
350 bbtkMessage("Debug",2," - From : "<<mFrom->bbGetFullName()<<std::endl);
351 if (!mFrom->bbHasOutput(mOutput))
353 bbtkError(mFrom->bbGetFullName()<<" does not have output '"
356 bbtkMessage("Debug",2," - From : Output '"<<mOutput<<"' exists"<<std::endl);
357 BlackBox::OutputConnectorMapType::const_iterator i
358 = mFrom->bbGetOutputConnectorMap().find(mOutput);
359 if (i== mFrom->bbGetOutputConnectorMap().end())
361 bbtkError(mFrom->bbGetFullName()<<" output '"
362 <<mOutput<<"' is not in OutputConnectorMap");
364 bbtkMessage("Debug",2," - From : Output '"<<mOutput
365 <<"' is in OutputConnectorMap"<<std::endl);
367 std::vector< Connection * >::const_iterator j;
368 j = find(i->second->GetConnectionVector().begin(),
369 i->second->GetConnectionVector().end(),
371 if (j==i->second->GetConnectionVector().end())
373 bbtkError("Connection ["<<GetFullName()<<"] : "
374 <<" OutputConnector '"
375 <<mOutput<<"' of "<<mFrom->bbGetFullName()
376 <<" does not point to this connection");
379 bbtkMessage("Debug",2," - From : This connection is in OutputConnector connection vector"<<std::endl);
380 bbtkMessage("Debug",1," * Box from : Check successfull"<<std::endl);
386 bbtkMessage("Debug",2," - To = 0"<<std::endl);
390 bbtkMessage("Debug",2," - To : "<<mTo->bbGetName()<<std::endl);
391 std::cout << mTo << std::endl;
392 std::cout << mTo->bbGetDescriptor() << std::endl;
393 std::cout << mTo->bbGetDescriptor()->GetTypeName() << std::endl;
394 mTo->bbGetFullName();
395 bbtkMessage("Debug",2," - To : "<<mTo->bbGetFullName()<<std::endl);
396 if (!mTo->bbHasInput(mInput))
398 bbtkError(mTo->bbGetFullName()<<" does not have input '"
401 bbtkMessage("Debug",2," - To : Input '"<<mInput<<"' exists"<<std::endl);
402 BlackBox::InputConnectorMapType::const_iterator i
403 = mTo->bbGetInputConnectorMap().find(mInput);
404 if (i== mTo->bbGetInputConnectorMap().end())
406 bbtkError(mTo->bbGetFullName()<<" input '"
407 <<mInput<<"' is not in InputConnectorMap");
409 bbtkMessage("Debug",2," - To : Input '"<<mInput
410 <<"' is in InputConnectorMap"<<std::endl);
412 if (i->second->GetConnection()==0)
414 bbtkError("Connection "<<GetFullName()<<" : "
415 <<" InputConnector '"
416 <<mInput<<"' of "<<mTo->bbGetFullName()
417 <<" does not point to this connection");
420 bbtkMessage("Debug",2," - To : This connection is in InputConnector connection vector"<<std::endl);
421 bbtkMessage("Debug",1," * Box to : Check successfull"<<std::endl);
425 //==================================================================