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 #ifndef META_SRC_STARTABLE_OBJECT_CONTROLLER_H
17 #define META_SRC_STARTABLE_OBJECT_CONTROLLER_H
18
19 #include <shared_mutex>
20
21 #include <base/containers/unordered_map.h>
22
23 #include <meta/api/timer.h>
24 #include <meta/ext/attachment/attachment.h>
25 #include <meta/interface/builtin_objects.h>
26 #include <meta/interface/intf_object_hierarchy_observer.h>
27 #include <meta/interface/intf_startable_controller.h>
28 #include <meta/interface/intf_task_queue.h>
29 #include <meta/interface/intf_tickable_controller.h>
30
META_BEGIN_NAMESPACE()31 META_BEGIN_NAMESPACE()
32
33 class IStartableObjectControllerInternal : public CORE_NS::IInterface {
34 META_INTERFACE(CORE_NS::IInterface, IStartableObjectControllerInternal, "fd5c13af-de72-4cc4-bed0-07cb6a751ac1")
35 public:
36 /**
37 * @brief Run tasks with given queueId.
38 */
39 virtual void RunTasks(const BASE_NS::Uid& queueId) = 0;
40 };
41
42 class StartableObjectController
43 : public META_NS::MetaObjectFwd<StartableObjectController, ClassId::StartableObjectController, ClassId::MetaObject,
44 IStartableController, IObjectHierarchyObserver, IStartableObjectControllerInternal, ITickableController> {
45 public: // ILifeCycle
46 bool Build(const IMetadata::Ptr& data) override;
47 void Destroy() override;
48
49 public: // IStartableController
50 META_IMPLEMENT_INTERFACE_PROPERTY(
51 IStartableController, META_NS::TraversalType, TraversalType, META_NS::TraversalType::DEPTH_FIRST_POST_ORDER)
52 META_IMPLEMENT_INTERFACE_PROPERTY(
53 IStartableController, META_NS::StartBehavior, StartBehavior, META_NS::StartBehavior::AUTOMATIC)
54 bool StartAll(ControlBehavior behavior) override;
55 bool StopAll(ControlBehavior behavior) override;
56 BASE_NS::vector<IStartable::Ptr> GetAllStartables() const override;
57 bool SetStartableQueueId(
58 const BASE_NS::Uid& startStartableQueueId, const BASE_NS::Uid& stopStartableQueueId) override;
59
60 public: // IObjectHierarchyObserver
61 void SetTarget(const IObject::Ptr& root, HierarchyChangeModeValue mode) override;
62 IObject::Ptr GetTarget() const override;
63 BASE_NS::vector<IObject::Ptr> GetAllObserved() const override;
64 META_FORWARD_EVENT(IOnHierarchyChanged, OnHierarchyChanged, observer_->EventOnHierarchyChanged())
65
66 public: // ITickableController
67 BASE_NS::vector<ITickable::Ptr> GetTickables() const override;
68 void TickAll(const TimeSpan& time) override;
69 META_IMPLEMENT_INTERFACE_PROPERTY(
70 ITickableController, META_NS::TimeSpan, TickInterval, META_NS::TimeSpan::Infinite())
71 META_IMPLEMENT_INTERFACE_PROPERTY(
72 ITickableController, META_NS::TraversalType, TickOrder, META_NS::TraversalType::DEPTH_FIRST_PRE_ORDER)
73 bool SetTickableQueueuId(const BASE_NS::Uid& queueId) override;
74
75 private:
76 void StartHierarchy(const IObject::Ptr& root, ControlBehavior behavior);
77 void StopHierarchy(const IObject::Ptr& root, ControlBehavior behavior);
78 void StartStartable(IStartable* const startable, ControlBehavior behavior);
79 void StopStartable(IStartable* const startable, ControlBehavior behavior);
80 void HierarchyChanged(const HierarchyChangedInfo& info);
81
82 IObject::WeakPtr target_;
83 IObjectHierarchyObserver::Ptr observer_;
84
85 private: // IStartableObjectControllerInternal
86 void RunTasks(const BASE_NS::Uid& queueId) override;
87
88 private: // Task queue handling
89 struct StartableOperation {
90 enum Operation {
91 /** Run StartHierarchy() for root_ */
92 START,
93 /** Run StopHierarchy() for root_ */
94 STOP,
95 };
96
97 Operation operation_;
98 IObject::WeakPtr root_;
99 };
100
101 BASE_NS::Uid startQueueId_;
102 BASE_NS::Uid stopQueueId_;
103 bool HasTasks(const BASE_NS::Uid& queueId) const;
104 bool ProcessOps(const BASE_NS::Uid& queueId);
105 bool AddOperation(StartableOperation&& operation, const BASE_NS::Uid& queue);
106 BASE_NS::unordered_map<BASE_NS::Uid, BASE_NS::vector<StartableOperation>> operations_;
107 mutable std::shared_mutex mutex_;
108 std::size_t executingStart_ {};
109
110 private: // Tickables
111 void InvalidateTickables();
112 void UpdateTicker();
113 mutable BASE_NS::vector<ITickable::WeakPtr> tickables_;
114 mutable std::shared_mutex tickMutex_;
115 mutable bool tickablesValid_ { false };
116 TimeSpan lastTick_ { TimeSpan::Infinite() };
117 IClock::Ptr clock_;
118 BASE_NS::Uid tickQueueId_;
119 ITaskQueue::Ptr tickerQueue_;
120 ITaskQueue::Ptr defaultTickerQueue_;
121 ITaskQueueTask::Ptr tickerTask_;
122 ITaskQueue::Token tickerToken_ {};
123 };
124
125 META_END_NAMESPACE()
126
127 #endif // META_SRC_STARTABLE_OBJECT_CONTROLLER_H
128