dispatcher.h
Go to the documentation of this file.
1 #ifndef H_CAN_DISPATCHER
2 #define H_CAN_DISPATCHER
3 
4 #include <functional>
5 #include <memory>
6 #include <list>
7 #include <unordered_map>
8 
10 #include <boost/thread/mutex.hpp>
11 
12 namespace can{
13 
14 template< typename Listener > class SimpleDispatcher{
15 public:
16  using Callable = typename Listener::Callable;
17  using Type = typename Listener::Type;
19 protected:
20  class DispatcherBase;
21  using DispatcherBaseSharedPtr = std::shared_ptr<DispatcherBase>;
23  DispatcherBase(const DispatcherBase&) = delete; // prevent copies
24  DispatcherBase& operator=(const DispatcherBase&) = delete;
25 
26  class GuardedListener: public Listener{
27  std::weak_ptr<DispatcherBase> guard_;
28  public:
29  GuardedListener(DispatcherBaseSharedPtr g, const Callable &callable): Listener(callable), guard_(g){}
30  virtual ~GuardedListener() {
31  DispatcherBaseSharedPtr d = guard_.lock();
32  if(d){
33  d->remove(this);
34  }
35  }
36  };
37 
38  boost::mutex &mutex_;
39  std::list<const Listener* > listeners_;
40  public:
41  DispatcherBase(boost::mutex &mutex) : mutex_(mutex) {}
42  void dispatch_nolock(const Type &obj) const{
43  for(typename std::list<const Listener* >::const_iterator it=listeners_.begin(); it != listeners_.end(); ++it){
44  (**it)(obj);
45  }
46  }
47  void remove(Listener *d){
48  boost::mutex::scoped_lock lock(mutex_);
49  listeners_.remove(d);
50  }
51  size_t numListeners(){
52  boost::mutex::scoped_lock lock(mutex_);
53  return listeners_.size();
54  }
55 
57  ListenerConstSharedPtr l(new GuardedListener(dispatcher,callable));
58  dispatcher->listeners_.push_back(l.get());
59  return l;
60  }
61  };
62  boost::mutex mutex_;
64 public:
65  SimpleDispatcher() : dispatcher_(new DispatcherBase(mutex_)) {}
67  boost::mutex::scoped_lock lock(mutex_);
68  return DispatcherBase::createListener(dispatcher_, callable);
69  }
70  void dispatch(const Type &obj){
71  boost::mutex::scoped_lock lock(mutex_);
72  dispatcher_->dispatch_nolock(obj);
73  }
74  size_t numListeners(){
75  return dispatcher_->numListeners();
76  }
77  operator Callable() { return Callable(this,&SimpleDispatcher::dispatch); }
78 };
79 
80 template<typename K, typename Listener, typename Hash = std::hash<K> > class FilteredDispatcher: public SimpleDispatcher<Listener>{
82  std::unordered_map<K, typename BaseClass::DispatcherBaseSharedPtr, Hash> filtered_;
83 public:
84  using BaseClass::createListener;
85  typename BaseClass::ListenerConstSharedPtr createListener(const K &key, const typename BaseClass::Callable &callable){
86  boost::mutex::scoped_lock lock(BaseClass::mutex_);
87  typename BaseClass::DispatcherBaseSharedPtr &ptr = filtered_[key];
88  if(!ptr) ptr.reset(new typename BaseClass::DispatcherBase(BaseClass::mutex_));
89  return BaseClass::DispatcherBase::createListener(ptr, callable);
90  }
91 
92  template <typename T>
93  [[deprecated("provide key explicitly")]]
94  typename BaseClass::ListenerConstSharedPtr createListener(const T &key, const typename BaseClass::Callable &callable){
95  return createListener(static_cast<K>(key), callable);
96  }
97 
98  void dispatch(const K &key, const typename BaseClass::Type &obj){
99  boost::mutex::scoped_lock lock(BaseClass::mutex_);
100  typename BaseClass::DispatcherBaseSharedPtr &ptr = filtered_[key];
101  if(ptr) ptr->dispatch_nolock(obj);
102  BaseClass::dispatcher_->dispatch_nolock(obj);
103  }
104 
105  [[deprecated("provide key explicitly")]]
106  void dispatch(const typename BaseClass::Type &obj){
107  return dispatch(static_cast<K>(obj), obj);
108  }
109 
110  operator typename BaseClass::Callable() { return typename BaseClass::Callable(this,&FilteredDispatcher::dispatch); }
111 };
112 
113 } // namespace can
114 #endif
std::shared_ptr< const Listener > ListenerConstSharedPtr
Definition: interface.h:105
std::shared_ptr< DispatcherBase > DispatcherBaseSharedPtr
Definition: dispatcher.h:21
std::unordered_map< K, typename BaseClass::DispatcherBaseSharedPtr, Hash > filtered_
Definition: dispatcher.h:82
DispatcherBase(const DispatcherBase &)=delete
void dispatch(const typename BaseClass::Type &obj)
Definition: dispatcher.h:106
Definition: asio_base.h:11
void dispatch(const K &key, const typename BaseClass::Type &obj)
Definition: dispatcher.h:98
typename CommInterface::FrameListener ::ListenerConstSharedPtr ListenerConstSharedPtr
Definition: dispatcher.h:18
static ListenerConstSharedPtr createListener(DispatcherBaseSharedPtr dispatcher, const Callable &callable)
Definition: dispatcher.h:56
DispatcherBase(boost::mutex &mutex)
Definition: dispatcher.h:41
BaseClass::ListenerConstSharedPtr createListener(const T &key, const typename BaseClass::Callable &callable)
Definition: dispatcher.h:94
boost::mutex mutex_
Definition: dispatcher.h:62
DispatcherBase & operator=(const DispatcherBase &)=delete
typename CommInterface::FrameListener ::Type Type
Definition: dispatcher.h:17
void dispatch(const Type &obj)
Definition: dispatcher.h:70
DispatcherBaseSharedPtr dispatcher_
Definition: dispatcher.h:63
typename CommInterface::FrameListener ::Callable Callable
Definition: dispatcher.h:16
void dispatch_nolock(const Type &obj) const
Definition: dispatcher.h:42
BaseClass::ListenerConstSharedPtr createListener(const K &key, const typename BaseClass::Callable &callable)
Definition: dispatcher.h:85
ListenerConstSharedPtr createListener(const Callable &callable)
Definition: dispatcher.h:66
GuardedListener(DispatcherBaseSharedPtr g, const Callable &callable)
Definition: dispatcher.h:29
std::list< const Listener *> listeners_
Definition: dispatcher.h:39


socketcan_interface
Author(s): Mathias Lüdtke
autogenerated on Mon Feb 28 2022 23:28:00