Extract duplicate into core; support it in the script engine + wx GUI

A script using `duplicate` failed with "unsupported command 'duplicate'"
because the clone logic was still inline in the tui command. Extract it to
core/app/edit.hpp::duplicate_module(System*, src, dst) -> {ok, error, parts,
signals}: a deep clone of a module (parts, pins with spec + nc_origin, signals
with type overrides, pin→signal wiring; no connections), refusing on an unknown
source or an already-taken destination name.

  - the tui `duplicate` command renders the result (output unchanged);
  - the script engine dispatches `duplicate` to it — the failing script now runs;
  - the wx GUI gains Edit ▸ Duplicate module… (PickModule + a name prompt).

tests/test_edit.cpp: deep clone wires to the clone's own signal (not the
source's) and preserves the type; unknown source / existing destination
refused. 412 core assertions green; tui + wx build clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-03 22:04:45 +02:00
parent 794430e86c
commit c2b1f4c4ae
7 changed files with 155 additions and 44 deletions

View File

@@ -7,6 +7,7 @@
class Part;
class Signal;
class System;
// Application layer: UI-independent part-editing operations any frontend can
// call. No console, no dialogs, no FTXUI — Part in, result struct out.
@@ -52,6 +53,21 @@ struct SetSignalTypeResult {
// Fails (ok=false, error set, no mutation) on an unrecognised name.
SetSignalTypeResult set_signal_type(Signal *sig, const std::string &type_name);
// Outcome of cloning a module under a new name.
struct DuplicateResult {
bool ok = false;
std::string error; ///< unknown source, or destination name already taken
int parts = 0;
int signals = 0;
};
// Deep-clone module `src_name` as `dst_name`: parts, pins (spec + nc_origin),
// signals (with type overrides) and the pin→signal wiring — but not the
// system's connections. Fails (ok=false, error set, no change) when the source
// is unknown or the destination name already exists.
DuplicateResult duplicate_module(System *sys, const std::string &src_name,
const std::string &dst_name);
} // namespace app
#endif // _APP_EDIT_HPP_