1 /*=========================================================================
4 Module: $RCSfile: bbtkConnection.cxx,v $
6 Date: $Date: 2008/03/07 10:21:30 $
7 Version: $Revision: 1.3 $
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<<"\")"
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->bbGetTypeName()
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 //==================================================================
126 //==================================================================
128 Connection::~Connection()
130 bbtkDebugMessageInc("Kernel",7,
131 "Connection::~Connection() ["
132 <<GetFullName()<<"]"<<std::endl);
134 mFrom->bbDisconnectOutput(mOutput,this);
135 mTo->bbDisconnectInput(mInput,this);
136 if (mAdaptor) mAdaptor->bbDelete();
138 bbtkDebugDecTab("Kernel",7);
140 //==================================================================
142 //==================================================================
144 IOStatus Connection::BackwardUpdate()
146 bbtkDebugMessageInc("Process",2,
147 "Connection::BackwardUpdate() ["
148 <<GetFullName()<<"]"<<std::endl);
150 IOStatus s = UPTODATE;
151 s = mFrom->bbBackwardUpdate(this);
155 if (mAdaptor && (s==MODIFIED)) mAdaptor->bbSetModifiedStatus();
157 bbtkDebugDecTab("Process",2);
161 //==================================================================
164 //==================================================================
166 void Connection::ForwardUpdate()
168 bbtkDebugMessageInc("Process",2,
169 "Connection::ForwardUpdate() ["
170 <<GetFullName()<<"]"<<std::endl);
175 mTo->bbForwardUpdate(this);
177 bbtkDebugDecTab("Process",2);
179 //==================================================================
182 //==================================================================
183 /// Transfers the data from the source output to the target input
184 /// doing necessary conversions (adaptation or pointer cast)
185 void Connection::TransferData()
187 bbtkDebugMessageInc("Process",3,
188 "Connection::TransferData() ["
189 <<GetFullName()<<"]"<<std::endl);
192 // If an adaptor was created we need to adapt the data
195 mAdaptor->bbSetInput("In",mFrom->bbGetOutput(mOutput),false);
196 mAdaptor->bbExecute();
197 // LG : Connection Update does not set mTo as modified
198 mTo->bbSetInput(mInput, mAdaptor->bbGetOutput("Out"),false);
201 // If no adaptor but source type is an any and target is not an any
202 else if ( mFromAny && (! mToAny) )
204 bbtkDebugMessage("Data",3,
205 "Connection::TransferData() ["
206 <<GetFullName()<<"]"<<std::endl);
207 bbtkDebugMessage("Data",3,
208 " * Source type is an "
209 <<HumanTypeName<Data>()
210 <<" which contains a <"
211 <<HumanTypeName(mFrom->bbGetOutput(mOutput).type())
213 bbtkDebugMessage("Data",3,
214 " * Target type is <"
215 <<HumanTypeName(mTo->bbGetInputType(mInput))
218 // 1) Test strict type matching between any content and target
219 if (mFrom->bbGetOutput(mOutput)
220 .contains( mTo->bbGetInputType(mInput) ) )
222 bbtkDebugMessage("Data",3,
223 " -> Equal types : transfer ok"<<std::endl);
224 mTo->bbSetInput( mInput,
225 mFrom->bbGetOutput(mOutput),
230 // 2) Look for an adaptor
231 bbtk::BlackBox* adaptor = 0;
234 adaptor = mFactory->NewAdaptor(mFrom->bbGetOutput(mOutput).type(),
235 mTo->bbGetInputType(mInput),
243 bbtkDebugMessage("Data",3," -> Adaptor found : using it"
245 adaptor->bbSetInput("In",mFrom->bbGetOutput(mOutput),false);
246 adaptor->bbExecute();
247 // LG : Connection Update does not set mTo as modified
248 mTo->bbSetInput(mInput, adaptor->bbGetOutput("Out"),false);
251 // 3) If no adaptor found but the any content is a pointer
252 // and target type is also a pointer : we try run-time cast
253 else if ( (mFrom->bbGetOutput(mOutput).contains_pointer()) &&
254 (mTo->bbGetDescriptor()->GetInputDescriptor(mInput)
257 bbtkDebugMessage("Data",3,
258 " -> No adaptor found but source and target types are both pointers : trying up or down cast"<<std::endl);
261 mFrom->bbGetOutput(mOutput)
262 .get_pointer_to(mTo->bbGetInput(mInput).pointed_type());
265 bbtkError("Connection '"
268 <<HumanTypeName(mFrom->bbGetOutput(mOutput).type())
270 <<HumanTypeName(mTo->bbGetInputType(mInput))
271 <<"> : no adaptor available and run-time up and down cast failed");
273 mTo->bbBruteForceSetInputPointer(mInput, nptr, false);
275 // 4) Nothing worked : error
278 bbtkError("Connection '"<<GetFullName()<<"' "
279 <<"no adaptor found to convert <"
280 <<HumanTypeName(mFrom->bbGetOutput(mOutput).type())
282 <<HumanTypeName(mTo->bbGetInputType(mInput))<<">");
286 // EO : mFromAny && ! mToAny
287 // Default case : types are the same; we use simple get-set
290 // LG : Connection Update does not set mTo as modified
291 mTo->bbSetInput(mInput, mFrom->bbGetOutput(mOutput),false);
294 bbtkDebugDecTab("Process",3);
296 //==================================================================
298 //==================================================================
300 void Connection::SetModifiedStatus()
302 bbtkDebugMessageInc("Process",5,
303 "Connection::SetModifiedStatus() ["
304 <<GetFullName()<<"]"<<std::endl);
306 if (mAdaptor) mAdaptor->bbSetModifiedStatus();
308 mTo->bbSetModifiedStatus( mTo->bbGetInputConnectorMap().find(mInput)->second );
310 bbtkDebugDecTab("Process",5);
312 //==================================================================
315 //==================================================================
316 std::string Connection::GetFullName() const {
318 return mFrom->bbGetName()+"."+mOutput+"--"
319 +mTo->bbGetName()+"."+mInput;
320 return "***Invalid Connection***";
322 //==================================================================