EventLayer.h
Go to the documentation of this file.00001 /******************************************************************************* 00002 * 00003 * Copyright (c) 2008-2010 Michael Schulze <mschulze@ivs.cs.uni-magdeburg.de> 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 00010 * * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * 00013 * * Redistributions in binary form must reproduce the above copyright 00014 * notice, this list of conditions and the following disclaimer in 00015 * the documentation and/or other materials provided with the 00016 * distribution. 00017 * 00018 * * Neither the name of the copyright holders nor the names of 00019 * contributors may be used to endorse or promote products derived 00020 * from this software without specific prior written permission. 00021 * 00022 * 00023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 00024 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 00025 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00026 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00027 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00028 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00029 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00030 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00031 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00032 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00033 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00034 * 00035 * 00036 * $Id$ 00037 * 00038 ******************************************************************************/ 00039 00040 #ifndef __EventLayer_h__ 00041 #define __EventLayer_h__ 00042 00043 #include "debug.h" 00044 00045 #include "mw/common/Subject.h" 00046 #include "mw/common/Event.h" 00047 #include "mw/api/SubscriberEventChannel.h" 00048 #include "mw/api/EventChannel.h" 00049 #include "mw/nl/DistinctNL.h" 00050 #include "mw/el/EventLayerCallBack.h" 00051 00052 #include "object/Queue.h" 00053 00054 namespace famouso { 00055 namespace mw { 00056 namespace el { 00057 00070 template < class LL > 00071 class EventLayer : public LL { 00072 00073 protected: 00074 00075 typedef LL LowerLayer; 00076 00077 // potentiell gefaerdete Datenstrukturen 00078 // wegen Nebenlaeufigkeit 00079 00082 Queue Publisher; 00083 00086 Queue Subscriber; 00087 00088 public: 00089 00092 typedef typename LL::SNN SNN; 00093 00096 typedef EventLayer type; 00097 00100 void init() { 00101 // initialization code 00102 // e.g. set callbacks and initalize all lower layers too 00103 IncommingEventFromNL.bind<EventLayer<LL>, &EventLayer<LL>::fetch>(this); 00104 LL::init(); 00105 } 00106 00107 00113 void announce(famouso::mw::api::EventChannel<EventLayer> &ec) { 00114 TRACE_FUNCTION; 00115 LL::announce(ec.subject(), ec.snn()); 00116 Publisher.append(ec); 00117 } 00118 00125 void publish(const famouso::mw::api::EventChannel<EventLayer> &ec, const Event &e) { 00126 TRACE_FUNCTION; 00127 ::logging::log::emit< ::logging::Info>() 00128 << PROGMEMSTRING("Publish channel with addr=") 00129 << ::logging::log::hex 00130 << reinterpret_cast<const void*>(&ec) 00131 << PROGMEMSTRING(" with Subject -> [") 00132 << ec.subject().value() << ']' 00133 << ::logging::log::endl; 00134 // publish on all lower layers/subnets 00135 LL::publish(ec.snn(), e); 00136 00137 // publish locally on all subscribed event channels 00138 publish_local(e); 00139 } 00140 00146 void subscribe(famouso::mw::api::EventChannel<EventLayer> &ec) { 00147 TRACE_FUNCTION; 00148 ::logging::log::emit< ::logging::Info>() 00149 << PROGMEMSTRING("Subscribe channel with addr=") 00150 << ::logging::log::hex 00151 << reinterpret_cast<const void*>(&ec) 00152 << PROGMEMSTRING(" with Subject -> [") 00153 << ec.subject().value() << ']' 00154 << ::logging::log::endl; 00155 LL::subscribe(ec.subject(), ec.snn()); 00156 Subscriber.append(ec); 00157 } 00158 00164 void unsubscribe(famouso::mw::api::EventChannel<EventLayer> &ec) { 00165 TRACE_FUNCTION; 00166 Subscriber.remove(ec); 00167 } 00168 00174 void unannounce(famouso::mw::api::EventChannel<EventLayer> &ec) { 00175 TRACE_FUNCTION; 00176 Publisher.remove(ec); 00177 } 00178 00186 void publish_local(const Event &e) { 00187 TRACE_FUNCTION; 00188 // give start of the SubsriberList 00189 typedef famouso::mw::api::SubscriberEventChannel<EventLayer> ec_t; 00190 ec_t* sec = static_cast<ec_t*>(Subscriber.select()); 00191 // traverse the list and call the respective subscriber notify callback 00192 // in case subject matching 00193 while (sec) { 00194 if (sec->subject() == e.subject) 00195 sec->callback(e); 00196 sec = static_cast<ec_t*>(sec->select()); 00197 } 00198 } 00199 00211 void fetch(famouso::mw::nl::DistinctNL *bnl = 0) { 00212 TRACE_FUNCTION; 00213 00214 // give start of the SubsriberList 00215 typedef famouso::mw::api::SubscriberEventChannel<EventLayer> ec_t; 00216 ec_t* sec = static_cast<ec_t*>(Subscriber.select()); 00217 00218 // inform low layer about fetching starts 00219 LL::event_process_request(bnl); 00220 00221 // traverse the list and try to find the correct subject, 00222 // corresponding to the arised event. 00223 while (sec) { 00224 Event e(sec->subject()); 00225 00226 // try to fetch an event from a specific subnet and SNN 00227 int8_t result = LL::fetch(sec->snn(), e, bnl); 00228 00229 // incoming packet on this SNN? 00230 if (result >= 0) { 00231 // subject of last incoming packet matches that of the 00232 // current event channel 00233 00234 // if we got a new event, publish it locally to the 00235 // respective subscribers (if the packet was a fragment 00236 // the corresponding event may not be complete) 00237 if (result > 0) 00238 publish_local(e); 00239 00240 // packet/event processed (fetch called for each packet) 00241 break; 00242 } 00243 sec = static_cast<ec_t*>(sec->select()); 00244 } 00245 // inform lower layer that we are done 00246 LL::event_processed(); 00247 } 00248 }; 00249 00250 } // namespace el 00251 } // namespace mw 00252 } // namespace famouso 00253 00254 #endif /* __EventLayer_h__ */ 00255