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
16 #include "property.h"
17
18 #include <meta/interface/intf_owner.h>
19
20 META_BEGIN_NAMESPACE()
21 namespace Internal {
22
GetName() const23 BASE_NS::string PropertyBase::GetName() const
24 {
25 return name_;
26 }
GetOwner() const27 IOwner::WeakPtr PropertyBase::GetOwner() const
28 {
29 return owner_;
30 }
SetOwner(IOwner::Ptr owner)31 void PropertyBase::SetOwner(IOwner::Ptr owner)
32 {
33 owner_ = owner;
34 }
SetSelf(IProperty::Ptr self)35 void PropertyBase::SetSelf(IProperty::Ptr self)
36 {
37 self_ = self;
38 }
SetValue(const IAny & value)39 AnyReturnValue PropertyBase::SetValue(const IAny& value)
40 {
41 auto res = SetInternalValue(value);
42 if (res == AnyReturn::SUCCESS) {
43 CallOnChanged(false);
44 }
45 return res;
46 }
GetValue() const47 const IAny& PropertyBase::GetValue() const
48 {
49 auto v = GetData();
50 CORE_ASSERT_MSG(v, "Internal any not set");
51 return *v;
52 }
IsCompatible(const TypeId & id) const53 bool PropertyBase::IsCompatible(const TypeId& id) const
54 {
55 auto v = GetData();
56 return v && META_NS::IsCompatible(*v, id);
57 }
GetTypeId() const58 TypeId PropertyBase::GetTypeId() const
59 {
60 auto p = GetData();
61 return p ? p->GetTypeId() : TypeId {};
62 }
EventOnChanged(MetadataQuery q) const63 IEvent::Ptr PropertyBase::EventOnChanged(MetadataQuery q) const
64 {
65 // notice that this requires locking outside unlike the old system
66 // if needed, consider separate locking for the construction
67 if (!onChanged_ && q == MetadataQuery::CONSTRUCT_ON_REQUEST) {
68 onChanged_ = CreateShared<OnChangedEvent>("OnChanged");
69 onChangedAtomic_.store(onChanged_.get());
70 }
71 return onChanged_;
72 }
NotifyChange() const73 void PropertyBase::NotifyChange() const
74 {
75 CallOnChanged(false);
76 }
InvokeOnChanged(const BASE_NS::shared_ptr<OnChangedEvent> & onChanged,const IOwner::WeakPtr & owner) const77 void PropertyBase::InvokeOnChanged(
78 const BASE_NS::shared_ptr<OnChangedEvent>& onChanged, const IOwner::WeakPtr& owner) const
79 {
80 if (auto ow = interface_pointer_cast<IPropertyOwner>(owner)) {
81 ow->OnPropertyChanged(*this);
82 }
83 if (onChanged) {
84 onChanged->Invoke();
85 }
86 }
CallOnChanged(bool forcePending) const87 void PropertyBase::CallOnChanged(bool forcePending) const
88 {
89 bool pending = forcePending || locked_ != 0;
90 SetPendingInvoke(pending);
91 if (!pending) {
92 InvokeOnChanged(onChanged_, owner_);
93 }
94 }
Lock() const95 void PropertyBase::Lock() const
96 {
97 mutex_.lock();
98 ++locked_;
99 }
Unlock() const100 void PropertyBase::Unlock() const
101 {
102 BASE_NS::shared_ptr<OnChangedEvent> invoke;
103 IOwner::WeakPtr owner {};
104 if (--locked_ == 0 && HasPendingInvoke()) {
105 invoke = onChanged_;
106 SetPendingInvoke(false);
107 owner = owner_;
108 }
109 mutex_.unlock();
110 InvokeOnChanged(invoke, owner);
111 }
LockShared() const112 void PropertyBase::LockShared() const
113 {
114 Lock();
115 }
UnlockShared() const116 void PropertyBase::UnlockShared() const
117 {
118 Unlock();
119 }
Attaching(const IAttach::Ptr & target,const IObject::Ptr &)120 bool PropertyBase::Attaching(const IAttach::Ptr& target, const IObject::Ptr&)
121 {
122 owner_ = interface_pointer_cast<IOwner>(target);
123 return true;
124 }
Detaching(const IAttach::Ptr &)125 bool PropertyBase::Detaching(const IAttach::Ptr&)
126 {
127 owner_ = nullptr;
128 return true;
129 }
SetInternalValue(const IAny & value)130 AnyReturnValue PropertyBase::SetInternalValue(const IAny& value)
131 {
132 if (auto& d = GetData()) {
133 if (d.get() == &value) {
134 return AnyReturn::SUCCESS;
135 }
136 return d->CopyFrom(value);
137 }
138 return AnyReturn::FAIL;
139 }
140
SetInternalAny(IAny::Ptr any)141 AnyReturnValue GenericProperty::SetInternalAny(IAny::Ptr any)
142 {
143 data_ = BASE_NS::move(any);
144 return AnyReturn::SUCCESS;
145 }
GetInternalAny() const146 IAny::Ptr GenericProperty::GetInternalAny() const
147 {
148 return data_;
149 }
150
151 } // namespace Internal
152 META_END_NAMESPACE()
153