• 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 #include <mutex>
17 #include <shared_mutex>
18 
19 #include <meta/api/event_handler.h>
20 #include <meta/api/property/property_event_handler.h>
21 #include <meta/api/threading/mutex.h>
22 #include <meta/base/interface_macros.h>
23 #include <meta/base/namespace.h>
24 #include <meta/ext/implementation_macros.h>
25 #include <meta/interface/intf_content.h>
26 #include <meta/interface/intf_iterable.h>
27 #include <meta/interface/intf_required_interfaces.h>
28 #include <meta/interface/loaders/intf_dynamic_content_loader.h>
29 
30 #include "object.h"
31 
32 META_BEGIN_INTERNAL_NAMESPACE()
33 
34 class ContentObject : public IntroduceInterfaces<MetaObject, IContent, IRequiredInterfaces, IIterable> {
35     META_OBJECT(ContentObject, ClassId::ContentObject, IntroduceInterfaces)
36 public:
37     META_BEGIN_STATIC_DATA()
META_STATIC_PROPERTY_DATA(IContent,IObject::Ptr,Content)38     META_STATIC_PROPERTY_DATA(IContent, IObject::Ptr, Content)
39     META_STATIC_PROPERTY_DATA(IContent, bool, ContentSearchable, true)
40     META_END_STATIC_DATA()
41     META_IMPLEMENT_READONLY_PROPERTY(IObject::Ptr, Content)
42     META_IMPLEMENT_PROPERTY(bool, ContentSearchable)
43 
44     bool SetContent(const IObject::Ptr& content) override
45     {
46         bool valid = CheckContentRequirements(content);
47         SetValue(META_ACCESS_PROPERTY(Content), valid ? content : nullptr);
48         if (!valid) {
49             CORE_LOG_W("Content does not fulfil interface requirements");
50         }
51         return valid;
52     }
53 
Build(const IMetadata::Ptr & data)54     bool Build(const IMetadata::Ptr& data) override
55     {
56         bool ret = Super::Build(data);
57         if (ret) {
58             OnSerializeChanged();
59         }
60         return ret;
61     }
62 
Destroy()63     void Destroy() override
64     {
65         if (auto c = META_ACCESS_PROPERTY(Content)) {
66             c->OnChanged()->Reset();
67             c->SetValue(nullptr);
68         }
69         Super::Destroy();
70     }
71 
OnSerializeChanged()72     void OnSerializeChanged()
73     {
74         if (auto cont = META_ACCESS_PROPERTY(Content)) {
75             META_NS::SetObjectFlags(cont.GetProperty(), ObjectFlagBits::SERIALIZE,
76                 GetObjectFlags().IsSet(ObjectFlagBits::SERIALIZE_HIERARCHY));
77         }
78     }
79 
SetObjectFlags(const ObjectFlagBitsValue & flags)80     void SetObjectFlags(const ObjectFlagBitsValue& flags) override
81     {
82         Super::SetObjectFlags(flags);
83         OnSerializeChanged();
84     }
85 
GetObjectDefaultFlags() const86     ObjectFlagBitsValue GetObjectDefaultFlags() const override
87     {
88         auto flags = Super::GetObjectDefaultFlags();
89         flags &= ~ObjectFlagBitsValue(ObjectFlagBits::SERIALIZE_HIERARCHY);
90         return flags;
91     }
92 
SetRequiredInterfaces(const BASE_NS::vector<TypeId> & interfaces)93     bool SetRequiredInterfaces(const BASE_NS::vector<TypeId>& interfaces) override
94     {
95         {
96             std::unique_lock lock(mutex_);
97             requiredInterfaces_ = interfaces;
98         }
99         if (const auto content = META_ACCESS_PROPERTY_VALUE(Content)) {
100             if (!CheckContentRequirements(content)) {
101                 SetContent(nullptr);
102             }
103         }
104         return true;
105     }
GetRequiredInterfaces() const106     BASE_NS::vector<TypeId> GetRequiredInterfaces() const override
107     {
108         std::shared_lock lock(mutex_);
109         return requiredInterfaces_;
110     }
111 
CheckContentRequirements(const IObject::Ptr & object)112     bool CheckContentRequirements(const IObject::Ptr& object)
113     {
114         std::shared_lock lock(mutex_);
115         // Null object always passes content requirements
116         return !object || CheckInterfaces(object, requiredInterfaces_, true);
117     }
118 
119     template<typename Func>
IterateImpl(const Func & f) const120     IterationResult IterateImpl(const Func& f) const
121     {
122         if (!f) {
123             CORE_LOG_W("Incompatible function with Iterate");
124             return IterationResult::FAILED;
125         }
126         if (META_ACCESS_PROPERTY_VALUE(ContentSearchable)) {
127             if (auto c = META_ACCESS_PROPERTY_VALUE(Content)) {
128                 return f->Invoke(c);
129             }
130         }
131         return IterationResult::CONTINUE;
132     }
133 
Iterate(const IterationParameters & params)134     IterationResult Iterate(const IterationParameters& params) override
135     {
136         return IterateImpl(params.function.GetInterface<IIterableCallable<IObject::Ptr>>());
137     }
138 
Iterate(const IterationParameters & params) const139     IterationResult Iterate(const IterationParameters& params) const override
140     {
141         return IterateImpl(params.function.GetInterface<IIterableConstCallable<IObject::Ptr>>());
142     }
143 
144 private:
145     mutable std::shared_mutex mutex_;
146     BASE_NS::vector<TypeId> requiredInterfaces_;
147 };
148 
GetContentObjectFactory()149 IObjectFactory::Ptr GetContentObjectFactory()
150 {
151     return ContentObject::GetFactory();
152 }
153 
154 META_END_INTERNAL_NAMESPACE()
155