00001 #ifndef ROSRTT_CONN_FACTORY_HPP 00002 #define ROSRTT_CONN_FACTORY_HPP 00003 00004 #include "channel_element.hpp" 00005 #include "conn_input_endpoint.hpp" 00006 #include "conn_output_endpoint.hpp" 00007 #include "data_lockfree.hpp" 00008 00009 namespace hpcl_rtt 00010 { 00011 00018 class ConnFactory 00019 { 00020 public: 00021 ConnFactory() {} 00022 ~ConnFactory() {} 00023 00024 template<typename T> 00025 static ChannelElementBase* buildDataStorage(const T& initial_value = T()) 00026 { 00027 typename DataObjectLockFree<T>::shared_ptr data_object; 00028 data_object.reset( new DataObjectLockFree<T>(initial_value) ); 00029 ChannelDataElement<T>* result = new ChannelDataElement<T>(data_object); 00030 return result; 00031 } 00032 00033 template<typename T> 00034 static ChannelElementBase::shared_ptr buildChannelInput(ConnectionBasePtr publication, ChannelElementBase::shared_ptr output_channel) 00035 { 00036 ChannelElementBase::shared_ptr endpoint = new ConnInputEndpoint<T>(publication); 00037 if (output_channel) 00038 endpoint->setOutput(output_channel); 00039 return endpoint; 00040 } 00041 00042 template<typename T> 00043 static ChannelElementBase::shared_ptr buildChannelOutput(ConnectionBasePtr subscription) 00044 { 00045 ChannelElementBase::shared_ptr endpoint = new ConnOutputEndpoint<T>(subscription); 00046 return endpoint; 00047 } 00048 00049 template<typename T> 00050 static ChannelElementBase::shared_ptr buildBufferedChannelOutput(ConnectionBasePtr subscription, T const& initial_value = T() ) 00051 { 00052 ChannelElementBase::shared_ptr endpoint = new ConnOutputEndpoint<T>(subscription); 00053 ChannelElementBase::shared_ptr data_object = buildDataStorage<T>(initial_value); 00054 data_object->setOutput(endpoint); 00055 return data_object; 00056 } 00057 00058 template<typename T> 00059 static bool createConnection(ConnectionBasePtr publication, ConnectionBasePtr subscription) 00060 { 00061 // This is the input channel element of the output half 00062 ChannelElementBase::shared_ptr output_half = 0; 00063 // local ports, create buffer here. 00064 output_half = buildBufferedChannelOutput<T>(subscription); 00065 00066 if (!output_half) 00067 return false; 00068 00069 // Since output is local, buildChannelInput is local as well. 00070 // This this the input channel element of the whole connection 00071 ChannelElementBase::shared_ptr channel_input = 00072 buildChannelInput<T>(publication, output_half); 00073 00074 return createAndCheckConnection(publication, subscription, channel_input); 00075 } 00076 00077 00078 protected: 00079 //template<typename T> 00080 static bool createAndCheckConnection(ConnectionBasePtr publication, ConnectionBasePtr subscription, ChannelElementBase::shared_ptr channel_input) 00081 { 00082 // Register the channel's input to the output port. 00083 if ( publication->addConnection(channel_input) ) 00084 { 00085 // notify input that the connection is now complete. 00086 00087 if ( channel_input->getOutputEndPoint()->inputReady() == false ) 00088 { 00089 return false; 00090 } 00091 return true; 00092 } 00093 // setup failed. 00094 channel_input->disconnect(true); 00095 return false; 00096 } 00097 }; 00098 00099 } 00100 #endif 00101