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* target) {
75  node_t* to_remove = head;
76  if(head->eh == target) {
77  head = head->next;
78  } else {
79  auto* it = head;
80  while(it->next) {
81  if(it->next->eh == target) {
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 protected:
98 
99  template<typename... FnArgs, typename... Args>
100  void execute_on_all(void (T::*fn)(FnArgs...), Args&&... args) {
101  auto it = head;
102  while(it) {
103  // we do not use std::forward, args have to remain lvalues
104  // as they are passed to multiple handlers
105  (it->eh->*fn)(args...);
106  it = it->next;
107  }
108  }
109 
110 private:
111 
112  struct node_t {
113  T* eh;
114  node_t* next = nullptr;
115  };
116 
117  node_t *head = nullptr;
118 
119 };
120 
121 #endif /* MBED_CHAINABLEEVENTHANDLER_H_ */
void removeEventHandler(T *target)
Remove an EventHandler previously added with addEventHandler.
bool addEventHandler(T *event_handler)
Add an EventHandler to be notified of events sent to this ChainableEventHandler.
Base class for chainable EventHandlers.
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.