1/*
2 * Copyright (c) 2021-2022 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 OHOS_WM_INCLUDE_FUTURE_H
17#define OHOS_WM_INCLUDE_FUTURE_H
18
19#include <condition_variable>
20#include "hilog/log.h"
21#include "window_manager_hilog.h"
22
23namespace OHOS::Rosen {
24template<class T>
25class Future {
26    constexpr static HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "Future"};
27public:
28    T GetResult(long timeOut)
29    {
30        std::unique_lock <std::mutex> lock(mutex_);
31        if (!conditionVariable_.wait_for(lock, std::chrono::milliseconds(timeOut), [this] { return IsReady(); })) {
32            OHOS::HiviewDFX::HiLog::Error(LABEL, "wait for %{public}ld, timeout.", timeOut);
33        }
34        return FetchResult();
35    }
36
37protected:
38    virtual bool IsReady() = 0;
39
40    virtual T FetchResult() = 0;
41
42    virtual void Call(T) = 0;
43
44    void FutureCall(T t)
45    {
46        std::unique_lock <std::mutex> lock(mutex_);
47        Call(t);
48        conditionVariable_.notify_one();
49    }
50
51    std::mutex mutex_;
52
53private:
54    std::condition_variable conditionVariable_;
55};
56
57template<class T>
58class RunnableFuture : public Future<T> {
59public:
60    void SetValue(T res)
61    {
62        Future<T>::FutureCall(res);
63    }
64    void Reset(T defaultValue)
65    {
66        flag_ = false;
67        result_ = defaultValue;
68    }
69    void ResetLock(T defaultValue)
70    {
71        std::unique_lock <std::mutex> lock(Future<T>::mutex_);
72        flag_ = false;
73        result_ = defaultValue;
74    }
75protected:
76    void Call(T res) override
77    {
78        if (!flag_) {
79            flag_ = true;
80            result_ = res;
81        }
82    }
83    bool IsReady() override
84    {
85        return flag_;
86    }
87    T FetchResult() override
88    {
89        return result_;
90    }
91private:
92    bool flag_ {false};
93    T result_;
94};
95} // namespace OHOS::Rosen
96#endif // OHOS_WM_INCLUDE_FUTURE_H
97