Mistake on this page?
Report an issue in GitHub or email us
ChainableEventHandler.h
1 /* mbed Microcontroller Library
2  * Copyright (c) 2020 ARM Limited
3  * SPDX-License-Identifier: Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef MBED_CHAINABLEEVENTHANDLER_H_
19 #define MBED_CHAINABLEEVENTHANDLER_H_
20 
21 #include <new>
22 
23 /**
24  * Base class for chainable EventHandlers. Acts as a collection
25  * of discrete EventHandlers that can be linked together and
26  * notified when relevant events happen
27  */
28 template<typename T>
30 {
31 
32 public:
33 
35 
37  // Clean up all nodes
38  auto it = head;
39  while(it) {
40  node_t* temp = it;
41  it = it->next;
42  delete temp;
43  }
44  }
45 
46  /**
47  * Add an EventHandler to be notified of events sent to
48  * this ChainableEventHandler
49  *
50  * @param[in] event_handler Handler to add to chain
51  *
52  * @retval true if adding EventHandler was successful, false otherwise
53  */
54  bool addEventHandler(T* event_handler) {
55  auto eh = new (std::nothrow) node_t { event_handler, nullptr };
56  if(!eh) { return false; }
57  if(!head) {
58  head = eh;
59  } else {
60  auto *it = head;
61  while(it->next) {
62  it = it->next;
63  }
64  it->next = eh;
65  }
66  return true;
67  }
68 
69  /**
70  * Remove an EventHandler previously added with addEventHandler.
71  *
72  * @param[in] event_handler Pointer to event handler to remove
73  */
74  void removeEventHandler(T* event_handler) {
75  node_t* to_remove = head;
76  if(head->eh == event_handler) {
77  head = head->next;
78  } else {
79  auto* it = head;
80  while(it->next) {
81  if(it->next->eh == event_handler) {
82  to_remove = it->next;
83  break;
84  }
85  it = it->next;
86  }
87  if(it->next) {
88  it->next = to_remove->next;
89  } else {
90  to_remove = nullptr;
91  }
92  }
93 
94  delete to_remove;
95  }
96 
97  /**
98  * Test if an event handler is present in the chain or not.
99  *
100  * @param[in] event_handler Pointer to event handler to check
101  */
102  bool isEventHandlerPresent(T* event_handler) {
103  auto* it = head;
104  while (it) {
105  if (it == event_handler) {
106  return true;
107  }
108  it = it->next;
109  }
110  return false;
111  }
112 
113 protected:
114 
115  template<typename... FnArgs, typename... Args>
116  void execute_on_all(void (T::*fn)(FnArgs...), Args&&... args) {
117  auto it = head;
118  while(it) {
119  // we do not use std::forward, args have to remain lvalues
120  // as they are passed to multiple handlers
121  (it->eh->*fn)(args...);
122  it = it->next;
123  }
124  }
125 
126 private:
127 
128  struct node_t {
129  T* eh;
130  node_t* next = nullptr;
131  };
132 
133  node_t *head = nullptr;
134 
135 };
136 
137 #endif /* MBED_CHAINABLEEVENTHANDLER_H_ */
bool addEventHandler(T *event_handler)
Add an EventHandler to be notified of events sent to this ChainableEventHandler.
Base class for chainable EventHandlers.
void removeEventHandler(T *event_handler)
Remove an EventHandler previously added with addEventHandler.
bool isEventHandlerPresent(T *event_handler)
Test if an event handler is present in the chain or not.
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.