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 <meta/api/make_callback.h>
17 #include <meta/interface/intf_recyclable.h>
18
19 #include "instantiating_object_provider.h"
20
META_BEGIN_NAMESPACE()21 META_BEGIN_NAMESPACE()
22
23 ObjectProviderBase::~ObjectProviderBase()
24 {
25 SetDataModel(nullptr);
26 }
27
CreateObject(const DataModelIndex & index)28 IObject::Ptr ObjectProviderBase::CreateObject(const DataModelIndex& index)
29 {
30 if (!index.IsValid() || !model_) {
31 return nullptr;
32 }
33
34 IObject::Ptr obj;
35 if (auto data = model_->GetModelData(index)) {
36 if (!recyclebin_.empty()) {
37 obj = recyclebin_.back();
38 recyclebin_.pop_back();
39 } else {
40 obj = Construct(data);
41 }
42 if (auto i = interface_cast<IRecyclable>(obj)) {
43 i->ReBuild(data);
44 } else {
45 BindProperties(obj, data);
46 }
47 }
48 return obj;
49 }
50
DisposeObject(const META_NS::IObject::Ptr & item)51 bool ObjectProviderBase::DisposeObject(const META_NS::IObject::Ptr& item)
52 {
53 if (auto i = interface_cast<IRecyclable>(item)) {
54 i->Dispose();
55 } else if (auto d = interface_cast<IMetadata>(item)) {
56 for (auto&& p : d->GetProperties()) {
57 if (!IsFlagSet(p, ObjectFlagBits::NATIVE)) {
58 PropertyLock l { p };
59 l->ResetBind();
60 }
61 }
62 }
63 bool recycle = recyclebin_.size() < CacheHint()->GetValue();
64 if (recycle) {
65 recyclebin_.push_back(item);
66 }
67 return recycle;
68 }
69
GetObjectCount(const DataModelIndex & index) const70 size_t ObjectProviderBase::GetObjectCount(const DataModelIndex& index) const
71 {
72 return model_ ? model_->GetSize() : 0;
73 }
74
SetDataModel(const IDataModel::Ptr & model)75 bool ObjectProviderBase::SetDataModel(const IDataModel::Ptr& model)
76 {
77 if (model_) {
78 model_->OnDataAdded()->RemoveHandler(uintptr_t(this));
79 model_->OnDataRemoved()->RemoveHandler(uintptr_t(this));
80 model_->OnDataMoved()->RemoveHandler(uintptr_t(this));
81 }
82 model_ = model;
83 if (model_) {
84 model_->OnDataAdded()->AddHandler(MakeCallback<IOnDataAdded>([this](DataModelIndex base, size_t count) {
85 Invoke<IOnDataAdded>(META_ACCESS_EVENT(OnDataAdded), base, count);
86 }),
87 uintptr_t(this));
88 model_->OnDataRemoved()->AddHandler(MakeCallback<IOnDataRemoved>([this](DataModelIndex base, size_t count) {
89 Invoke<IOnDataRemoved>(META_ACCESS_EVENT(OnDataRemoved), base, count);
90 }),
91 uintptr_t(this));
92 model_->OnDataMoved()->AddHandler(
93 MakeCallback<IOnDataMoved>([this](DataModelIndex from, size_t count, DataModelIndex to) {
94 Invoke<IOnDataMoved>(META_ACCESS_EVENT(OnDataMoved), from, count, to);
95 }),
96 uintptr_t(this));
97 }
98 return true;
99 }
100
GetDataModel() const101 IDataModel::Ptr ObjectProviderBase::GetDataModel() const
102 {
103 return model_;
104 }
105
BindProperties(const IObject::Ptr & object,const IMetadata::Ptr & data) const106 void ObjectProviderBase::BindProperties(const IObject::Ptr& object, const IMetadata::Ptr& data) const
107 {
108 if (auto odata = interface_cast<IMetadata>(object)) {
109 for (auto&& p : data->GetProperties()) {
110 BASE_NS::string name = "Model." + p->GetName();
111 IProperty::Ptr prop = odata->GetProperty(name);
112 if (!prop) {
113 prop = DuplicatePropertyType(META_NS::GetObjectRegistry(), p, name);
114 if (prop) {
115 odata->AddProperty(prop);
116 }
117 }
118 if (prop) {
119 PropertyLock l { prop };
120 l->SetBind(p);
121 }
122 }
123 }
124 }
125
Construct(const IMetadata::Ptr & data)126 IObject::Ptr ObjectProviderBase::Construct(const IMetadata::Ptr& data)
127 {
128 return nullptr;
129 }
130
131 META_END_NAMESPACE()
132