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 "startable_handler.h"
17
18 SCENE_BEGIN_NAMESPACE()
19
20 namespace Internal {
21
StartStartable(const IInternalScene::Ptr & scene,StartableHandler::StartType type,const META_NS::IObject::Ptr & object)22 bool StartStartable(
23 const IInternalScene::Ptr& scene, StartableHandler::StartType type, const META_NS::IObject::Ptr& object)
24 {
25 if (auto startable = interface_cast<META_NS::IStartable>(object); startable && scene) {
26 const auto state = META_NS::GetValue(startable->StartableState());
27 if (state == META_NS::StartableState::ATTACHED) {
28 const auto mode = GetValue(startable->StartableMode());
29 if (mode == META_NS::StartBehavior::AUTOMATIC) {
30 if (type == StartableHandler::StartType::DEFERRED) {
31 scene->PostUserNotification(
32 [s = interface_pointer_cast<META_NS::IStartable>(object)]() { s->Start(); });
33 return true;
34 }
35 return startable->Start();
36 }
37 }
38 }
39 return false;
40 }
41
StopStartable(const META_NS::IObject::Ptr & object)42 bool StopStartable(const META_NS::IObject::Ptr& object)
43 {
44 if (auto startable = interface_cast<META_NS::IStartable>(object)) {
45 const auto state = META_NS::GetValue(startable->StartableState());
46 if (state == META_NS::StartableState::STARTED) {
47 const auto mode = GetValue(startable->StartableMode());
48 if (mode == META_NS::StartBehavior::AUTOMATIC) {
49 return startable->Stop();
50 }
51 }
52 }
53 return false;
54 }
55
StartAllStartables(const IInternalScene::Ptr & scene,StartableHandler::StartType type,const META_NS::IObject::Ptr & object)56 bool StartAllStartables(
57 const IInternalScene::Ptr& scene, StartableHandler::StartType type, const META_NS::IObject::Ptr& object)
58 {
59 auto startAll = [s = IInternalScene::WeakPtr { scene }, n = META_NS::IObject::WeakPtr { object }]() {
60 if (auto attach = interface_pointer_cast<META_NS::IAttach>(n)) {
61 if (auto container = attach->GetAttachmentContainer(false)) {
62 META_NS::IterateShared(
63 container,
64 [s](const META_NS::IObject::Ptr& attachment) {
65 StartStartable(s.lock(), StartableHandler::StartType::DIRECT, attachment);
66 return true;
67 },
68 META_NS::TraversalType::NO_HIERARCHY);
69 return true;
70 }
71 }
72 return false;
73 };
74 if (scene) {
75 if (type == StartableHandler::StartType::DEFERRED) {
76 scene->PostUserNotification(startAll);
77 } else {
78 startAll();
79 }
80 return true;
81 }
82 return false;
83 }
84
StopAllStartables(const META_NS::IObject::Ptr & object)85 bool StopAllStartables(const META_NS::IObject::Ptr& object)
86 {
87 if (auto attach = interface_pointer_cast<META_NS::IAttach>(object)) {
88 if (auto container = attach->GetAttachmentContainer(false)) {
89 META_NS::IterateShared(container, [](const META_NS::IObject::Ptr& attachment) {
90 StopStartable(attachment);
91 return true;
92 });
93 return true;
94 }
95 }
96 return false;
97 }
98
99 } // namespace Internal
100
GetScene() const101 IInternalScene::Ptr StartableHandler::GetScene() const
102 {
103 if (auto node = node_.lock()) {
104 if (auto scene = node->GetScene()) {
105 return scene->GetInternalScene();
106 }
107 }
108 return {};
109 }
110
Start(const META_NS::IObject::Ptr & attachment,StartType type)111 bool StartableHandler::Start(const META_NS::IObject::Ptr& attachment, StartType type)
112 {
113 return Internal::StartStartable(GetScene(), type, attachment);
114 }
115
Stop(const META_NS::IObject::Ptr & attachment)116 bool StartableHandler::Stop(const META_NS::IObject::Ptr& attachment)
117 {
118 return Internal::StopStartable(attachment);
119 }
120
StartAll(StartType type)121 bool StartableHandler::StartAll(StartType type)
122 {
123 return Internal::StartAllStartables(GetScene(), type, interface_pointer_cast<META_NS::IObject>(node_));
124 }
125
StopAll(const META_NS::IContainer::Ptr & container)126 bool StartableHandler::StopAll(const META_NS::IContainer::Ptr& container)
127 {
128 if (container) {
129 META_NS::IterateShared(container, [this](const META_NS::IObject::Ptr& attachment) {
130 Stop(attachment);
131 return true;
132 });
133 return true;
134 }
135 return false;
136 }
137
StopAll()138 bool StartableHandler::StopAll()
139 {
140 return Internal::StopAllStartables(interface_pointer_cast<META_NS::IObject>(node_));
141 }
142
143 SCENE_END_NAMESPACE()
144