• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef OHOS_DISTRIBUTED_HARDWARE_EVENT_BUS_H
17 #define OHOS_DISTRIBUTED_HARDWARE_EVENT_BUS_H
18 
19 #include <memory>
20 #include <set>
21 #include <unordered_map>
22 #include <mutex>
23 
24 #include "event_handler.h"
25 
26 #include "dh_log.h"
27 #include "anonymous_string.h"
28 #include "event.h"
29 #include "eventbus_handler.h"
30 #include "event_registration.h"
31 
32 #ifndef DH_LOG_TAG
33 #define DH_LOG_TAG "DHEventBus"
34 #endif
35 
36 namespace OHOS {
37 namespace DistributedHardware {
38 enum POSTMODE : uint32_t {
39     POST_ASYNC = 0,
40     POST_SYNC,
41 };
42 
43 class EventBus final {
44 public:
EventBus()45     EventBus()
46     {
47         ULOGI("ctor EventBus");
48         if (!eventbusHandler_) {
49             auto busRunner = OHOS::AppExecFwk::EventRunner::Create("DHEventbusHandler");
50             eventbusHandler_ = std::make_shared<OHOS::AppExecFwk::EventHandler>(busRunner);
51         }
52     }
~EventBus()53     ~EventBus()
54     {
55         ULOGI("dtor EventBus");
56     }
57 
58     template<class T>
AddHandler(const std::string & typeId,DistributedHardware::EventBusHandler<T> & handler)59     std::shared_ptr<EventRegistration> AddHandler(const std::string &typeId,
60         DistributedHardware::EventBusHandler<T> &handler)
61     {
62         std::lock_guard<std::mutex> lock(handlerMtx);
63         Registrations *registrations = handlers[typeId];
64 
65         if (registrations == nullptr) {
66             registrations = new EventRegistration::Registrations();
67             handlers[typeId] = registrations;
68         }
69 
70         for (auto &reg : *registrations) {
71             if (reg->GetHandler() == static_cast<void *>(&handler) && reg->GetSender() == nullptr) {
72                 return reg;
73             }
74         }
75 
76         std::shared_ptr<EventRegistration> registration =
77             std::make_shared<EventRegistration>(static_cast<void *>(&handler), nullptr);
78         registrations->insert(registration);
79 
80         return registration;
81     }
82 
83     template<class T>
AddHandler(const std::string & typeId,EventBusHandler<T> & handler,EventSender & sender)84     std::shared_ptr<EventRegistration> AddHandler(const std::string &typeId, EventBusHandler<T> &handler,
85         EventSender &sender)
86     {
87         std::lock_guard<std::mutex> lock(handlerMtx);
88         Registrations *registrations = handlers[typeId];
89 
90         if (registrations == nullptr) {
91             registrations = new EventRegistration::Registrations();
92             handlers[typeId] = registrations;
93         }
94 
95         for (auto &reg : *registrations) {
96             if (reg->GetHandler() == static_cast<void *>(&handler) && reg->GetSender() == &sender) {
97                 return reg;
98             }
99         }
100 
101         std::shared_ptr<EventRegistration> registration =
102             std::make_shared<EventRegistration>(static_cast<void *>(&handler), &sender);
103         registrations->insert(registration);
104 
105         return registration;
106     }
107 
108     template<class T>
RemoveHandler(const std::string & typeId,std::shared_ptr<EventRegistration> & EvenReg)109     bool RemoveHandler(const std::string &typeId, std::shared_ptr<EventRegistration> &EvenReg)
110     {
111         std::lock_guard<std::mutex> lock(handlerMtx);
112         Registrations *registrations = handlers[typeId];
113         if (registrations == nullptr) {
114             return false;
115         }
116 
117         bool ret = false;
118         auto regIter = registrations->find(EvenReg);
119         if (regIter != registrations->end()) {
120             registrations->erase(regIter);
121             ret = true;
122         }
123 
124         return ret;
125     }
126 
127     template<class T>
128     void PostEvent(T &e, POSTMODE mode = POSTMODE::POST_ASYNC)
129     {
130         if (mode == POSTMODE::POST_SYNC) {
131             PostEventInner(e);
132         } else {
133             auto eventFunc = [this, e]() mutable {
134                 PostEventInner(e);
135             };
136             if (!(eventbusHandler_ && eventbusHandler_->PostTask(eventFunc))) {
137                 ULOGE("Eventbus::PostEvent Async PostTask fail");
138             }
139         }
140     }
141 
142     template<class T>
PostEvent(T & e,int64_t delayTime)143     void PostEvent(T &e, int64_t delayTime)
144     {
145         auto eventFunc = [this, e]() mutable {
146             PostEventInner(e);
147         };
148         if (!(eventbusHandler_ && eventbusHandler_->PostTask(eventFunc, e->getType(), delayTime))) {
149             ULOGE("Eventbus::PostEvent Async PostTask fail");
150         }
151     }
152 
153     template<class T>
RemoveEvent(T & e)154     void RemoveEvent(T &e)
155     {
156         if (!(eventbusHandler_ && eventbusHandler_->RemoveTask(e->getType()))) {
157             ULOGE("Eventbus::RemoveEvent fail");
158         }
159     }
160 
161     void PostTask(const OHOS::AppExecFwk::InnerEvent::Callback& callback,
162         const std::string& name,
163         int64_t delayTimeInMs = 0)
164     {
165         ULOGI("Eventbus::PostTask Async PostTask, taskName:%{public}s.", GetAnonyString(name).c_str());
166         if (eventbusHandler_ != nullptr) {
167             eventbusHandler_->PostTask(callback, name, delayTimeInMs);
168         }
169     }
170 
RemoveTask(const std::string & name)171     void RemoveTask(const std::string& name)
172     {
173         ULOGI("Eventbus::RemoveTask, taskName:%{public}s.", GetAnonyString(name).c_str());
174         if (eventbusHandler_ != nullptr) {
175             eventbusHandler_->RemoveTask(name);
176         }
177     }
178 
179 private:
180     template<class T>
PostEventInner(T & e)181     void PostEventInner(T &e)
182     {
183         std::lock_guard<std::mutex> lock(handlerMtx);
184         Registrations *registrations = handlers[e.GetType()];
185         if (registrations == nullptr) {
186             return;
187         }
188 
189         for (auto &reg : *registrations) {
190             if ((reg->GetSender() == nullptr) || (reg->GetSender() == &e.GetSender())) {
191                 static_cast<EventBusHandler<Event> *>(const_cast<void *>(reg->GetHandler()))->Dispatch(e);
192             }
193         }
194     }
195 
196 private:
197     std::shared_ptr<OHOS::AppExecFwk::EventHandler> eventbusHandler_;
198 
199     using Registrations = std::set<std::shared_ptr<EventRegistration>>;
200     std::mutex handlerMtx;
201     using TypeMap = std::unordered_map<std::string, std::set<std::shared_ptr<EventRegistration>> *>;
202     TypeMap handlers;
203 };
204 }
205 }
206 #endif