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