00001
00020 #ifndef RTC_CORBAPORT_H
00021 #define RTC_CORBAPORT_H
00022
00023 #include <rtm/PortBase.h>
00024 #include <rtm/CorbaConsumer.h>
00025 #include <rtm/NVUtil.h>
00026 #include <list>
00027
00042 namespace RTC
00043 {
00623 class CorbaPort
00624 : public PortBase
00625 {
00626 public:
00641 CorbaPort(const char* name);
00642
00654 virtual ~CorbaPort(void);
00655
00670 void init(coil::Properties& prop);
00671
00706 bool registerProvider(const char* instance_name, const char* type_name,
00707 PortableServer::RefCountServantBase& provider);
00708
00750 bool registerConsumer(const char* instance_name, const char* type_name,
00751 CorbaConsumerBase& consumer);
00752
00753 protected:
00835 virtual ReturnCode_t
00836 publishInterfaces(ConnectorProfile& connector_profile);
00837
00970 virtual ReturnCode_t
00971 subscribeInterfaces(const ConnectorProfile& connector_profile);
00972
00994 virtual void
00995 unsubscribeInterfaces(const ConnectorProfile& connector_profile);
00996
00997
00998
00999
01016 virtual void activateInterfaces();
01017
01034 virtual void deactivateInterfaces();
01035
01036 protected:
01044 coil::Properties m_properties;
01045
01046 private:
01047 class CorbaConsumerHolder;
01048 virtual bool findProvider(const NVList& nv, CorbaConsumerHolder& cons);
01049 virtual bool findProviderOld(const NVList&nv, CorbaConsumerHolder& cons);
01050
01051 private:
01067 class CorbaProviderHolder
01068 {
01069 public:
01070 CorbaProviderHolder(const char* type_name,
01071 const char* instance_name,
01072 PortableServer::RefCountServantBase* servant)
01073 : m_typeName(type_name),
01074 m_instanceName(instance_name),
01075 m_servant(servant),
01076 m_ior()
01077 {
01078 m_oid = Manager::instance().getPOA()->servant_to_id(m_servant);
01079 try
01080 {
01081 Manager::instance().
01082 getPOA()->activate_object_with_id(m_oid, m_servant);
01083 }
01084 catch(const ::PortableServer::POA::ServantAlreadyActive &)
01085 {
01086 ;
01087 }
01088 catch(const ::PortableServer::POA::ObjectAlreadyActive &)
01089 {
01090 ;
01091 }
01092 CORBA::Object_var obj;
01093 obj = Manager::instance().getPOA()->id_to_reference(m_oid);
01094 CORBA::ORB_ptr orb = Manager::instance().getORB();
01095 CORBA::String_var ior_var = orb->object_to_string(obj);
01096 m_ior = ior_var;
01097 deactivate();
01098 }
01099
01100 std::string instanceName() { return m_instanceName; }
01101 std::string typeName() { return m_typeName; }
01102 std::string ior() { return m_ior; }
01103 std::string descriptor() { return m_typeName + "." + m_instanceName; }
01104
01105 void activate()
01106 {
01107 try
01108 {
01109 Manager::instance().
01110 getPOA()->activate_object_with_id(m_oid, m_servant);
01111 }
01112 catch(const ::PortableServer::POA::ServantAlreadyActive &)
01113 {
01114 ;
01115 }
01116 catch(const ::PortableServer::POA::ObjectAlreadyActive &)
01117 {
01118 ;
01119 }
01120 }
01121 void deactivate()
01122 {
01123 try
01124 {
01125 Manager::instance().getPOA()->deactivate_object(m_oid);
01126 }
01127 catch(const ::PortableServer::POA::ObjectNotActive&)
01128 {
01129 ;
01130 }
01131 }
01132 private:
01133 std::string m_typeName;
01134 std::string m_instanceName;
01135 PortableServer::RefCountServantBase* m_servant;
01136 PortableServer::ObjectId_var m_oid;
01137 std::string m_ior;
01138 };
01139
01147 typedef std::vector<CorbaProviderHolder> CorbaProviderList;
01148 CorbaProviderList m_providers;
01149
01157 class CorbaConsumerHolder
01158 {
01159 public:
01160 CorbaConsumerHolder(const char* type_name,
01161 const char* instance_name,
01162 CorbaConsumerBase* consumer)
01163 : m_typeName(type_name),
01164 m_instanceName(instance_name),
01165 m_consumer(consumer)
01166 {
01167 }
01168 std::string instanceName() { return m_instanceName; }
01169 std::string typeName() { return m_typeName; }
01170 std::string descriptor() { return m_typeName + "." + m_instanceName; }
01171
01172 bool setObject(const char* ior)
01173 {
01174 CORBA::ORB_ptr orb = ::RTC::Manager::instance().getORB();
01175 CORBA::Object_var obj = orb->string_to_object(ior);
01176 if (CORBA::is_nil(obj))
01177 {
01178 return false;
01179 }
01180
01181 return m_consumer->setObject(obj.in());
01182 }
01183 void releaseObject()
01184 {
01185 m_consumer->releaseObject();
01186 }
01187
01188 private:
01189 std::string m_typeName;
01190 std::string m_instanceName;
01191 CorbaConsumerBase* m_consumer;
01192 };
01193 typedef std::vector<CorbaConsumerHolder> CorbaConsumerList;
01194 CorbaConsumerList m_consumers;
01195
01196
01204 struct unsubscribe
01205 {
01206 unsubscribe(CorbaConsumerList& consumers)
01207 : m_consumers(consumers)
01208 {
01209 }
01210
01211 void operator()(const SDOPackage::NameValue& nv)
01212 {
01213 for (CorbaConsumerList::iterator it(m_consumers.begin());
01214 it != m_consumers.end(); ++it)
01215 {
01216 std::string name(nv.name);
01217 if (it->descriptor() == (const char*)nv.name)
01218 {
01219 it->releaseObject();
01220 }
01221 }
01222 }
01223 CorbaConsumerList& m_consumers;
01224 };
01225 };
01226 };
01227 #endif // RTC_CORBAPORT_H