Files
essim/src/core/app/connect.hpp
François a040cc1957 Extract connect into core (app::connect_parts); thin the command + screen.
Move the wiring orchestration — transform lookup, identity-compatibility
check, identity NC fill, transform apply, Connection creation/add — out of
the `connect` command and the interactive connect screen into
core/app/connect.{hpp,cpp}: app::connect_parts(System*, m1,p1, m2,p2) returns
a ConnectResult (ok/refused/error, connection_name, transform_name, wires,
identity_info, nc_added) with no Print/dialog/FTXUI. Name/pattern resolution
and ambiguity reporting stay in the command — that is arg-parsing, not the op.

Both frontends now call the one core op, removing the duplicated logic. This
also unifies a divergence: the interactive screen previously called
CheckIdentityCompatible without the info pointer and so never filled identity
NC pins (unlike the command); routing it through app::connect_parts makes the
screen fill NCs and surface the same warning, matching the scriptable path.

Command output is unchanged. Prune the now-dead transform.hpp / domain
connect.hpp includes from the frontends (commands.cpp keeps transform_vpx.hpp
only for ValidatePartForKind).

Add tests/test_connect.cpp (core, no UI): identity-compatible pair wires,
unknown type pairing is refused with nothing created, subset side gets NC
pins filled and the warning reported.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 20:12:11 +02:00

43 lines
1.6 KiB
C++

#ifndef _APP_CONNECT_HPP_
#define _APP_CONNECT_HPP_
#include <string>
class System;
class Module;
class Part;
// Application layer: UI-independent operations that any frontend (TUI, GUI, …)
// can call. No console, no dialogs, no FTXUI — just System in, result out.
namespace app {
// Outcome of connecting two parts. The side effects (filling identity NC pins,
// creating the Connection and adding it to the system) all happen in core; the
// caller only renders the fields.
struct ConnectResult {
bool ok = false; ///< a Connection was created and added
bool refused = false; ///< a business rule rejected it (vs. an exception)
std::string error; ///< why refused/failed; empty when ok
std::string connection_name;
std::string transform_name;
int wires = 0; ///< pin_map size of the created connection
// Identity-transform path only: the compatibility info line and how many NC
// pins were materialised so both sides match. Empty / 0 otherwise.
std::string identity_info;
int nc_added = 0;
};
// Wire part `p1` (in module `m1`) to part `p2` (in module `m2`): look up the
// transform for their connector types, refuse on an unknown pairing or an
// identity-incompatible layout, fill identity NC pins when needed, apply the
// transform and create the Connection. Pure core — no resolution of names or
// patterns (the frontend turns user input into the Module*/Part* it passes).
ConnectResult connect_parts(System *sys, Module *m1, Part *p1,
Module *m2, Part *p2);
} // namespace app
#endif // _APP_CONNECT_HPP_