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 #ifndef META_INTERFACE_IFUTURE_H
16 #define META_INTERFACE_IFUTURE_H
17 
18 #include <meta/base/interface_macros.h>
19 #include <meta/base/time_span.h>
20 #include <meta/base/types.h>
21 #include <meta/interface/intf_any.h>
22 #include <meta/interface/intf_callable.h>
23 
24 META_BEGIN_NAMESPACE()
25 
26 class ITaskQueue;
27 
28 META_REGISTER_INTERFACE(IFutureContinuation, "5bf12e6d-4a49-4a5a-973c-4352c0095edd")
29 
30 /**
31  * @brief Callable type for future continuation support.
32  */
33 class IFutureContinuation : public META_NS::ICallable {
34     META_INTERFACE(META_NS::ICallable, IFutureContinuation);
35 
36 public:
37     using FunctionType = IAny::Ptr(const IAny::Ptr&);
38 
39     /**
40      * @brief Invokes the continuation with the future's value and returns a new value.
41      */
42     virtual IAny::Ptr Invoke(const IAny::Ptr&) = 0;
43 };
44 
45 META_REGISTER_INTERFACE(IFuture, "0321fd50-8835-422b-aff6-1e090026fb56")
46 
47 /**
48  * @brief Future that lets wait for a result
49  */
50 class IFuture : public CORE_NS::IInterface {
51     META_INTERFACE(CORE_NS::IInterface, IFuture);
52 
53 public:
54     enum StateType {
55         WAITING,   /// There is no result yet and Wait would block
56         COMPLETED, /// There is a result, Wait no longer blocks
57         ABANDONED  /// The underlying task was abandoned, Wait does not block and Get returns nullptr
58     };
59     /**
60      * @brief Returns the current state of the future
61      */
62     virtual StateType GetState() const = 0;
63     /**
64      * @brief Calling Wait will block until unblocked by promise indicating the job was done or abandoned.
65      * Returns state, either Succeeded or Abandoned
66      */
67     virtual StateType Wait() const = 0;
68     /**
69      * @brief Wait for given amount of time. Returns state, which is Waiting if the timeout expired.
70      */
71     virtual StateType WaitFor(const TimeSpan& time) const = 0;
72     /**
73      * @brief Calls internally Wait and returns the result after Wait returns.
74      * Notice that both, abandoning task and void result value, means returning nullptr.
75      */
76     virtual IAny::Ptr GetResult() const = 0;
77     /**
78      * @brief Attach continuation function to the future which is called when there is a result
79      * The continuation function is executed in the given task queue or inline in the same thread as this one if null.
80      */
81     virtual IFuture::Ptr Then(const IFutureContinuation::Ptr& func, const BASE_NS::shared_ptr<ITaskQueue>& queue) = 0;
82     /**
83      * @brief Get the result and try to convert it to given type T. If type mismatch or task was abandoned,
84      * returns the value given.
85      */
86     template<typename T>
GetResultOr(T def)87     T GetResultOr(T def) const
88     {
89         if (auto p = GetResult()) {
90             return GetValue<T>(*p, BASE_NS::move(def));
91         }
92         return BASE_NS::move(def);
93     }
94 
95     /**
96      * @brief Cancel the task. Affects only the immediate future, not continuations.
97      * @note If currently being executed, wait for it to finish.
98      */
99     virtual void Cancel() = 0;
100 };
101 
102 META_REGISTER_INTERFACE(IPromise, "252e664b-76f3-44c7-abc3-6f14aa2d7fd6")
103 
104 META_END_NAMESPACE()
105 
106 META_INTERFACE_TYPE(META_NS::IFuture)
107 
108 #endif
109