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