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