Blender V5.0
blender_cli_command.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
25
26#include <iostream>
27
28#include "BLI_vector.hh"
29
30#include "BKE_blender_cli_command.hh" /* own include */
31
32/* -------------------------------------------------------------------- */
35
36using CommandHandlerPtr = std::unique_ptr<CommandHandler>;
37
43
44static CommandHandler *blender_cli_command_lookup(const std::string &id)
45{
46 for (CommandHandlerPtr &cmd_iter : g_command_handlers) {
47 if (id == cmd_iter->id) {
48 return cmd_iter.get();
49 }
50 }
51 return nullptr;
52}
53
55{
56 int index = 0;
57 for (CommandHandlerPtr &cmd_iter : g_command_handlers) {
58 if (cmd_iter.get() == cmd) {
59 return index;
60 }
61 index++;
62 }
63 return -1;
64}
65
67
68/* -------------------------------------------------------------------- */
71
72void BKE_blender_cli_command_register(std::unique_ptr<CommandHandler> cmd)
73{
74 bool is_duplicate = false;
75 if (CommandHandler *cmd_exists = blender_cli_command_lookup(cmd->id)) {
76 std::cerr << "warning: registered duplicate command \"" << cmd->id
77 << "\", this will be inaccessible" << std::endl;
78 cmd_exists->is_duplicate = true;
79 is_duplicate = true;
80 }
81 cmd->is_duplicate = is_duplicate;
82 g_command_handlers.append(std::move(cmd));
83}
84
86{
87 const int cmd_index = blender_cli_command_index(cmd);
88 if (cmd_index == -1) {
89 std::cerr << "failed to unregister command handler" << std::endl;
90 return false;
91 }
92
93 /* Update duplicates after removal. */
94 if (cmd->is_duplicate) {
95 CommandHandler *cmd_other = nullptr;
96 for (CommandHandlerPtr &cmd_iter : g_command_handlers) {
97 /* Skip self. */
98 if (cmd == cmd_iter.get()) {
99 continue;
100 }
101 if (cmd_iter->is_duplicate && (cmd_iter->id == cmd->id)) {
102 if (cmd_other) {
103 /* Two or more found, clear and break. */
104 cmd_other = nullptr;
105 break;
106 }
107 cmd_other = cmd_iter.get();
108 }
109 }
110 if (cmd_other) {
111 cmd_other->is_duplicate = false;
112 }
113 }
114
115 g_command_handlers.remove_and_reorder(cmd_index);
116
117 return true;
118}
119
120int BKE_blender_cli_command_exec(bContext *C, const char *id, const int argc, const char **argv)
121{
123 if (cmd == nullptr) {
124 std::cerr << "Unrecognized command: \"" << id << "\"" << std::endl;
125 return EXIT_FAILURE;
126 }
127 if (cmd->is_duplicate) {
128 std::cerr << "Command: \"" << id
129 << "\" was registered multiple times, must be resolved, aborting!" << std::endl;
130 return EXIT_FAILURE;
131 }
132
133 return cmd->exec(C, argc, argv);
134}
135
137{
138 /* As `g_command_handlers` isn't ordered, sorting in-place is acceptable. */
139 std::sort(g_command_handlers.begin(),
140 g_command_handlers.end(),
141 [](const CommandHandlerPtr &a, const CommandHandlerPtr &b) { return a->id < b->id; });
142
143 for (int pass = 0; pass < 2; pass++) {
144 std::cout << ((pass == 0) ? "Blender Command Listing:" :
145 "Duplicate Command Listing (ignored):")
146 << std::endl;
147
148 const bool show_duplicates = pass > 0;
149 bool found = false;
150 bool has_duplicate = false;
151 for (CommandHandlerPtr &cmd_iter : g_command_handlers) {
152 if (cmd_iter->is_duplicate) {
153 has_duplicate = true;
154 }
155 if (cmd_iter->is_duplicate != show_duplicates) {
156 continue;
157 }
158
159 std::cout << "\t" << cmd_iter->id << std::endl;
160 found = true;
161 }
162
163 if (!found) {
164 std::cout << "\tNone found" << std::endl;
165 }
166 /* Don't print that no duplicates are found as it's not helpful. */
167 if (pass == 0 && !has_duplicate) {
168 break;
169 }
170 }
171}
172
177
Blender CLI Generic --command Support.
#define C
Definition RandGen.cpp:29
blender::Vector< CommandHandlerPtr > g_command_handlers
int BKE_blender_cli_command_exec(bContext *C, const char *id, const int argc, const char **argv)
std::unique_ptr< CommandHandler > CommandHandlerPtr
void BKE_blender_cli_command_print_help()
static CommandHandler * blender_cli_command_lookup(const std::string &id)
void BKE_blender_cli_command_free_all()
bool BKE_blender_cli_command_unregister(CommandHandler *cmd)
void BKE_blender_cli_command_register(std::unique_ptr< CommandHandler > cmd)
static int blender_cli_command_index(const CommandHandler *cmd)
virtual int exec(struct bContext *C, int argc, const char **argv)=0