00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "torc/generic/om/DumpRestoreConfig.hpp"
00017
00018 #ifndef HAVE_CONFIG_H
00019 #include "torc/generic/config.h"
00020 #endif
00021
00022
00023 #include <boost/bind.hpp>
00024 #include <boost/mem_fn.hpp>
00025 #ifdef GENOM_SERIALIZATION
00026 #include <boost/archive/binary_iarchive.hpp>
00027 #include <boost/archive/binary_oarchive.hpp>
00028 #include <boost/serialization/base_object.hpp>
00029 #include <boost/serialization/export.hpp>
00030 #endif //GENOM_SERIALIZATION
00031
00032 #include "torc/generic/om/ConnectionHandler.hpp"
00033 #include "torc/generic/om/Net.hpp"
00034 #include "torc/generic/om/Port.hpp"
00035 #include "torc/generic/om/PortBundleReference.hpp"
00036 #include "torc/generic/om/PortRefCreator.hpp"
00037
00038 #ifdef GENOM_SERIALIZATION
00039 BOOST_CLASS_EXPORT( torc::generic::PortBundleReference )
00040 #endif //GENOM_SERIALIZATION
00041
00042 #include <iostream>
00043 namespace torc {
00044
00045 namespace generic {
00046
00047 PortBundleReferenceSharedPtr
00048 PortBundleReference::Factory::newPortBundleReferencePtr( const InstanceSharedPtr &inInstancePtr,
00049 const PortSharedPtr &inPortPtr,
00050 const ObjectFactorySharedPtr &inFactory,
00051 const PortBundleReferenceSharedPtr &inParentCollection ) throw(Error) {
00052 try
00053 {
00054 PortBundleReferenceSharedPtr newPortBundleReference;
00055 PortRefCreator<PortBundleReferenceSharedPtr> creator( inFactory, inInstancePtr, inParentCollection );
00056 inPortPtr->getParent()->applyOnAllPorts(
00057 VisitorApplier< PortRefCreator<PortBundleReferenceSharedPtr> >( creator ) );
00058 newPortBundleReference = creator.getReturnValue();
00059 newPortBundleReference->bindToMasterPort( inPortPtr );
00060 return newPortBundleReference;
00061 }
00062 catch( Error &e )
00063 {
00064 e.setCurrentLocation(
00065 __FUNCTION__, __FILE__, __LINE__ );
00066 throw;
00067 }
00068
00069 }
00070
00071 void
00072 PortBundleReference::accept(
00073 BaseVisitor & inoutVisitor) throw(Error) {
00074 try
00075 {
00076 runVisitor( *this, inoutVisitor );
00077 }
00078 catch( Error &e )
00079 {
00080 e.setCurrentLocation(
00081 __FUNCTION__, __FILE__, __LINE__ );
00082 throw;
00083 }
00084 }
00085
00086 void
00087 PortBundleReference::setParent(
00088 const InstanceSharedPtr &inParent ) throw() {
00089 ParentedObject<Instance>::setParent( inParent );
00090 applyOnAllChildren(
00091 boost::bind( boost::mem_fn(
00092 &PortReference::setParent), _1, getParent() ));
00093 }
00094
00095 Connectable::Connection
00096 PortBundleReference::connect(
00097 const NetSharedPtr &inNet) throw(Error) {
00098 if( getSize() != getMaster()->getSize() )
00099 {
00100 Error e( eMessageIdErrorItemSizeMismatch,
00101 __FUNCTION__, __FILE__, __LINE__ );
00102 e.saveContextData("PortBundleReference Size", getSize() );
00103 e.saveContextData("Master Port Size", getMaster()->getSize() );
00104 throw e;
00105 }
00106 if( inNet->getSize() != getSize() )
00107 {
00108 Error e( eMessageIdErrorItemSizeMismatch,
00109 __FUNCTION__, __FILE__, __LINE__ );
00110 e.saveContextData("Net Size", inNet->getSize());
00111 e.saveContextData("PortBundleReference Size", getSize() );
00112 throw e;
00113 }
00114 Bundle<PortReference>::List children;
00115 BundleFlattener<PortReference, ScalarPortReference, VectorPortReference,
00116 VectorPortBitReference, PortBundleReference> flattener;
00117 accept( flattener );
00118 flattener.getChildren( children );
00119
00120 Bundle<Net>::List netChildren;
00121 inNet->getChildren( netChildren );
00122 Bundle<PortReference>::List::iterator childPortRef = children.begin();
00123 Bundle<PortReference>::List::iterator childEnd
00124 = children.end();
00125 Bundle<Net>::List::iterator net = netChildren.begin();
00126 for(; childPortRef != childEnd; ++childPortRef, ++net )
00127 {
00128 try
00129 {
00130 (*childPortRef)->connect( *net );
00131 }
00132 catch( Error &e )
00133 {
00134 e.setCurrentLocation(
00135 __FUNCTION__, __FILE__, __LINE__ );
00136 throw;
00137 }
00138 }
00139 Connectable::Connection newConnection;
00140 try
00141 {
00142 ConnectionHandler handler( inNet );
00143 handler.connectPortRefToNet( getSharedThis() );
00144 newConnection = Connectable::connect( inNet );
00145 }
00146 catch( Error &e )
00147 {
00148 e.setCurrentLocation(
00149 __FUNCTION__, __FILE__, __LINE__ );
00150 throw;
00151 }
00152 return newConnection;
00153 }
00154
00155 void
00156 PortBundleReference::disconnect(
00157 const Connection & inConnection) throw(Error) {
00158 NetSharedPtr connNet = *inConnection;
00159 if( !connNet )
00160 {
00161 Error e( eMessageIdErrorConnectionInvalid,
00162 __FUNCTION__, __FILE__, __LINE__ );
00163 e.saveContextData("Pointer to Net", connNet);
00164 throw e;
00165 }
00166 Bundle<PortReference>::List children;
00167 BundleFlattener<PortReference, ScalarPortReference, VectorPortReference,
00168 VectorPortBitReference, PortBundleReference> flattener;
00169 accept( flattener );
00170 flattener.getChildren( children );
00171
00172 Bundle<Net>::List netChildren;
00173 connNet->getChildren( netChildren );
00174 Bundle<PortReference>::List::iterator childPortRef
00175 = children.begin();
00176 Bundle<PortReference>::List::iterator childEnd
00177 = children.end();
00178 Bundle<Net>::List::iterator net = netChildren.begin();
00179
00180
00181
00182
00183
00184 for(; childPortRef != childEnd; ++childPortRef, ++net )
00185 {
00186 try
00187 {
00188 (*childPortRef)->disconnect( *net );
00189 }
00190 catch( Error &e )
00191 {
00192 e.setCurrentLocation(
00193 __FUNCTION__, __FILE__, __LINE__ );
00194 throw;
00195 }
00196 }
00197 try
00198 {
00199 ConnectionHandler handler( connNet );
00200 handler.disconnectPortRefFromNet( getSharedThis() );
00201 Connectable::disconnect( inConnection );
00202 }
00203 catch( Error &e )
00204 {
00205 e.setCurrentLocation(
00206 __FUNCTION__, __FILE__, __LINE__ );
00207 throw;
00208 }
00209 return;
00210 }
00211
00212
00213
00214
00215
00216
00217
00218 void
00219 PortBundleReference::bindToMasterPort(
00220 const PortSharedPtr &inMaster) throw(Error) {
00221 if( inMaster->getSize() != getSize() )
00222 {
00223 Error e( eMessageIdErrorItemSizeMismatch,
00224 __FUNCTION__, __FILE__, __LINE__ );
00225 e.saveContextData("Master Port Size", inMaster->getSize());
00226 e.saveContextData("Port bundle reference Size", getSize() );
00227 throw e;
00228 }
00229 PortReference::bindToMasterPort( inMaster );
00230 #if 0 //Bind during reference creation
00231 std::vector< PortReferenceSharedPtr > children;
00232 getChildren( children );
00233 std::vector< PortSharedPtr > childrenPort;
00234 inMaster->getChildren( childrenPort );
00235 std::vector< PortReferenceSharedPtr >::iterator pRef
00236 = children.begin();
00237 std::vector< PortReferenceSharedPtr >::iterator pRefEnd
00238 = children.end();
00239 std::vector< PortSharedPtr >::iterator pIt
00240 = childrenPort.begin();
00241 for( ; pRef != pRefEnd; ++pRef, ++pIt )
00242 {
00243 PortReferenceSharedPtr childRef;
00244 PortSharedPtr childPort = *pIt;
00245 try
00246 {
00247 childRef->bindToMasterPort( childPort );
00248 }
00249 catch( Error &e )
00250 {
00251 e.setCurrentLocation( __FUNCTION__, __FILE__, __LINE__ );
00252 throw;
00253 }
00254 }
00255 #endif
00256 }
00257
00258 PortBundleReference::PortBundleReference()
00259 :PortReference(),
00260 Bundle<PortReference>() {
00261 }
00262
00263 PortBundleReference::~PortBundleReference() throw() {
00264 }
00265
00266 #ifdef GENOM_SERIALIZATION
00267 template<class Archive> void
00268 PortBundleReference::serialize( Archive &ar, unsigned int ) {
00269 ar & boost::serialization::base_object< PortReference >( *this );
00270 ar & boost::serialization::base_object<
00271 Bundle<PortReference> >(*this);
00272 }
00273
00274
00275 template void
00276 PortBundleReference::serialize<boost::archive::binary_iarchive>(
00277 boost::archive::binary_iarchive & ar, const unsigned int);
00278
00279 template void
00280 PortBundleReference::serialize<boost::archive::binary_oarchive>(
00281 boost::archive::binary_oarchive & ar, const unsigned int);
00282
00283 #endif //GENOM_SERIALIZATION
00284
00285 }
00286
00287 }