From: Karel G. <kg...@us...> - 2002-03-23 20:17:16
|
Update of /cvsroot/micomt/mico/demo/ccm/events In directory usw-pr-cvs1:/tmp/cvs-serv31844/demo/ccm/events Added Files: Makefile README channel.idl channel_impl.cc client.cc consumer.idl consumer_impl.cc events message.idl message_impl.cc message_impl.h producer.idl producer_impl.cc Log Message: - merged with MICO 2.3.7 --- NEW FILE: Makefile --- all: all_target DIR_PREFIX=../ include ../../MakeVars INSTALL_DIR = ccm/events INSTALL_SRCS = README Makefile channel.idl channel_impl.cc \ client.cc consumer.idl consumer_impl.cc message.idl \ message_impl.cc message_impl.h producer.idl \ producer_impl.cc INSTALL_SCRIPTS = events all_target: .depend channel.$(SOEXT) consumer.$(SOEXT) producer.$(SOEXT) client channel.$(SOEXT): channel_impl.pic.o channel_ccm.pic.o channel.pic.o \ message_impl.pic.o message.pic.o $(RM) $@ $(LDSO) $(CXXFLAGS) $(LDFLAGS) -o channel \ channel_impl.pic.o channel_ccm.pic.o channel.pic.o \ message_impl.pic.o message.pic.o \ -lmicoccm$(VERSION) -lmico$(VERSION) $(LDLIBS) consumer.$(SOEXT): consumer_impl.pic.o consumer_ccm.pic.o consumer.pic.o \ message_impl.pic.o message.pic.o $(RM) $@ $(LDSO) $(CXXFLAGS) $(LDFLAGS) -o consumer \ consumer_impl.pic.o consumer_ccm.pic.o consumer.pic.o \ message_impl.pic.o message.pic.o \ -lmicoccm$(VERSION) -lmico$(VERSION) $(LDLIBS) producer.$(SOEXT): producer_impl.pic.o producer_ccm.pic.o producer.pic.o \ message_impl.pic.o message.pic.o $(RM) $@ $(LDSO) $(CXXFLAGS) $(LDFLAGS) -o producer \ producer_impl.pic.o producer_ccm.pic.o producer.pic.o \ message_impl.pic.o message.pic.o \ -lmicoccm$(VERSION) -lmico$(VERSION) $(LDLIBS) client: client.o channel.pic.o consumer.pic.o producer.pic.o \ message_impl.pic.o message.pic.o $(LD) $(CXXFLAGS) $(LDFLAGS) -o $@ client.o channel.pic.o \ consumer.pic.o producer.pic.o message_impl.pic.o \ message.pic.o -lmicoccm$(VERSION) -lmicocoss$(VERSION) \ -lmico$(VERSION) $(LDLIBS) clean: $(RM) channel.$(SOEXT) consumer.$(SOEXT) producer.$(SOEXT) client $(RM) channel_ccm.cc channel_ccm.h channel.cc channel.h $(RM) consumer_ccm.cc consumer_ccm.h consumer.cc consumer.h $(RM) producer_ccm.cc producer_ccm.h producer.cc producer.h $(RM) message.cc message.h $(RM) *.o *.$(SOEXT) *~ core *.ior channel_impl.pic.o: channel_impl.cc channel.h message_impl.h message.h consumer_impl.pic.o: consumer_impl.cc consumer.h message_impl.h message.h producer_impl.pic.o: producer_impl.cc producer.h message_impl.h message.h message_impl.pic.o: message_impl.cc message_impl.h message.h consumer_ccm.pic.o: consumer_ccm.cc producer_ccm.pic.o: producer_ccm.cc consumer.pic.o: consumer.cc producer.pic.o: producer.cc message.pic.o: message.cc client.o: client.cc channel_ccm.cc channel_ccm.h: channel.idl $(CCMGEN) $^ consumer_ccm.cc consumer_ccm.h: consumer.idl $(CCMGEN) $^ producer_ccm.cc producer_ccm.h: producer.idl $(CCMGEN) $^ channel.cc channel.h: channel.idl $(IDL) $^ consumer.cc consumer.h: consumer.idl $(IDL) $^ producer.cc producer.h: producer.idl $(IDL) $^ message.cc message.h: message.idl $(IDL) $^ --- NEW FILE: README --- This is an example that demonstrates usage of publishes and consumes event ports. The EventChannel component (channel.idl) implements a very simple event channel similar to the Event Service. The component simply sends out all events that are sent to the "incoming" port to all components that are subscribed to its "outgoing" port, and voilà, you have a oneway, n-to-n event channel. You could even create multiple event channels and connect them. Also included here are a Consumer component (consumer.idl) and a Producer component (producer.idl). The eventtype that is sent is defined in message.idl. The client starts one event channel, a couple of producers and consumers, and interconnects them. It then causes each producer to send some events. Since all three consumers are launched in the same console, you will see each event thrice. The Producer and the EventChannel consumers both implement the SessionComponent interface to gain access to their SessionContext, which they need to push events. Otherwise, the components don't have very much to do. Note the create_* entry points, which must register the Valuetype factory for the Message type. For this reason, entry points receive a pointer to the ORB, upon which they can call register_value_factory. --- NEW FILE: channel.idl --- #include <mico/CCM.idl> #include "message.idl" component EventChannel { consumes Message incoming; publishes Message outgoing; }; local interface MyEventChannel : Components::SessionComponent, CCM_EventChannel { }; home EventChannelHome manages EventChannel { }; --- NEW FILE: channel_impl.cc --- #include <iostream.h> #include "channel.h" #include "message_impl.h" class MyEventChannel_impl : virtual public MyEventChannel { private: CCM_EventChannel_Context_var _ctx; bool active; public: MyEventChannel_impl () { active = false; } void push_incoming (Message * msg) { if (active) { _ctx->push_outgoing (msg); } } void set_session_context (Components::SessionContext_ptr ctx) { _ctx = CCM_EventChannel_Context::_narrow (ctx); } void ccm_activate () { cout << "Event Channel is active." << endl; active = true; } void ccm_passivate () { cout << "Event Channel is passive." << endl; active = false; } void ccm_remove () { cout << "Event Channel is being removed." << endl; } }; class MyEventChannelHome_impl : virtual public CCM_EventChannelHome { public: Components::EnterpriseComponent_ptr create () { return new MyEventChannel_impl; } }; extern "C" { Components::HomeExecutorBase_ptr create_EventChannelHome (CORBA::ORB_ptr orb) { CORBA::ValueFactoryBase_var f = new MessageFactory; orb->register_value_factory ("IDL:Message:1.0", f); return new MyEventChannelHome_impl; } } --- NEW FILE: client.cc --- #include <mico/CosNaming.h> #include <mico/CCMContainer.h> #include "channel.h" #include "producer.h" #include "consumer.h" #include "message_impl.h" int main (int argc, char *argv[]) { CORBA::ORB_var orb = CORBA::ORB_init (argc, argv); CORBA::Object_var obj = orb->resolve_initial_references ("NameService"); CosNaming::NamingContextExt_var nc = CosNaming::NamingContextExt::_narrow (obj); MICO::CCM::register_all_factories (orb); CORBA::ValueFactoryBase_var f = new MessageFactory; orb->register_value_factory ("IDL:Message:1.0", f); EventChannel_var channel; Consumer_var consumers[3]; Producer_var producers[4]; MessageConsumer_var mc; CORBA::ULong i; /* * --- */ cout << "creating Event Channel ... " << flush; obj = nc->resolve_str ("EventChannelHome"); EventChannelHome_var channel_home = EventChannelHome::_narrow (obj); channel = channel_home->create (); cout << "done." << endl; /* * --- */ cout << "creating Consumers ... " << flush; obj = nc->resolve_str ("ConsumerHome"); ConsumerHome_var consumer_home = ConsumerHome::_narrow (obj); for (i=0; i<3; i++) { cout << i << " " << flush; consumers[i] = consumer_home->create (); } cout << "done." << endl; /* * --- */ cout << "subscribing Consumers ... " << flush; for (i=0; i<3; i++) { cout << i << " " << flush; mc = consumers[i]->get_consumer_msg (); channel->subscribe_outgoing (mc); } cout << "done." << endl; /* * --- */ cout << "creating Producers ... " << flush; obj = nc->resolve_str ("ProducerHome"); ProducerHome_var producer_home = ProducerHome::_narrow (obj); for (i=0; i<4; i++) { cout << i << " " << flush; producers[i] = producer_home->create (); } cout << "done." << endl; /* * --- */ cout << "configuring Message ... " << flush; Message_var msg = new Message_impl; for (i=0; i<4; i++) { cout << i << " " << flush; char temp[256]; sprintf (temp, "Producer %d", i); msg->text ((const char *) temp); producers[i]->myMessage (msg); } cout << "done." << endl; /* * --- */ cout << "connecting Producers ... " << flush; mc = channel->get_consumer_incoming (); for (i=0; i<4; i++) { cout << i << " " << flush; producers[i]->subscribe_msg (mc); } cout << "done." << endl; /* * --- */ cout << "Activating ... " << flush; channel->configuration_complete (); for (i=0; i<3; i++) { consumers[i]->configuration_complete (); } for (i=0; i<4; i++) { producers[i]->configuration_complete (); } cout << "done." << endl; /* * --- */ cout << "Send some Events ... " << flush; for (i=0; i<4; i++) { producers[i]->run (i+1); } cout << "done." << endl; return 0; } --- NEW FILE: consumer.idl --- #include "message.idl" component Consumer { consumes Message msg; }; home ConsumerHome manages Consumer {}; --- NEW FILE: consumer_impl.cc --- #include "consumer.h" #include "message_impl.h" class MyConsumer_impl : virtual public CCM_Consumer { public: void push_msg (Message * msg) { cout << "Consumer: got message `" << msg->text() << "'" << endl; } }; class MyConsumerHome_impl : virtual public CCM_ConsumerHome { public: Components::EnterpriseComponent_ptr create () { return new MyConsumer_impl; } }; extern "C" { Components::HomeExecutorBase_ptr create_ConsumerHome (CORBA::ORB_ptr orb) { CORBA::ValueFactoryBase_var f = new MessageFactory; orb->register_value_factory ("IDL:Message:1.0", f); return new MyConsumerHome_impl; } } --- NEW FILE: events --- #!/bin/sh MICORC=/dev/null export MICORC # run Naming Service echo "Starting Naming Service ..." rm -f nsd.ior nsd --ior nsd.ior & nsd_pid=$! trap "kill $nsd_pid > /dev/null 2> /dev/null" 0 # wait for Naming Service to start for i in 0 1 2 3 4 5 6 7 8 9 ; do if test -r nsd.ior ; then break ; else sleep 1 ; fi done # start Server Activator echo "Starting Server Activator ..." rm -f ccmd.ior mico-ccmd --ior ccmd.ior & server_pid=$! trap "kill $nsd_pid $server_pid > /dev/null 2> /dev/null" 0 # wait for Server Activator to start for i in 0 1 2 3 4 5 6 7 8 9 ; do if test -r ccmd.ior ; then break ; else sleep 1 ; fi done # start EventChannel echo "Loading Event Channel component ..." ccmload -ORBInitRef NameService=file://`pwd`/nsd.ior --sa file://`pwd`/ccmd.ior -v --ns EventChannelHome EventChannelHome ./channel.so echo "Loading Consumer component ..." ccmload -ORBInitRef NameService=file://`pwd`/nsd.ior --sa file://`pwd`/ccmd.ior -v --ns ConsumerHome ConsumerHome ./consumer.so echo "Loading Producer component ..." ccmload -ORBInitRef NameService=file://`pwd`/nsd.ior --sa file://`pwd`/ccmd.ior -v --ns ProducerHome ProducerHome ./producer.so # run Client echo "Running Client ..." ./client -ORBInitRef NameService=file://`pwd`/nsd.ior echo "Terminating ..." sleep 3 --- NEW FILE: message.idl --- #ifndef __MESSAGE__ #define __MESSAGE__ eventtype Message { public string text; }; #endif --- NEW FILE: message_impl.cc --- #include "message_impl.h" Message_impl::Message_impl () { text ((const char *) ""); } CORBA::ValueBase * MessageFactory::create_for_unmarshal () { return new Message_impl; } --- NEW FILE: message_impl.h --- #ifndef __EVENT_IMPL_H__ #define __EVENT_IMPL_H__ #include "message.h" class Message_impl : virtual public OBV_Message, virtual public CORBA::DefaultValueRefCountBase { public: Message_impl (); }; class MessageFactory : public CORBA::ValueFactoryBase { public: CORBA::ValueBase * create_for_unmarshal (); }; #endif --- NEW FILE: producer.idl --- #include <mico/CCM.idl> #include "message.idl" interface ProducerAdmin { attribute Message myMessage; void run (in unsigned long count); }; component Producer supports ProducerAdmin { publishes Message msg; }; home ProducerHome manages Producer {}; local interface MyProducer : CCM_Producer, Components::SessionComponent { }; --- NEW FILE: producer_impl.cc --- #include "producer.h" #include "message_impl.h" class MyProducer_impl : virtual public MyProducer { private: CCM_Producer_Context_var _ctx; Message_var _mymsg; bool active; public: MyProducer_impl () { _mymsg = new Message_impl; _mymsg->text ((const char*) "Hello World!"); active = false; } void myMessage (Message * newmsg) { CORBA::add_ref (newmsg); _mymsg = newmsg; } Message * myMessage () { CORBA::add_ref (_mymsg); return _mymsg; } void run (CORBA::ULong count) { if (active) { for (CORBA::ULong i=0; i<count; i++) { _ctx->push_msg (_mymsg); } } } void set_session_context (Components::SessionContext_ptr ctx) { _ctx = CCM_Producer_Context::_narrow (ctx); } void ccm_activate () { if (!active) { active = true; run (1); } } void ccm_passivate () { active = false; } void ccm_remove () { } }; class MyProducerHome_impl : virtual public CCM_ProducerHome { public: Components::EnterpriseComponent_ptr create () { return new MyProducer_impl; } }; extern "C" { Components::HomeExecutorBase_ptr create_ProducerHome (CORBA::ORB_ptr orb) { CORBA::ValueFactoryBase_var f = new MessageFactory; orb->register_value_factory ("IDL:Message:1.0", f); return new MyProducerHome_impl; } } |