1/*
2 * Copyright (c) 2021 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 DFSU_CMD_H
17#define DFSU_CMD_H
18
19#include <functional>
20
21#include "dfsu_exception.h"
22
23namespace OHOS {
24namespace Storage {
25namespace DistributedFile {
26enum class CmdImportance {
27    // If it fails(even has tried multiple times), shutdown the actor.
28    VITAL,
29
30    SUBVITAL,
31    // If it fails(even has tried multiple times), reboot the actor.
32    NORMAL,
33
34    // If it fails(may also try multiple times), just do nothing.
35    TRIVIAL,
36};
37
38struct CmdOptions {
39    CmdImportance importance_ { CmdImportance::TRIVIAL };
40    uint32_t tryTimes_ {1};
41};
42
43template<typename T>
44class DfsuActor;
45
46template<typename Ctx>
47class VirtualCmd {
48    friend class DfsuActor<Ctx>;
49
50public:
51    VirtualCmd() = default;
52    virtual ~VirtualCmd() = default;
53    virtual void operator()(Ctx *ctx) = 0;
54
55    void UpdateOption(CmdOptions op)
56    {
57        option_ = op;
58    }
59
60protected:
61    CmdOptions option_;
62};
63
64template<typename Ctx, typename... Args>
65class DfsuCmd : public VirtualCmd<Ctx> {
66    friend class DfsuActor<Ctx>;
67
68public:
69    DfsuCmd(void (Ctx::*f)(Args...), Args... args) : f_(f), args_(args...) {}
70    ~DfsuCmd() override = default;
71
72private:
73    void (Ctx::*f_)(Args...);
74    std::tuple<Args...> args_;
75
76    void operator()(Ctx *ctx) override
77    {
78        if (!VirtualCmd<Ctx>::option_.tryTimes_) {
79            ThrowException(ERR_UTILS_ACTOR_INVALID_CMD, "Cannot execute a command that has 0 try times");
80        }
81
82        VirtualCmd<Ctx>::option_.tryTimes_--;
83        std::apply(f_, std::tuple_cat(std::make_tuple(ctx), args_));
84    }
85};
86} // namespace DistributedFile
87} // namespace Storage
88} // namespace OHOS
89#endif // DFSU_CMD_H