• 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 FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_LIBEVENTHANDLER_INCLUDE_INNER_EVENT_H
17 #define FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_LIBEVENTHANDLER_INCLUDE_INNER_EVENT_H
18 
19 #include <cstdint>
20 #include <chrono>
21 #include <functional>
22 #include <memory>
23 #include <string>
24 #include <typeinfo>
25 
26 #include "nocopyable.h"
27 
28 namespace OHOS {
29 namespace AppExecFwk {
30 class EventHandler;
31 
32 const std::string LINE_SEPARATOR = "\n";
33 
34 class InnerEvent final {
35 public:
36     using Clock = std::chrono::steady_clock;
37     using TimePoint = std::chrono::time_point<Clock>;
38     using Callback = std::function<void()>;
39     using Pointer = std::unique_ptr<InnerEvent, void (*)(InnerEvent *)>;
40 
41     class Waiter {
42     public:
43         Waiter() = default;
44         virtual ~Waiter() = default;
45         DISALLOW_COPY_AND_MOVE(Waiter);
46 
47         virtual void Wait() = 0;
48         virtual void Notify() = 0;
49     };
50 
51     DISALLOW_COPY_AND_MOVE(InnerEvent);
52 
53     /**
54      * Get InnerEvent instance from pool.
55      *
56      * @param innerEventId The id of the event.
57      * @param param Basic parameter of the event, default is 0.
58      * @return Returns the pointer of InnerEvent instance.
59      */
60     static Pointer Get(uint32_t innerEventId, int64_t param = 0);
61 
62     /**
63      * Get InnerEvent instance from pool.
64      *
65      * @param innerEventId The id of the event.
66      * @param object Shared pointer of the object.
67      * @param param Basic parameter of the event, default is 0.
68      * @return Returns the pointer of InnerEvent instance.
69      */
70     template<typename T>
71     static inline Pointer Get(uint32_t innerEventId, const std::shared_ptr<T> &object, int64_t param = 0)
72     {
73         auto event = Get(innerEventId, param);
74         event->SaveSharedPtr(object);
75         return event;
76     }
77 
78     /**
79      * Get InnerEvent instance from pool.
80      *
81      * @param innerEventId The id of the event.
82      * @param object Weak pointer of the object.
83      * @param param Basic parameter of the event, default is 0.
84      * @return Returns the pointer of InnerEvent instance.
85      */
86     template<typename T>
87     static inline Pointer Get(uint32_t innerEventId, const std::weak_ptr<T> &object, int64_t param = 0)
88     {
89         auto event = Get(innerEventId, param);
90         event->SaveSharedPtr(object);
91         return event;
92     }
93 
94     /**
95      * Get InnerEvent instance from pool.
96      *
97      * @param innerEventId The id of the event.
98      * @param object Unique pointer of the object.
99      * @param param Basic parameter of the event, default is 0.
100      * @return Returns the pointer of InnerEvent instance.
101      */
102     template<typename T, typename D>
103     static inline Pointer Get(uint32_t innerEventId, std::unique_ptr<T, D> &&object, int64_t param = 0)
104     {
105         auto event = Get(innerEventId, param);
106         event->SaveUniquePtr(object);
107         return event;
108     }
109 
110     /**
111      * Get InnerEvent instance from pool.
112      *
113      * @param innerEventId The id of the event.
114      * @param object Unique pointer of the object.
115      * @param param Basic parameter of the event, default is 0.
116      * @return Returns the pointer of InnerEvent instance.
117      */
118     template<typename T, typename D>
119     static inline Pointer Get(uint32_t innerEventId, std::unique_ptr<T, D> &object, int64_t param = 0)
120     {
121         auto event = Get(innerEventId, param);
122         event->SaveUniquePtr(object);
123         return event;
124     }
125 
126     /**
127      * Get InnerEvent instance from pool.
128      *
129      * @param innerEventId The id of the event.
130      * @param param Basic parameter of the event.
131      * @param object Shared pointer of the object.
132      * @return Returns the pointer of InnerEvent instance.
133      */
134     template<typename T>
Get(uint32_t innerEventId,int64_t param,const std::shared_ptr<T> & object)135     static inline Pointer Get(uint32_t innerEventId, int64_t param, const std::shared_ptr<T> &object)
136     {
137         auto event = Get(innerEventId, param);
138         event->SaveSharedPtr(object);
139         return event;
140     }
141 
142     /**
143      * Get InnerEvent instance from pool.
144      *
145      * @param innerEventId The id of the event.
146      * @param param Basic parameter of the event.
147      * @param object Weak pointer of the object.
148      * @return Returns the pointer of InnerEvent instance.
149      */
150     template<typename T>
Get(uint32_t innerEventId,int64_t param,const std::weak_ptr<T> & object)151     static inline Pointer Get(uint32_t innerEventId, int64_t param, const std::weak_ptr<T> &object)
152     {
153         auto event = Get(innerEventId, param);
154         event->SaveSharedPtr(object);
155         return event;
156     }
157 
158     /**
159      * Get InnerEvent instance from pool.
160      *
161      * @param innerEventId The id of the event.
162      * @param param Basic parameter of the event.
163      * @param object Unique pointer of the object.
164      * @return Returns the pointer of InnerEvent instance.
165      */
166     template<typename T, typename D>
Get(uint32_t innerEventId,int64_t param,std::unique_ptr<T,D> && object)167     static inline Pointer Get(uint32_t innerEventId, int64_t param, std::unique_ptr<T, D> &&object)
168     {
169         auto event = Get(innerEventId, param);
170         event->SaveUniquePtr(object);
171         return event;
172     }
173 
174     /**
175      * Get InnerEvent instance from pool.
176      *
177      * @param innerEventId The id of the event.
178      * @param param Basic parameter of the event.
179      * @param object Unique pointer of the object.
180      * @return Returns the pointer of InnerEvent instance.
181      */
182     template<typename T, typename D>
Get(uint32_t innerEventId,int64_t param,std::unique_ptr<T,D> & object)183     static inline Pointer Get(uint32_t innerEventId, int64_t param, std::unique_ptr<T, D> &object)
184     {
185         auto event = Get(innerEventId, param);
186         event->SaveUniquePtr(object);
187         return event;
188     }
189 
190     /**
191      * Get InnerEvent instance from pool.
192      *
193      * @param callback Callback for task.
194      * @param name Name of task.
195      * @return Returns the pointer of InnerEvent instance, if callback is invalid, returns nullptr object.
196      */
197     static Pointer Get(const Callback &callback, const std::string &name = std::string());
198 
199     /**
200      * Get InnerEvent instance from pool.
201      *
202      * @return Returns the pointer of InnerEvent instance
203      */
204     static Pointer Get();
205 
206     /**
207      * Get owner of the event.
208      *
209      * @return Returns owner of the event after it has been sent.
210      */
GetOwner()211     inline std::shared_ptr<EventHandler> GetOwner() const
212     {
213         return owner_.lock();
214     }
215 
216     /**
217      * Set owner of the event.
218      *
219      * @param owner Owner for the event.
220      */
SetOwner(const std::shared_ptr<EventHandler> & owner)221     inline void SetOwner(const std::shared_ptr<EventHandler> &owner)
222     {
223         owner_ = owner;
224     }
225 
226     /**
227      * Get handle time of the event.
228      *
229      * @return Returns handle time of the event after it has been sent.
230      */
GetHandleTime()231     inline const TimePoint &GetHandleTime() const
232     {
233         return handleTime_;
234     }
235 
236     /**
237      * Set handle time of the event.
238      *
239      * @param handleTime Handle time of the event.
240      */
SetHandleTime(const TimePoint & handleTime)241     inline void SetHandleTime(const TimePoint &handleTime)
242     {
243         handleTime_ = handleTime;
244     }
245 
246     /**
247      * Get send time of the event.
248      *
249      * @return Returns send time of the event after it has been sent.
250      */
GetSendTime()251     inline const TimePoint &GetSendTime() const
252     {
253         return sendTime_;
254     }
255 
256     /**
257      * Set send time of the event.
258      *
259      * @param sendTime Send time of the event.
260      */
SetSendTime(const TimePoint & sendTime)261     inline void SetSendTime(const TimePoint &sendTime)
262     {
263         sendTime_ = sendTime;
264     }
265 
266     /**
267      * Get id of the event.
268      * Make sure {@link #hasTask} returns false.
269      *
270      * @return Returns id of the event after it has been sent.
271      */
GetInnerEventId()272     inline uint32_t GetInnerEventId() const
273     {
274         return innerEventId_;
275     }
276 
277     /**
278      * Get basic param of the event.
279      * Make sure {@link #hasTask} returns false.
280      *
281      * @return Returns basic param of the event after it has been sent.
282      */
GetParam()283     inline int64_t GetParam() const
284     {
285         return param_;
286     }
287 
288     /**
289      * Get saved object.
290      *
291      * @return Returns shared pointer of saved object.
292      */
293     template<typename T>
GetSharedObject()294     std::shared_ptr<T> GetSharedObject() const
295     {
296         const std::shared_ptr<T> &sharedObject = *reinterpret_cast<const std::shared_ptr<T> *>(smartPtr_);
297         if (CalculateSmartPtrTypeId(sharedObject) == smartPtrTypeId_) {
298             return sharedObject;
299         }
300 
301         const std::weak_ptr<T> &weakObject = *reinterpret_cast<const std::weak_ptr<T> *>(smartPtr_);
302         if (CalculateSmartPtrTypeId(weakObject) == smartPtrTypeId_) {
303             return weakObject.lock();
304         }
305 
306         WarnSmartPtrCastMismatch();
307         return nullptr;
308     }
309 
310     /**
311      * Get saved object.
312      *
313      * @return Returns unique pointer of saved object.
314      */
315     template<typename T>
GetUniqueObject()316     std::unique_ptr<T> GetUniqueObject() const
317     {
318         std::unique_ptr<T> &object = *reinterpret_cast<std::unique_ptr<T> *>(smartPtr_);
319         if (CalculateSmartPtrTypeId(object) == smartPtrTypeId_) {
320             return std::move(object);
321         }
322 
323         WarnSmartPtrCastMismatch();
324         return nullptr;
325     }
326 
327     /**
328      * Get saved object.
329      *
330      * @return Returns unique pointer of saved object.
331      */
332     template<typename T, typename D>
GetUniqueObject()333     std::unique_ptr<T, D> GetUniqueObject() const
334     {
335         std::unique_ptr<T, D> &object = *reinterpret_cast<std::unique_ptr<T, D> *>(smartPtr_);
336         if (CalculateSmartPtrTypeId(object) == smartPtrTypeId_) {
337             return std::move(object);
338         }
339 
340         WarnSmartPtrCastMismatch();
341         return std::unique_ptr<T, D>(nullptr, nullptr);
342     }
343 
344     /**
345      * Get task name.
346      * Make sure {@link #hasTask} returns true.
347      *
348      * @return Returns the task name.
349      */
GetTaskName()350     inline const std::string &GetTaskName() const
351     {
352         return taskName_;
353     }
354 
355     /**
356      * Get task callback.
357      * Make sure {@link #hasTask} returns true.
358      *
359      * @return Returns the callback of the task.
360      */
GetTaskCallback()361     inline const Callback &GetTaskCallback() const
362     {
363         return taskCallback_;
364     }
365 
366     /**
367      * Obtains the Runnable task that will be executed when this InnerEvent is handled.
368      *
369      * @return Returns the callback of the task.
370      */
GetTask()371     inline const Callback &GetTask() const
372     {
373         return GetTaskCallback();
374     }
375 
376     /**
377      * Check whether it takes a task callback in event.
378      *
379      * @return Returns true if it takes a task callback.
380      */
HasTask()381     inline bool HasTask() const
382     {
383         return static_cast<bool>(taskCallback_);
384     }
385 
386     /**
387      * Prints out the internal information about an object in the specified format,
388      * helping you diagnose internal errors of the object.
389      *
390      * @param return The content of the event.
391      */
392     std::string Dump();
393 
394 private:
395     using SmartPtrDestructor = void (*)(void *);
396 
397     InnerEvent() = default;
398     ~InnerEvent() = default;
399 
400     void ClearEvent();
401 
402     static void WarnSmartPtrCastMismatch();
403 
404     template<typename T>
ReleaseSmartPtr(void * smartPtr)405     static void ReleaseSmartPtr(void *smartPtr)
406     {
407         if (smartPtr != nullptr) {
408             delete reinterpret_cast<T *>(smartPtr);
409         }
410     }
411 
412     template<typename T>
SaveSharedPtr(const T & object)413     inline void SaveSharedPtr(const T &object)
414     {
415         smartPtr_ = new T(object);
416         smartPtrDtor_ = ReleaseSmartPtr<T>;
417         smartPtrTypeId_ = CalculateSmartPtrTypeId(object);
418     }
419 
420     template<typename T>
SaveUniquePtr(T & object)421     inline void SaveUniquePtr(T &object)
422     {
423         smartPtr_ = new T(std::move(object));
424         smartPtrDtor_ = ReleaseSmartPtr<T>;
425         smartPtrTypeId_ = CalculateSmartPtrTypeId(object);
426     }
427 
428     /*
429      * Calculate the type id for different smart pointers.
430      */
431 #ifdef __GXX_RTTI
432     // If RTTI(Run-Time Type Info) is enabled, use hash code of type info.
433     template<typename T>
CalculateSmartPtrTypeId(const T &)434     static inline size_t CalculateSmartPtrTypeId(const T &)
435     {
436         return typeid(T).hash_code();
437     }
438 #else   // #ifdef __GXX_RTTI
439     // Otherwise, generate type id using smart pointer type and the size of the elements they contain.
440     static const size_t SHARED_PTR_TYPE = 0x10000000;
441     static const size_t WEAK_PTR_TYPE = 0x20000000;
442     static const size_t UNIQUE_PTR_TYPE = 0x30000000;
443     static const size_t UNIQUE_PTR_ARRAY_TYPE = 0x40000000;
444 
445     template<typename T>
CalculateSmartPtrTypeId(const std::shared_ptr<T> &)446     static inline size_t CalculateSmartPtrTypeId(const std::shared_ptr<T> &)
447     {
448         return (sizeof(T) | SHARED_PTR_TYPE);
449     }
450 
451     template<typename T>
CalculateSmartPtrTypeId(const std::weak_ptr<T> &)452     static inline size_t CalculateSmartPtrTypeId(const std::weak_ptr<T> &)
453     {
454         return (sizeof(T) | WEAK_PTR_TYPE);
455     }
456 
457     template<typename T, typename D>
CalculateSmartPtrTypeId(const std::unique_ptr<T,D> &)458     static inline size_t CalculateSmartPtrTypeId(const std::unique_ptr<T, D> &)
459     {
460         return (sizeof(T) | (sizeof(D) - 1) | UNIQUE_PTR_TYPE);
461     }
462 
463     template<typename T, typename D>
CalculateSmartPtrTypeId(const std::unique_ptr<T[],D> &)464     static inline size_t CalculateSmartPtrTypeId(const std::unique_ptr<T[], D> &)
465     {
466         return (sizeof(T) | (sizeof(D) - 1) | UNIQUE_PTR_ARRAY_TYPE);
467     }
468 #endif  // #ifdef __GXX_RTTI
469 
470     // Used by event handler to create waiter.
471     const std::shared_ptr<Waiter> &CreateWaiter();
472 
473     // Used by event handler to tell whether event has waiter.
474     bool HasWaiter() const;
475 
476     // Let event pool to create instance of events.
477     friend class InnerEventPool;
478     // Let event handler to access private interface.
479     friend class EventHandler;
480 
481     std::weak_ptr<EventHandler> owner_;
482     TimePoint handleTime_;
483     TimePoint sendTime_;
484 
485     // Event id of the event, if it is not a task object
486     uint32_t innerEventId_{0};
487 
488     // Simple parameter for the event.
489     int64_t param_{0};
490 
491     // Using to save smart pointer
492     size_t smartPtrTypeId_{0};
493     void *smartPtr_{nullptr};
494     SmartPtrDestructor smartPtrDtor_{nullptr};
495 
496     // Task callback and its name.
497     Callback taskCallback_;
498     std::string taskName_;
499 
500     // Used for synchronized event.
501     std::shared_ptr<Waiter> waiter_;
502 };
503 }  // namespace AppExecFwk
504 }  // namespace OHOS
505 
506 #endif  // #ifndef FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_LIBEVENTHANDLER_INCLUDE_INNER_EVENT_H
507