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