1 /*=========================================================================
4 Module: $RCSfile: bbtkConnection.cxx,v $
6 Date: $Date: 2008/01/22 15:02:00 $
7 Version: $Revision: 1.1 $
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 )
40 bbtkDebugMessageInc("Core",7,"Connection::Connection(\""
41 <<from->bbGetName()<<"\",\""<<output<<"\",\""
42 <<to->bbGetName()<<"\",\""<<input<<"\")"
51 if (! from->bbHasOutput(output) )
53 bbtkError("The box \""<<from->bbGetTypeName()<<
54 "\" has no output \""<<output<<"\"");
56 if (! to->bbHasInput(input) )
58 bbtkError("The box \""<<to->bbGetTypeName()<<
59 "\" has no input \""<<input<<"\"");
62 if (to->bbGetInputConnectorMap().find(input)->second->IsConnected())
64 bbtkError("The input \""<<input<<"\" of the box \""<<to->bbGetTypeName()
65 <<"\" is already connected");
68 // std::string t1 ( from->bbGetOutputType(output).name() );
69 // std::string t2 ( to->bbGetInputType(input).name() );
71 if ( from->bbGetOutputType(output) !=
72 to->bbGetInputType(input) )
74 if ( from->bbGetOutputType(output) == typeid(Data) )
76 bbtkWarning("Connection '"
78 <<"' : '"<<from->bbGetName()<<"."<<output
80 <<HumanTypeName<Data>()
81 <<"> : type compatibility with '"
82 <<to->bbGetName()<<"."<<input
83 <<"' will be resolved at run time"
87 else if ( to->bbGetInputType(input) == typeid(Data) )
89 bbtkDebugMessage("Core",8," -> '"<<input<<"' type is "
90 <<TypeName<Data>()<<" : can receive any data"
96 // std::cout << "Adaptive connection "<<std::endl;
98 name = from->bbGetName() + "." + output + "-"
99 + to->bbGetName() + "." + input;
100 mAdaptor = NewAdaptor(from->bbGetOutputType(output),
101 to->bbGetInputType(input),
105 bbtkError("did not find any <"
106 <<TypeName(from->bbGetOutputType(output))
108 <<TypeName(to->bbGetInputType(input))
115 from->bbConnectOutput(output,this);
116 to->bbConnectInput(input,this);
118 bbtkDebugDecTab("Core",7);
121 //==================================================================
124 //==================================================================
126 Connection::~Connection()
128 bbtkDebugMessageInc("Core",7,
129 "Connection::~Connection() ["
130 <<GetFullName()<<"]"<<std::endl);
132 mFrom->bbDisconnectOutput(mOutput,this);
133 mTo->bbDisconnectInput(mInput,this);
134 if (mAdaptor) mAdaptor->bbDelete();
136 bbtkDebugDecTab("Core",7);
138 //==================================================================
140 //==================================================================
142 IOStatus Connection::BackwardUpdate()
144 bbtkDebugMessageInc("Process",2,
145 "Connection::BackwardUpdate() ["
146 <<GetFullName()<<"]"<<std::endl);
148 IOStatus s = UPTODATE;
149 s = mFrom->bbBackwardUpdate(this);
153 if (mAdaptor && (s==MODIFIED)) mAdaptor->bbSetModifiedStatus();
155 bbtkDebugDecTab("Process",2);
159 //==================================================================
162 //==================================================================
164 void Connection::ForwardUpdate()
166 bbtkDebugMessageInc("Process",2,
167 "Connection::ForwardUpdate() ["
168 <<GetFullName()<<"]"<<std::endl);
173 mTo->bbForwardUpdate(this);
175 bbtkDebugDecTab("Process",2);
177 //==================================================================
180 //==================================================================
181 /// Transfers the data from the source output to the target input
182 /// doing necessary conversions (adaptation or pointer cast)
183 void Connection::TransferData()
185 bbtkDebugMessageInc("Process",3,
186 "Connection::TransferData() ["
187 <<GetFullName()<<"]"<<std::endl);
190 // If an adaptor was created we need to adapt the data
193 mAdaptor->bbSetInput("In",mFrom->bbGetOutput(mOutput),false);
194 mAdaptor->bbExecute();
195 // LG : Connection Update does not set mTo as modified
196 mTo->bbSetInput(mInput, mAdaptor->bbGetOutput("Out"),false);
199 // If no adaptor but source type is an any and target is not an any
200 else if ( mFromAny && (! mToAny) )
202 bbtkDebugMessage("Data",3,
203 "Connection::TransferData() ["
204 <<GetFullName()<<"]"<<std::endl);
205 bbtkDebugMessage("Data",3,
206 " * Source type is an "
207 <<HumanTypeName<Data>()
208 <<" which contains a <"
209 <<HumanTypeName(mFrom->bbGetOutput(mOutput).type())
211 bbtkDebugMessage("Data",3,
212 " * Target type is <"
213 <<HumanTypeName(mTo->bbGetInputType(mInput))
216 // 1) Test strict type matching between any content and target
217 if (mFrom->bbGetOutput(mOutput)
218 .contains( mTo->bbGetInputType(mInput) ) )
220 bbtkDebugMessage("Data",3,
221 " -> Equal types : transfer ok"<<std::endl);
222 mTo->bbSetInput( mInput,
223 mFrom->bbGetOutput(mOutput),
228 // 2) Look for an adaptor
229 bbtk::BlackBox* adaptor = 0;
232 adaptor = NewAdaptor(mFrom->bbGetOutput(mOutput).type(),
233 mTo->bbGetInputType(mInput),
241 bbtkDebugMessage("Data",3," -> Adaptor found : using it"
243 adaptor->bbSetInput("In",mFrom->bbGetOutput(mOutput),false);
244 adaptor->bbExecute();
245 // LG : Connection Update does not set mTo as modified
246 mTo->bbSetInput(mInput, adaptor->bbGetOutput("Out"),false);
249 // 3) If no adaptor found but the any content is a pointer
250 // and target type is also a pointer : we try run-time cast
251 else if ( (mFrom->bbGetOutput(mOutput).contains_pointer()) &&
252 (mTo->bbGetDescriptor()->GetInputDescriptor(mInput)
255 bbtkDebugMessage("Data",3,
256 " -> No adaptor found but source and target types are both pointers : trying up or down cast"<<std::endl);
259 mFrom->bbGetOutput(mOutput)
260 .get_pointer_to(mTo->bbGetInput(mInput).pointed_type());
263 bbtkError("Connection '"
266 <<HumanTypeName(mFrom->bbGetOutput(mOutput).type())
268 <<HumanTypeName(mTo->bbGetInputType(mInput))
269 <<"> : no adaptor available and run-time up and down cast failed");
271 mTo->bbBruteForceSetInputPointer(mInput, nptr, false);
273 // 4) Nothing worked : error
276 bbtkError("Connection '"<<GetFullName()<<"' "
277 <<"no adaptor found to convert <"
278 <<HumanTypeName(mFrom->bbGetOutput(mOutput).type())
280 <<HumanTypeName(mTo->bbGetInputType(mInput))<<">");
284 // EO : mFromAny && ! mToAny
285 // Default case : types are the same; we use simple get-set
288 // LG : Connection Update does not set mTo as modified
289 mTo->bbSetInput(mInput, mFrom->bbGetOutput(mOutput),false);
292 bbtkDebugDecTab("Process",3);
294 //==================================================================
296 //==================================================================
298 void Connection::SetModifiedStatus()
300 bbtkDebugMessageInc("Process",5,
301 "Connection::SetModifiedStatus() ["
302 <<GetFullName()<<"]"<<std::endl);
304 if (mAdaptor) mAdaptor->bbSetModifiedStatus();
306 mTo->bbSetModifiedStatus( mTo->bbGetInputConnectorMap().find(mInput)->second );
308 bbtkDebugDecTab("Process",5);
310 //==================================================================
313 //==================================================================
314 std::string Connection::GetFullName() const {
316 return mFrom->bbGetName()+"."+mOutput+"--"
317 +mTo->bbGetName()+"."+mInput;
318 return "***Invalid Connection***";
320 //==================================================================