Blender V4.3
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
26#include <iostream>
27
28#include "BLI_vector.hh"
29
30#include "BKE_blender_cli_command.hh" /* own include */
31
32#include "MEM_guardedalloc.h"
33
34/* -------------------------------------------------------------------- */
38using CommandHandlerPtr = std::unique_ptr<CommandHandler>;
39
45
46static CommandHandler *blender_cli_command_lookup(const std::string &id)
47{
48 for (CommandHandlerPtr &cmd_iter : g_command_handlers) {
49 if (id == cmd_iter->id) {
50 return cmd_iter.get();
51 }
52 }
53 return nullptr;
54}
55
57{
58 int index = 0;
59 for (CommandHandlerPtr &cmd_iter : g_command_handlers) {
60 if (cmd_iter.get() == cmd) {
61 return index;
62 }
63 index++;
64 }
65 return -1;
66}
67
70/* -------------------------------------------------------------------- */
74void BKE_blender_cli_command_register(std::unique_ptr<CommandHandler> cmd)
75{
76 bool is_duplicate = false;
77 if (CommandHandler *cmd_exists = blender_cli_command_lookup(cmd->id)) {
78 std::cerr << "warning: registered duplicate command \"" << cmd->id
79 << "\", this will be inaccessible" << std::endl;
80 cmd_exists->is_duplicate = true;
81 is_duplicate = true;
82 }
83 cmd->is_duplicate = is_duplicate;
84 g_command_handlers.append(std::move(cmd));
85}
86
88{
89 const int cmd_index = blender_cli_command_index(cmd);
90 if (cmd_index == -1) {
91 std::cerr << "failed to unregister command handler" << std::endl;
92 return false;
93 }
94
95 /* Update duplicates after removal. */
96 if (cmd->is_duplicate) {
97 CommandHandler *cmd_other = nullptr;
98 for (CommandHandlerPtr &cmd_iter : g_command_handlers) {
99 /* Skip self. */
100 if (cmd == cmd_iter.get()) {
101 continue;
102 }
103 if (cmd_iter->is_duplicate && (cmd_iter->id == cmd->id)) {
104 if (cmd_other) {
105 /* Two or more found, clear and break. */
106 cmd_other = nullptr;
107 break;
108 }
109 cmd_other = cmd_iter.get();
110 }
111 }
112 if (cmd_other) {
113 cmd_other->is_duplicate = false;
114 }
115 }
116
117 g_command_handlers.remove_and_reorder(cmd_index);
118
119 return true;
120}
121
122int BKE_blender_cli_command_exec(bContext *C, const char *id, const int argc, const char **argv)
123{
125 if (cmd == nullptr) {
126 std::cerr << "Unrecognized command: \"" << id << "\"" << std::endl;
127 return EXIT_FAILURE;
128 }
129 if (cmd->is_duplicate) {
130 std::cerr << "Command: \"" << id
131 << "\" was registered multiple times, must be resolved, aborting!" << std::endl;
132 return EXIT_FAILURE;
133 }
134
135 return cmd->exec(C, argc, argv);
136}
137
139{
140 /* As this is isn't ordered sorting in-place is acceptable,
141 * sort alphabetically for display purposes only. */
142 std::sort(g_command_handlers.begin(),
143 g_command_handlers.end(),
144 [](const CommandHandlerPtr &a, const CommandHandlerPtr &b) { return a->id < b->id; });
145
146 for (int pass = 0; pass < 2; pass++) {
147 std::cout << ((pass == 0) ? "Blender Command Listing:" :
148 "Duplicate Command Listing (ignored):")
149 << std::endl;
150
151 const bool is_duplicate = pass > 0;
152 bool found = false;
153 bool has_duplicate = false;
154 for (CommandHandlerPtr &cmd_iter : g_command_handlers) {
155 if (cmd_iter->is_duplicate) {
156 has_duplicate = true;
157 }
158 if (cmd_iter->is_duplicate != is_duplicate) {
159 continue;
160 }
161
162 std::cout << "\t" << cmd_iter->id << std::endl;
163 found = true;
164 }
165
166 if (!found) {
167 std::cout << "\tNone found" << std::endl;
168 }
169 /* Don't print that no duplicates are found as it's not helpful. */
170 if (pass == 0 && !has_duplicate) {
171 break;
172 }
173 }
174}
175
180
Blender CLI Generic --command Support.
Read Guarded memory(de)allocation.
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
local_group_size(16, 16) .push_constant(Type b