1 /*
2  * Copyright (c) 2024 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 #ifndef META_API_PROPERTY_EVENT_HANDLER_H
16 #define META_API_PROPERTY_EVENT_HANDLER_H
17 
18 #include <meta/api/event_handler.h>
19 #include <meta/base/interface_macros.h>
20 #include <meta/interface/property/property_events.h>
21 
META_BEGIN_NAMESPACE()22 META_BEGIN_NAMESPACE()
23 
24 /**
25  * @brief The PropertyEventHandler class is a helper class for adding event handlers to property events.
26  */
27 
28 template<typename EventType, BASE_NS::shared_ptr<IEvent> (INotifyOnChange::*EventFunc)() const>
29 class PropertyEventHandler {
30 public:
31     using CallableTypePtr = typename EventType::InterfaceTypePtr;
32 
33     META_NO_COPY(PropertyEventHandler)
34     META_DEFAULT_MOVE(PropertyEventHandler)
35     PropertyEventHandler() noexcept = default;
36     virtual ~PropertyEventHandler() = default;
37 
38     bool Subscribe(const IProperty::ConstPtr& property, const CallableTypePtr& onInvoked)
39     {
40         // This basic from is used with array properties as well, so use the typeless subscribe here
41         return handler_.TypelessSubscribe((property.get()->*EventFunc)(), onInvoked);
42     }
43 
44     bool Subscribe(const IProperty::ConstPtr& property, const CallableTypePtr& onInvoked, const ITaskQueue::Ptr& queue)
45     {
46         return handler_.Subscribe<EventType>((property.get()->*EventFunc)(), onInvoked, queue);
47     }
48 
49     bool Subscribe(const IProperty::ConstPtr& property, const CallableTypePtr& onInvoked, const BASE_NS::Uid& queueId)
50     {
51         return handler_.Subscribe<EventType>((property.get()->*EventFunc)(), onInvoked, queueId);
52     }
53 
54     template<typename Func, typename = EnableIfCanInvokeWithArguments<Func, typename EventType::FunctionType>>
55     bool Subscribe(const IProperty::ConstPtr& property, Func func, const ITaskQueue::Ptr& queue = nullptr)
56     {
57         return handler_.Subscribe<EventType>((property.get()->*EventFunc)(), BASE_NS::move(func), queue);
58     }
59 
60     template<typename Func, typename = EnableIfCanInvokeWithArguments<Func, typename EventType::FunctionType>>
61     bool Subscribe(const IProperty::ConstPtr& property, Func func, const BASE_NS::Uid& queueId)
62     {
63         return handler_.Subscribe<EventType>((property.get()->*EventFunc)(), BASE_NS::move(func), queueId);
64     }
65 
66     void Unsubscribe()
67     {
68         handler_.Unsubscribe();
69     }
70 
71 private:
72     EventHandler handler_;
73 };
74 
75 /**
76  * @brief EventHandler for handling IProperty::OnChanged event.
77  */
78 class PropertyChangedEventHandler final : public PropertyEventHandler<IOnChanged, &IProperty::EventOnChanged> {
79 public:
80     PropertyChangedEventHandler() = default;
PropertyChangedEventHandler(const IProperty::ConstPtr & property,const IOnChanged::InterfaceTypePtr & onInvoked)81     PropertyChangedEventHandler(const IProperty::ConstPtr& property, const IOnChanged::InterfaceTypePtr& onInvoked)
82     {
83         Subscribe(property, onInvoked);
84     }
85 };
86 
87 META_END_NAMESPACE()
88 
89 #endif
90