1 /*
2 * Copyright (C) 2022 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 CALLBACK_MANAGER_H
17 #define CALLBACK_MANAGER_H
18
19 #include <mutex>
20
21 namespace OHOS {
22 namespace Location {
23 template <typename T>
24 class CallbackManager {
25 public:
26 CallbackManager() = default;
27 virtual ~CallbackManager() = default;
28 bool IsCallbackInMap(const napi_env& env, const napi_value& handler);
29 void AddCallback(const napi_env& env, const napi_ref& handlerRef, const sptr<T>& callback);
30 void DeleteCallback(const napi_env& env, const napi_value& handler);
31 sptr<T> GetCallbackPtr(const napi_env& env, const napi_value& handler);
32 void DeleteCallbackByEnv(const napi_env& env);
33 std::map<napi_env, std::map<napi_ref, sptr<T>>> GetCallbackMap();
34 private:
35 std::map<napi_env, std::map<napi_ref, sptr<T>>> callbackMap_;
36 std::mutex mMutex;
37 };
38
39 template <typename T>
GetCallbackMap()40 std::map<napi_env, std::map<napi_ref, sptr<T>>> CallbackManager<T>::GetCallbackMap()
41 {
42 std::unique_lock<std::mutex> lock(mMutex);
43 return callbackMap_;
44 }
45
46 template <typename T>
DeleteCallbackByEnv(const napi_env & env)47 void CallbackManager<T>::DeleteCallbackByEnv(const napi_env& env)
48 {
49 std::unique_lock<std::mutex> lock(mMutex);
50 auto iter = callbackMap_.find(env);
51 if (iter == callbackMap_.end()) {
52 return;
53 }
54 iter->second.clear();
55 callbackMap_.erase(iter);
56 }
57
58 template <typename T>
IsCallbackInMap(const napi_env & env,const napi_value & handler)59 bool CallbackManager<T>::IsCallbackInMap(const napi_env& env, const napi_value& handler)
60 {
61 std::unique_lock<std::mutex> lock(mMutex);
62 auto iter = callbackMap_.find(env);
63 if (iter == callbackMap_.end()) {
64 return false;
65 }
66 for (auto innerIter = iter->second.begin(); innerIter != iter->second.end(); innerIter++) {
67 auto ref = innerIter->first;
68 if (IsCallbackEquals(env, handler, ref)) {
69 return true;
70 }
71 }
72 return false;
73 }
74
75 template <typename T>
AddCallback(const napi_env & env,const napi_ref & handlerRef,const sptr<T> & callback)76 void CallbackManager<T>::AddCallback(const napi_env& env, const napi_ref& handlerRef, const sptr<T>& callback)
77 {
78 std::unique_lock<std::mutex> lock(mMutex);
79 auto iter = callbackMap_.find(env);
80 if (iter == callbackMap_.end()) {
81 std::map<napi_ref, sptr<T>> innerMap;
82 innerMap.insert(std::make_pair(handlerRef, callback));
83 callbackMap_.insert(std::make_pair(env, innerMap));
84 return;
85 }
86 iter->second.insert(std::make_pair(handlerRef, callback));
87 }
88
89 template <typename T>
DeleteCallback(const napi_env & env,const napi_value & handler)90 void CallbackManager<T>::DeleteCallback(const napi_env& env, const napi_value& handler)
91 {
92 std::unique_lock<std::mutex> lock(mMutex);
93 auto iter = callbackMap_.find(env);
94 if (iter == callbackMap_.end()) {
95 return;
96 }
97 for (auto innerIter = iter->second.begin(); innerIter != iter->second.end(); innerIter++) {
98 auto ref = innerIter->first;
99 if (IsCallbackEquals(env, handler, ref)) {
100 innerIter = iter->second.erase(innerIter);
101 if (iter->second.size() == 0) {
102 callbackMap_.erase(iter);
103 }
104 break;
105 }
106 }
107 }
108
109 template <typename T>
GetCallbackPtr(const napi_env & env,const napi_value & handler)110 sptr<T> CallbackManager<T>::GetCallbackPtr(const napi_env& env, const napi_value& handler)
111 {
112 std::unique_lock<std::mutex> lock(mMutex);
113 auto iter = callbackMap_.find(env);
114 if (iter == callbackMap_.end()) {
115 return nullptr;
116 }
117 for (auto innerIter = iter->second.begin(); innerIter != iter->second.end(); innerIter++) {
118 auto ref = innerIter->first;
119 if (IsCallbackEquals(env, handler, ref)) {
120 return innerIter->second;
121 }
122 }
123 return nullptr;
124 }
125 } // namespace Location
126 } // namespace OHOS
127 #endif // CALLBACK_MANAGER_H
128