Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore/Audacity CLA applies
4 : *
5 : * Copyright (C) MuseScore/Audacity and others
6 : *
7 : * This program is free software: you can redistribute it and/or modify
8 : * it under the terms of the GNU General Public License version 3 as
9 : * published by the Free Software Foundation.
10 : *
11 : * This program is distributed in the hope that it will be useful,
12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : * GNU General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU General Public License
17 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 : */
19 :
20 : #pragma once
21 :
22 : #include <memory>
23 :
24 : #include "commandtypes.h"
25 : #include "icommanddispatcher.h"
26 : #include "actions/actiontypes.h"
27 : #include "actions/iactionsdispatcher.h"
28 :
29 : //! NOTE compat action to command convertor
30 : /**
31 : * Example:
32 : {
33 : static const std::vector<ActionToCommand> actionToCommand = {
34 : { "file-new", NEW_PROJECT_COMMAND, {} }, // no args - no convertor
35 : { "file-save-at", PROJECT_SAVE_AT_COMMAND, make_conv({ { "path", param<io::path_t> } }) }, // general converotor
36 : { "file-open", OPEN_PROJECT_COMMAND, openArgs }, // custom convertor
37 :
38 : };
39 :
40 : rcommand::registerActionToCommand(this, actionToCommand, commandDispatcher(), dispatcher());
41 : }
42 : */
43 :
44 : namespace muse::rcommand {
45 : template<typename T>
46 0 : constexpr auto param = [](const actions::ActionData& args, int index) -> Val {
47 0 : return Val(args.arg<T>(index));
48 : };
49 :
50 : struct ParamSpec {
51 : std::string name;
52 : std::function<Val(const actions::ActionData&, int)> param;
53 : };
54 :
55 : using Convertor = std::function<muse::rcommand::CommandQuery (const rcommand::Command&, const actions::ActionData&)>;
56 : struct ActionToCommand {
57 : actions::ActionCode actionCode;
58 : muse::rcommand::Command command;
59 : Convertor convertor;
60 : };
61 :
62 0 : static inline Convertor make_conv(const std::vector<ParamSpec>& specs)
63 : {
64 0 : return [specs](const rcommand::Command& command, const actions::ActionData& args) -> muse::rcommand::CommandQuery {
65 0 : muse::rcommand::CommandQuery query(command);
66 0 : if (args.empty()) {
67 0 : return query;
68 : }
69 :
70 0 : IF_ASSERT_FAILED(args.count() <= static_cast<int>(specs.size())) {
71 0 : return query;
72 : }
73 :
74 0 : for (int i = 0; i < args.count(); ++i) {
75 0 : query.set(specs[i].name, specs[i].param(args, i));
76 : }
77 0 : return query;
78 0 : };
79 : }
80 :
81 0 : static inline void registerActionToCommand(actions::Actionable* actionable,
82 : const std::vector<ActionToCommand>& actionToCommand,
83 : std::shared_ptr<ICommandDispatcher> cd,
84 : std::shared_ptr<actions::IActionsDispatcher> ad)
85 : {
86 0 : for (const auto& atc : actionToCommand) {
87 0 : ad->reg(actionable, atc.actionCode, [cd, atc](const actions::ActionData& args) {
88 0 : if (atc.convertor) {
89 0 : return cd->dispatch(atc.convertor(atc.command, args));
90 : }
91 0 : return cd->dispatch(atc.command);
92 : });
93 : }
94 0 : }
95 : }
|