1 /*=========================================================================
4 Module: $RCSfile: bbtkConnection.cxx,v $
6 Date: $Date: 2008/04/08 06:59:30 $
7 Version: $Revision: 1.5 $
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->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()
132 //==================================================================
134 Connection::~Connection()
136 bbtkDebugMessageInc("Kernel",7,
137 "Connection::~Connection() ["
138 <<GetFullName()<<"]"<<std::endl);
140 if (mFrom) mFrom->bbDisconnectOutput(mOutput,this);
141 if (mTo) mTo->bbDisconnectInput(mInput,this);
142 if (mAdaptor) mAdaptor->bbDelete();
144 bbtkDebugDecTab("Kernel",7);
146 //==================================================================
148 //==================================================================
150 IOStatus Connection::BackwardUpdate()
152 bbtkDebugMessageInc("Process",2,
153 "Connection::BackwardUpdate() ["
154 <<GetFullName()<<"]"<<std::endl);
156 IOStatus s = UPTODATE;
157 s = mFrom->bbBackwardUpdate(this);
161 if (mAdaptor && (s==MODIFIED)) mAdaptor->bbSetModifiedStatus();
163 bbtkDebugDecTab("Process",2);
167 //==================================================================
170 //==================================================================
172 void Connection::ForwardUpdate()
174 bbtkDebugMessageInc("Process",2,
175 "Connection::ForwardUpdate() ["
176 <<GetFullName()<<"]"<<std::endl);
181 mTo->bbForwardUpdate(this);
183 bbtkDebugDecTab("Process",2);
185 //==================================================================
188 //==================================================================
189 /// Transfers the data from the source output to the target input
190 /// doing necessary conversions (adaptation or pointer cast)
191 void Connection::TransferData()
193 bbtkDebugMessageInc("Process",3,
194 "Connection::TransferData() ["
195 <<GetFullName()<<"]"<<std::endl);
198 // If an adaptor was created we need to adapt the data
201 mAdaptor->bbSetInput("In",mFrom->bbGetOutput(mOutput),false);
202 mAdaptor->bbExecute();
203 // LG : Connection Update does not set mTo as modified
204 mTo->bbSetInput(mInput, mAdaptor->bbGetOutput("Out"),false);
207 // If no adaptor but source type is an any and target is not an any
208 else if ( mFromAny && (! mToAny) )
210 bbtkDebugMessage("Data",3,
211 "Connection::TransferData() ["
212 <<GetFullName()<<"]"<<std::endl);
213 bbtkDebugMessage("Data",3,
214 " * Source type is an "
215 <<HumanTypeName<Data>()
216 <<" which contains a <"
217 <<HumanTypeName(mFrom->bbGetOutput(mOutput).type())
219 bbtkDebugMessage("Data",3,
220 " * Target type is <"
221 <<HumanTypeName(mTo->bbGetInputType(mInput))
224 // 1) Test strict type matching between any content and target
225 if (mFrom->bbGetOutput(mOutput)
226 .contains( mTo->bbGetInputType(mInput) ) )
228 bbtkDebugMessage("Data",3,
229 " -> Equal types : transfer ok"<<std::endl);
230 mTo->bbSetInput( mInput,
231 mFrom->bbGetOutput(mOutput),
236 // 2) Look for an adaptor
237 bbtk::BlackBox* adaptor = 0;
240 adaptor = mFactory->NewAdaptor(mFrom->bbGetOutput(mOutput).type(),
241 mTo->bbGetInputType(mInput),
249 bbtkDebugMessage("Data",3," -> Adaptor found : using it"
251 adaptor->bbSetInput("In",mFrom->bbGetOutput(mOutput),false);
252 adaptor->bbExecute();
253 // LG : Connection Update does not set mTo as modified
254 mTo->bbSetInput(mInput, adaptor->bbGetOutput("Out"),false);
257 // 3) If no adaptor found but the any content is a pointer
258 // and target type is also a pointer : we try run-time cast
259 else if ( (mFrom->bbGetOutput(mOutput).contains_pointer()) &&
260 (mTo->bbGetDescriptor()->GetInputDescriptor(mInput)
263 bbtkDebugMessage("Data",3,
264 " -> No adaptor found but source and target types are both pointers : trying up or down cast"<<std::endl);
267 mFrom->bbGetOutput(mOutput)
268 .get_pointer_to(mTo->bbGetInput(mInput).pointed_type());
271 bbtkError("Connection '"
274 <<HumanTypeName(mFrom->bbGetOutput(mOutput).type())
276 <<HumanTypeName(mTo->bbGetInputType(mInput))
277 <<"> : no adaptor available and run-time up and down cast failed");
279 mTo->bbBruteForceSetInputPointer(mInput, nptr, false);
281 // 4) Nothing worked : error
284 bbtkError("Connection '"<<GetFullName()<<"' "
285 <<"no adaptor found to convert <"
286 <<HumanTypeName(mFrom->bbGetOutput(mOutput).type())
288 <<HumanTypeName(mTo->bbGetInputType(mInput))<<">");
292 // EO : mFromAny && ! mToAny
293 // Default case : types are the same; we use simple get-set
296 // LG : Connection Update does not set mTo as modified
297 mTo->bbSetInput(mInput, mFrom->bbGetOutput(mOutput),false);
300 bbtkDebugDecTab("Process",3);
302 //==================================================================
304 //==================================================================
306 void Connection::SetModifiedStatus()
308 bbtkDebugMessageInc("Process",5,
309 "Connection::SetModifiedStatus() ["
310 <<GetFullName()<<"]"<<std::endl);
312 if (mAdaptor) mAdaptor->bbSetModifiedStatus();
314 mTo->bbSetModifiedStatus( mTo->bbGetInputConnectorMap().find(mInput)->second );
316 bbtkDebugDecTab("Process",5);
318 //==================================================================
321 //==================================================================
322 std::string Connection::GetFullName() const {
324 return mFrom->bbGetName()+"."+mOutput+"--"
325 +mTo->bbGetName()+"."+mInput;
326 return "***Invalid Connection***";
328 //==================================================================