• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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