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