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 JSWATCHER_H
17 #define JSWATCHER_H
18 
19 #include "distributed_objectstore.h"
20 #include "flat_object_store.h"
21 #include "napi/native_api.h"
22 #include "napi/native_node_api.h"
23 #include "uv_queue.h"
24 
25 namespace OHOS::ObjectStore {
26 class JSWatcher;
27 struct EventHandler {
28     napi_ref callbackRef = nullptr;
29     EventHandler *next = nullptr;
30 };
31 
32 class EventListener {
33 public:
EventListener()34     EventListener() : handlers_(nullptr)
35     {
36     }
37 
~EventListener()38     virtual ~EventListener()
39     {
40     }
41 
IsEmpty()42     bool IsEmpty()
43     {
44         return handlers_ == nullptr;
45     }
46 
47     virtual bool Add(napi_env env, napi_value handler);
48 
49     virtual bool Del(napi_env env, napi_value handler);
50 
51     virtual void Clear(napi_env env);
52 
53     EventHandler *Find(napi_env env, napi_value handler);
54     EventHandler *handlers_;
55 };
56 
57 class ChangeEventListener : public EventListener {
58 public:
59     ChangeEventListener(
60         std::weak_ptr<JSWatcher> watcher, DistributedObjectStore *objectStore, DistributedObject *object);
61 
62     bool Add(napi_env env, napi_value handler) override;
63 
64     bool Del(napi_env env, napi_value handler) override;
65 
66     void Clear(napi_env env) override;
67 private:
68     bool isWatched_ = false;
69     DistributedObjectStore *objectStore_;
70     DistributedObject *object_;
71     std::weak_ptr<JSWatcher> watcher_;
72 };
73 
74 class StatusEventListener : public EventListener {
75 public:
76     StatusEventListener(std::weak_ptr<JSWatcher> watcher, const std::string &sessionId);
77     bool Add(napi_env env, napi_value handler) override;
78 
79     bool Del(napi_env env, napi_value handler) override;
80 
81     void Clear(napi_env env) override;
82 private:
83     std::weak_ptr<JSWatcher> watcher_;
84     std::string sessionId_;
85 };
86 
87 class JSWatcher : public UvQueue {
88 public:
89     JSWatcher(const napi_env env, DistributedObjectStore *objectStore, DistributedObject *object);
90 
91     ~JSWatcher();
92 
93     bool On(const char *type, napi_value handler);
94 
95     void Off(const char *type, napi_value handler = nullptr);
96 
97     void Emit(const char *type, const std::string &sessionId, const std::vector<std::string> &changeData);
98 
99     void Emit(const char *type, const std::string &sessionId, const std::string &networkId, const std::string &status);
100 
101     bool IsEmpty();
102 
103     void SetListener(ChangeEventListener *changeEventListener, StatusEventListener *statusEventListener);
104 private:
105     struct ChangeArgs {
106         ChangeArgs(const napi_ref callback, const std::string &sessionId, const std::vector<std::string> &changeData);
107         napi_ref callback_;
108         const std::string sessionId_;
109         const std::vector<std::string> changeData_;
110     };
111     struct StatusArgs {
112         StatusArgs(const napi_ref callback, const std::string &sessionId, const std::string &networkId,
113             const std::string &status);
114         napi_ref callback_;
115         const std::string sessionId_;
116         const std::string networkId_;
117         const std::string status_;
118     };
119     EventListener *Find(const char *type);
120     static void ProcessChange(napi_env env, std::list<void *> &args);
121     static void ProcessStatus(napi_env env, std::list<void *> &args);
122     napi_env env_;
123     ChangeEventListener *changeEventListener_;
124     StatusEventListener *statusEventListener_;
125 };
126 
127 class WatcherImpl : public ObjectWatcher {
128 public:
WatcherImpl(std::weak_ptr<JSWatcher> watcher)129     WatcherImpl(std::weak_ptr<JSWatcher> watcher) : watcher_(watcher)
130     {
131     }
132 
133     virtual ~WatcherImpl();
134 
135     void OnChanged(const std::string &sessionid, const std::vector<std::string> &changedData) override;
136 
137 private:
138     std::weak_ptr<JSWatcher> watcher_;
139 };
140 } // namespace OHOS::ObjectStore
141 
142 #endif // JSWATCHER_H
143