feat: ysync 0008 Stage D — wire the v2 items collab into the app + verify
- WasmTool: hard cutover to startKicadCollab (gates on kicadCollabSnapshotItems; scalar reconciler no longer runs in the app) - file-seed (ysync 0005 tie-in): empty rooms are seeded from the opened file via fileToDoc/docToY (meta+layout+items — file recoverable from the Y.Doc alone); populated rooms still adopt (seed-once unchanged) - binding: gate UP applies until seed() — the provider's initial state sync otherwise streams the full doc into an editor that already holds the file (trapped eeschema's paste path in the real app) - pcbnew blobForItem: footprints Format a uuid-corrected copy directly — SaveSelection's copy regenerated mandatory-field uuids (FOOTPRINT copy ctor assigns into fresh fields), breaking wire identity (rebuild) - roundtrip.spec on the v2 items wire; new passing pcbnew footprint-containment round trip (the 0004 containment win); full fixture stays fixme on the tracked envelope-parse limit - real-app two-tab emit verified for eeschema + pcbnew (see 0008 doc) Full kicad suite: 45 passed, 3 skipped (known), 0 failed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3a06a267b0
commit
07863da416
7 changed files with 273 additions and 46 deletions
|
|
@ -26,6 +26,8 @@
|
|||
#include <eda_text.h>
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <kicad_clipboard.h>
|
||||
#include <io/kicad/kicad_io_utils.h>
|
||||
#include <richio.h>
|
||||
#include <tools/pcb_selection.h>
|
||||
#include <geometry/shape_poly_set.h>
|
||||
#include <geometry/shape_line_chain.h>
|
||||
|
|
@ -253,8 +255,52 @@ json itemToJson( BOARD_ITEM* aItem )
|
|||
|
||||
// Serialize one live board item to a clipboard blob (used only for `added` payloads — NOT the
|
||||
// diff unit, so `changed`/`removed` stay light and the blob never drives change detection).
|
||||
//
|
||||
// Footprints DON'T go through SaveSelection: its "make safe to transfer" step copies the
|
||||
// footprint, and FOOTPRINT's copy ctor ASSIGNS the mandatory fields into the new footprint's
|
||||
// freshly-constructed ones (`*existingField = *field`; EDA_ITEM::operator= keeps the target's
|
||||
// uuid) — so Reference/Value/Datasheet/Description would carry NEW uuids in every blob,
|
||||
// breaking the wire's identity-by-uuid (every emit would read as field remove+add, and round
|
||||
// trips lose the field uuids). Instead we make the same safety copy ourselves, RESTORE the
|
||||
// mandatory-field uuids from the source, and Format it directly — the same Format machinery
|
||||
// SaveSelection uses internally, so asyncify behavior is identical.
|
||||
std::string blobForItem( BOARD* aBoard, BOARD_ITEM* aItem )
|
||||
{
|
||||
if( aItem->Type() == PCB_FOOTPRINT_T )
|
||||
{
|
||||
const FOOTPRINT* src = static_cast<const FOOTPRINT*>( aItem );
|
||||
FOOTPRINT copy( *src );
|
||||
|
||||
for( PCB_FIELD* field : copy.GetFields() )
|
||||
{
|
||||
if( field->IsMandatory() )
|
||||
{
|
||||
if( const PCB_FIELD* srcField = src->GetField( field->GetId() ) )
|
||||
const_cast<KIID&>( field->m_Uuid ) = srcField->m_Uuid;
|
||||
}
|
||||
}
|
||||
|
||||
// The rest of SaveSelection's footprint safety steps, minus the refPoint move
|
||||
// (the wire carries absolute positions).
|
||||
for( PAD* pad : copy.Pads() )
|
||||
pad->SetNetCode( 0 );
|
||||
|
||||
copy.SetLocked( false );
|
||||
|
||||
CLIPBOARD_IO io;
|
||||
STRING_FORMATTER fmt;
|
||||
io.SetBoard( aBoard );
|
||||
io.SetOutputFormatter( &fmt );
|
||||
io.Format( © );
|
||||
|
||||
copy.SetParent( nullptr );
|
||||
copy.SetParentGroup( nullptr );
|
||||
|
||||
std::string out = fmt.GetString();
|
||||
KICAD_FORMAT::Prettify( out, KICAD_FORMAT::FORMAT_MODE::COMPACT_TEXT_PROPERTIES );
|
||||
return out;
|
||||
}
|
||||
|
||||
PCB_SELECTION sel;
|
||||
sel.Add( aItem ); // pointer-only insert; no mutation of the live item
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue