fix(eeschema): collab move carries the symbol/label text fields along
After the body-move devirtualization, moving a symbol synced the body to the peer but left its reference/value text behind: SCH_SYMBOL::Move()/SCH_LABEL_BASE::Move() move the child fields via an inner virtual field.Move() that also mis-dispatches in the apply context. Move the fields explicitly with a devirtualized SCH_FIELD::Move (moveFields). Verified: a moved symbol's text label now follows the body on the peer. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2d1d7c4681
commit
6bd17aeb26
1 changed files with 26 additions and 3 deletions
|
|
@ -30,6 +30,7 @@
|
|||
#include <sch_text.h>
|
||||
#include <sch_label.h>
|
||||
#include <sch_symbol.h>
|
||||
#include <sch_field.h>
|
||||
#include <sch_shape.h>
|
||||
#include <eda_shape.h>
|
||||
#include <stroke_params.h>
|
||||
|
|
@ -330,13 +331,25 @@ SCHEMATIC* ensureBridge()
|
|||
|
||||
namespace {
|
||||
|
||||
// SCH_SYMBOL::Move() / SCH_LABEL_BASE::Move() move their child fields (reference, value, …) via
|
||||
// an inner `field.Move()` — itself a virtual call that mis-dispatches in the apply context, so
|
||||
// the field text is left behind at its old position while the body moves. Re-move the fields
|
||||
// with a devirtualized call so the labels follow the symbol on the peer. (The inner call is a
|
||||
// harmless no-op when it mis-dispatches — the fields stay put — so this doesn't double-move.)
|
||||
void moveFields( std::vector<SCH_FIELD>& aFields, const VECTOR2I& aDelta )
|
||||
{
|
||||
for( SCH_FIELD& field : aFields )
|
||||
field.SCH_FIELD::Move( aDelta );
|
||||
}
|
||||
|
||||
// Move an item to an absolute position for the `changed` path. SCH_ITEM::Move() is virtual;
|
||||
// dispatching it through the vtable from the apply/CallAfter context hits the asyncify
|
||||
// call_indirect mis-dispatch and silently NO-OPS (so symbols/junctions/labels never moved on
|
||||
// the peer — only SCH_LINE worked, via its direct SetStart/EndPoint path). GetPosition() reads
|
||||
// fine (it's a plain virtual read; see 0003 / eeschema_collab_asyncify_apply). The fix:
|
||||
// devirtualize Move() with an explicit class-qualified call, which is statically bound — a
|
||||
// plain wasm `call`, not an instrumented call_indirect — so it actually executes.
|
||||
// plain wasm `call`, not an instrumented call_indirect — so it actually executes. Composite
|
||||
// items additionally need their child fields moved (see moveFields).
|
||||
void moveItemTo( SCH_ITEM* aItem, const VECTOR2I& aNewPos )
|
||||
{
|
||||
VECTOR2I delta = aNewPos - aItem->GetPosition();
|
||||
|
|
@ -346,15 +359,25 @@ void moveItemTo( SCH_ITEM* aItem, const VECTOR2I& aNewPos )
|
|||
|
||||
switch( aItem->Type() )
|
||||
{
|
||||
case SCH_SYMBOL_T: static_cast<SCH_SYMBOL*>( aItem )->SCH_SYMBOL::Move( delta ); break;
|
||||
case SCH_SYMBOL_T:
|
||||
{
|
||||
auto* sym = static_cast<SCH_SYMBOL*>( aItem );
|
||||
sym->SCH_SYMBOL::Move( delta );
|
||||
moveFields( sym->GetFields(), delta );
|
||||
break;
|
||||
}
|
||||
case SCH_JUNCTION_T: static_cast<SCH_JUNCTION*>( aItem )->SCH_JUNCTION::Move( delta ); break;
|
||||
case SCH_NO_CONNECT_T: static_cast<SCH_NO_CONNECT*>( aItem )->SCH_NO_CONNECT::Move( delta ); break;
|
||||
case SCH_TEXT_T: static_cast<SCH_TEXT*>( aItem )->SCH_TEXT::Move( delta ); break;
|
||||
case SCH_LABEL_T:
|
||||
case SCH_GLOBAL_LABEL_T:
|
||||
case SCH_HIER_LABEL_T:
|
||||
static_cast<SCH_LABEL_BASE*>( aItem )->SCH_LABEL_BASE::Move( delta );
|
||||
{
|
||||
auto* lbl = static_cast<SCH_LABEL_BASE*>( aItem );
|
||||
lbl->SCH_LABEL_BASE::Move( delta );
|
||||
moveFields( lbl->GetFields(), delta );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
aItem->Move( delta ); // virtual fallback (may no-op in the apply context)
|
||||
break;
|
||||
|
|
|
|||
Loading…
Reference in a new issue