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 #include "property.h"
16 
17 META_BEGIN_NAMESPACE()
18 namespace Internal {
19 
GetName() const20 BASE_NS::string PropertyBase::GetName() const
21 {
22     return name_;
23 }
GetOwner() const24 IObject::WeakPtr PropertyBase::GetOwner() const
25 {
26     return owner_;
27 }
SetOwner(IObject::Ptr owner)28 void PropertyBase::SetOwner(IObject::Ptr owner)
29 {
30     owner_ = owner;
31 }
SetSelf(IProperty::Ptr self)32 void PropertyBase::SetSelf(IProperty::Ptr self)
33 {
34     self_ = self;
35 }
SetValue(const IAny & value)36 AnyReturnValue PropertyBase::SetValue(const IAny& value)
37 {
38     auto res = SetInternalValue(value);
39     if (res == AnyReturn::SUCCESS) {
40         CallOnChanged();
41     }
42     return res;
43 }
GetValue() const44 const IAny& PropertyBase::GetValue() const
45 {
46     auto v = GetData();
47     CORE_ASSERT(v);
48     return *v;
49 }
IsCompatible(const TypeId & id) const50 bool PropertyBase::IsCompatible(const TypeId& id) const
51 {
52     auto v = GetData();
53     return v && META_NS::IsCompatible(*v, id);
54 }
GetTypeId() const55 TypeId PropertyBase::GetTypeId() const
56 {
57     auto p = GetData();
58     return p ? p->GetTypeId() : TypeId {};
59 }
EventOnChanged() const60 IEvent::Ptr PropertyBase::EventOnChanged() const
61 {
62     // notice that this requires locking outside unlike the old system
63     // if needed, consider separate locking for the construction
64     if (!onChanged_) {
65         onChanged_ = CreateShared<OnChangedEvent>("OnChanged");
66         onChangedAtomic_.store(onChanged_.get());
67     }
68     return onChanged_;
69 }
NotifyChange() const70 void PropertyBase::NotifyChange() const
71 {
72     CallOnChanged();
73 }
CallOnChanged() const74 void PropertyBase::CallOnChanged() const
75 {
76     pendingInvoke_ = locked_ != 0;
77     if (!locked_ && onChanged_) {
78         onChanged_->Invoke();
79     }
80 }
Lock() const81 void PropertyBase::Lock() const
82 {
83     mutex_.lock();
84     ++locked_;
85 }
Unlock() const86 void PropertyBase::Unlock() const
87 {
88     BASE_NS::shared_ptr<OnChangedEvent> invoke;
89     if (--locked_ == 0 && pendingInvoke_) {
90         invoke = onChanged_;
91         pendingInvoke_ = false;
92     }
93     mutex_.unlock();
94     if (invoke) {
95         invoke->Invoke();
96     }
97 }
LockShared() const98 void PropertyBase::LockShared() const
99 {
100     Lock();
101 }
UnlockShared() const102 void PropertyBase::UnlockShared() const
103 {
104     Unlock();
105 }
SetInternalValue(const IAny & value)106 AnyReturnValue PropertyBase::SetInternalValue(const IAny& value)
107 {
108     if (auto& d = GetData()) {
109         if (d.get() == &value) {
110             return AnyReturn::SUCCESS;
111         }
112         return d->CopyFrom(value);
113     }
114     return AnyReturn::FAIL;
115 }
116 
SetInternalAny(IAny::Ptr any)117 AnyReturnValue GenericProperty::SetInternalAny(IAny::Ptr any)
118 {
119     data_ = BASE_NS::move(any);
120     return AnyReturn::SUCCESS;
121 }
GetInternalAny() const122 IAny::Ptr GenericProperty::GetInternalAny() const
123 {
124     return data_;
125 }
126 
127 } // namespace Internal
128 META_END_NAMESPACE()
129