1bc03f14fSopenharmony_ci/*
2bc03f14fSopenharmony_ci * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3bc03f14fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4bc03f14fSopenharmony_ci * you may not use this file except in compliance with the License.
5bc03f14fSopenharmony_ci * You may obtain a copy of the License at
6bc03f14fSopenharmony_ci *
7bc03f14fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8bc03f14fSopenharmony_ci *
9bc03f14fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10bc03f14fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11bc03f14fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12bc03f14fSopenharmony_ci * See the License for the specific language governing permissions and
13bc03f14fSopenharmony_ci * limitations under the License.
14bc03f14fSopenharmony_ci */
15bc03f14fSopenharmony_ci#ifndef PASTEBOARD_ASYNC_CALL_H
16bc03f14fSopenharmony_ci#define PASTEBOARD_ASYNC_CALL_H
17bc03f14fSopenharmony_ci
18bc03f14fSopenharmony_ci#include <functional>
19bc03f14fSopenharmony_ci#include <memory>
20bc03f14fSopenharmony_ci#include <string>
21bc03f14fSopenharmony_ci
22bc03f14fSopenharmony_ci#include "napi/native_api.h"
23bc03f14fSopenharmony_ci#include "napi/native_common.h"
24bc03f14fSopenharmony_ci#include "napi/native_node_api.h"
25bc03f14fSopenharmony_ci
26bc03f14fSopenharmony_cinamespace OHOS::MiscServicesNapi {
27bc03f14fSopenharmony_ciclass AsyncCall final {
28bc03f14fSopenharmony_cipublic:
29bc03f14fSopenharmony_ci    class Context {
30bc03f14fSopenharmony_ci    public:
31bc03f14fSopenharmony_ci        using InputAction = std::function<napi_status(napi_env, size_t, napi_value *, napi_value)>;
32bc03f14fSopenharmony_ci        using OutputAction = std::function<napi_status(napi_env, napi_value *)>;
33bc03f14fSopenharmony_ci        using ExecAction = std::function<void(Context *)>;
34bc03f14fSopenharmony_ci        Context(){};
35bc03f14fSopenharmony_ci        Context(InputAction input, OutputAction output) : input_(std::move(input)), output_(std::move(output)){};
36bc03f14fSopenharmony_ci        virtual ~Context(){};
37bc03f14fSopenharmony_ci        void SetAction(InputAction input, OutputAction output = nullptr)
38bc03f14fSopenharmony_ci        {
39bc03f14fSopenharmony_ci            input_ = input;
40bc03f14fSopenharmony_ci            output_ = output;
41bc03f14fSopenharmony_ci        }
42bc03f14fSopenharmony_ci
43bc03f14fSopenharmony_ci        void SetAction(OutputAction output)
44bc03f14fSopenharmony_ci        {
45bc03f14fSopenharmony_ci            SetAction(nullptr, std::move(output));
46bc03f14fSopenharmony_ci        }
47bc03f14fSopenharmony_ci
48bc03f14fSopenharmony_ci        void SetErrInfo(int32_t errCode, std::string errMsg)
49bc03f14fSopenharmony_ci        {
50bc03f14fSopenharmony_ci            errCode_ = errCode;
51bc03f14fSopenharmony_ci            errMsg_ = errMsg;
52bc03f14fSopenharmony_ci        }
53bc03f14fSopenharmony_ci
54bc03f14fSopenharmony_ci        virtual napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self)
55bc03f14fSopenharmony_ci        {
56bc03f14fSopenharmony_ci            if (input_ == nullptr) {
57bc03f14fSopenharmony_ci                return napi_ok;
58bc03f14fSopenharmony_ci            }
59bc03f14fSopenharmony_ci            auto ret = input_(env, argc, argv, self);
60bc03f14fSopenharmony_ci            input_ = nullptr;
61bc03f14fSopenharmony_ci            return ret;
62bc03f14fSopenharmony_ci        }
63bc03f14fSopenharmony_ci
64bc03f14fSopenharmony_ci        virtual napi_status operator()(napi_env env, napi_value *result)
65bc03f14fSopenharmony_ci        {
66bc03f14fSopenharmony_ci            if (output_ == nullptr) {
67bc03f14fSopenharmony_ci                *result = nullptr;
68bc03f14fSopenharmony_ci                return napi_ok;
69bc03f14fSopenharmony_ci            }
70bc03f14fSopenharmony_ci            auto ret = output_(env, result);
71bc03f14fSopenharmony_ci            output_ = nullptr;
72bc03f14fSopenharmony_ci            return ret;
73bc03f14fSopenharmony_ci        }
74bc03f14fSopenharmony_ci
75bc03f14fSopenharmony_ci        virtual void Exec()
76bc03f14fSopenharmony_ci        {
77bc03f14fSopenharmony_ci            if (exec_ == nullptr) {
78bc03f14fSopenharmony_ci                return;
79bc03f14fSopenharmony_ci            }
80bc03f14fSopenharmony_ci            exec_(this);
81bc03f14fSopenharmony_ci            exec_ = nullptr;
82bc03f14fSopenharmony_ci        };
83bc03f14fSopenharmony_ci
84bc03f14fSopenharmony_ci    protected:
85bc03f14fSopenharmony_ci        friend class AsyncCall;
86bc03f14fSopenharmony_ci        InputAction input_ = nullptr;
87bc03f14fSopenharmony_ci        OutputAction output_ = nullptr;
88bc03f14fSopenharmony_ci        ExecAction exec_ = nullptr;
89bc03f14fSopenharmony_ci        int32_t errCode_ = 0;
90bc03f14fSopenharmony_ci        std::string errMsg_;
91bc03f14fSopenharmony_ci    };
92bc03f14fSopenharmony_ci
93bc03f14fSopenharmony_ci    // The default AsyncCallback in the parameters is at the end position.
94bc03f14fSopenharmony_ci    static constexpr size_t ASYNC_DEFAULT_POS = -1;
95bc03f14fSopenharmony_ci    AsyncCall(napi_env env, napi_callback_info info, std::shared_ptr<Context> context, size_t pos = ASYNC_DEFAULT_POS);
96bc03f14fSopenharmony_ci    ~AsyncCall();
97bc03f14fSopenharmony_ci    napi_value Call(napi_env env, Context::ExecAction exec = nullptr);
98bc03f14fSopenharmony_ci    napi_value SyncCall(napi_env env, Context::ExecAction exec = nullptr);
99bc03f14fSopenharmony_ci
100bc03f14fSopenharmony_ciprivate:
101bc03f14fSopenharmony_ci    enum arg : int { ARG_ERROR, ARG_DATA, ARG_BUTT };
102bc03f14fSopenharmony_ci    static void OnExecute(napi_env env, void *data);
103bc03f14fSopenharmony_ci    static void OnComplete(napi_env env, napi_status status, void *data);
104bc03f14fSopenharmony_ci    struct AsyncContext {
105bc03f14fSopenharmony_ci        std::shared_ptr<Context> ctx = nullptr;
106bc03f14fSopenharmony_ci        napi_ref callback = nullptr;
107bc03f14fSopenharmony_ci        napi_ref self = nullptr;
108bc03f14fSopenharmony_ci        napi_deferred defer = nullptr;
109bc03f14fSopenharmony_ci        napi_async_work work = nullptr;
110bc03f14fSopenharmony_ci    };
111bc03f14fSopenharmony_ci    static void DeleteContext(napi_env env, AsyncContext *context);
112bc03f14fSopenharmony_ci
113bc03f14fSopenharmony_ci    AsyncContext *context_ = nullptr;
114bc03f14fSopenharmony_ci    napi_env env_ = nullptr;
115bc03f14fSopenharmony_ci};
116bc03f14fSopenharmony_ci} // namespace OHOS::MiscServicesNapi
117bc03f14fSopenharmony_ci
118bc03f14fSopenharmony_ci#endif // PASTEBOARD_ASYNC_CALL_H
119bc03f14fSopenharmony_ci       // namespace OHOS