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_SRC_PROPERTY_H
16 #define META_SRC_PROPERTY_H
17 
18 #include <atomic>
19 #include <memory>
20 #include <mutex>
21 
22 #include <meta/base/namespace.h>
23 #include <meta/base/types.h>
24 #include <meta/ext/event_impl.h>
25 #include <meta/ext/minimal_object.h>
26 #include <meta/interface/intf_any.h>
27 #include <meta/interface/intf_lockable.h>
28 #include <meta/interface/property/intf_modifier.h>
29 #include <meta/interface/property/intf_property_internal.h>
30 #include <meta/interface/property/property_events.h>
31 
META_BEGIN_NAMESPACE()32 META_BEGIN_NAMESPACE()
33 namespace Internal {
34 
35 META_REGISTER_CLASS(Property, "1801d9a9-3557-4e0d-b90e-54791acd6768", ObjectCategoryBits::NO_CATEGORY)
36 
37 class PropertyBase : public MinimalObject<ClassId::Property, IProperty, IPropertyInternal, ILockable, IValue> {
38 public:
39     using OnChangedEvent = EventImpl<IOnChanged>;
40 
41     PropertyBase(BASE_NS::string name) : name_(BASE_NS::move(name)) {}
42 
43     BASE_NS::string GetName() const override;
44 
45     IObject::WeakPtr GetOwner() const override;
46     void SetOwner(IObject::Ptr owner) override;
47     void SetSelf(IProperty::Ptr self) override;
48 
49     AnyReturnValue SetValue(const IAny& value) override;
50     const IAny& GetValue() const override;
51     bool IsCompatible(const TypeId& id) const override;
52 
53     TypeId GetTypeId() const override;
54     void NotifyChange() const override;
55 
56     IEvent::Ptr EventOnChanged() const override;
57 
58     void Lock() const override;
59     void Unlock() const override;
60     void LockShared() const override;
61     void UnlockShared() const override;
62 
63 protected:
64     virtual IAny::Ptr& GetData() const = 0;
65     AnyReturnValue SetInternalValue(const IAny& value);
66     void CallOnChanged() const;
67 
68 protected:
69     // this has to be recursive because of the usage pattern
70     mutable std::recursive_mutex mutex_;
71     mutable size_t locked_ {};
72     mutable bool pendingInvoke_ {};
73     const BASE_NS::string name_;
74     IObject::WeakPtr owner_;
75     IProperty::WeakPtr self_;
76     // lazy event, constructed when needed
77     mutable BASE_NS::shared_ptr<OnChangedEvent> onChanged_;
78     mutable std::atomic<OnChangedEvent*> onChangedAtomic_ {};
79 };
80 
81 class GenericProperty : public IntroduceInterfaces<PropertyBase, IPropertyInternalAny> {
82     using Super = IntroduceInterfaces<PropertyBase, IPropertyInternalAny>;
83 
84 public:
85     using Super::Super;
86 
87     AnyReturnValue SetInternalAny(IAny::Ptr any) override;
88     IAny::Ptr GetInternalAny() const override;
89 
90 protected:
91     IAny::Ptr& GetData() const override
92     {
93         return data_;
94     }
95 
96 private:
97     mutable IAny::Ptr data_;
98 };
99 
100 } // namespace Internal
101 META_END_NAMESPACE()
102 
103 #endif