Skip to content

Fix joined ravels not synchronizing state when joining existing lock groups - #570

Merged
highperformancecoder merged 5 commits into
masterfrom
copilot/fix-joined-ravels-functionality
Oct 8, 2025
Merged

highperformancecoder merged 5 commits into
masterfrom
copilot/fix-joined-ravels-functionality

Conversation

Copilot AI commented Oct 8, 2025 •

Copy link
Copy Markdown
Contributor
  • Analyzed the issue - "Joined Ravels not working" (SourceForge ticket #1879)
  • Identified root cause: Ravel::joinLockGroup() doesn't call initialBroadcast() after adding ravel to lock group
  • Fixed by adding lockGroup->initialBroadcast() call in joinLockGroup() method (line 596 in model/ravelWrap.cc)
  • Updated test to properly call joinLockGroup() method and verify state synchronization with calipers
  • Verified fix follows same pattern as Canvas::lockRavelsInSelection()

Summary

The issue was that when a Ravel joins an existing lock group via the context menu (using joinLockGroup()), the state from that lock group was not being broadcast to the newly joined ravel. This meant the ravel would join the group but not synchronize its state with the other ravels in the group.

The fix adds a single line calling initialBroadcast() after adding the ravel to the lock group, which propagates the group's state to all members including the newly joined ravel. This matches the behavior of lockRavelsInSelection() which already calls initialBroadcast() after creating/updating lock groups.

The test now:

  1. Adds ravels to the model so joinLockGroup() can find them
  2. Creates a lock group with one ravel and sets caliper state on it
  3. Calls joinLockGroup() on the second ravel to join the group
  4. Verifies both ravels are in the same group AND that the state was synchronized by checking caliper settings match
Original prompt

This section details on the original issue you should resolve

<issue_title>Joined Ravels not working</issue_title>
<issue_description>See https://sourceforge.net/p/minsky/tickets/1879/</issue_description>

Comments on the Issue (you are @copilot in this section)

Fixes #569

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.


This change is Reviewable

Summary by CodeRabbit

  • Bug Fixes

    • Joining a lock group now immediately syncs the group's initial state to the joining item, ensuring consistent display filters and label ranges across grouped items.
  • Tests

    • Added a test verifying that when an item joins a lock group, the existing item's caliper/display state is broadcast and applied to the joining item.

@coderabbitai

coderabbitai Bot commented Oct 8, 2025 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds an initialBroadcast() call when a ravel joins a RavelLockGroup so the group's current state is propagated to the newly joined ravel. Adds a test verifying two registered ravels share the lock group and that caliper-related state is broadcast on join.

Changes

Cohort / File(s) Summary
Model: lock group broadcast on join
model/ravelWrap.cc
After associating a ravel with an existing lock group in join, invoke initialBroadcast() so the group’s current state is propagated to all ravels, including the newly joined one.
Tests: lock group join broadcast
test/testLockGroup.cc
Adds JoinLockGroupBroadcast test: creates two registered ravels, establishes a lock group on the first, applies caliper-related state to it, has the second join the group, and asserts both share the group, group size becomes 2, and the second receives the first's caliper state. Introduces Minsky and LocalMinsky members in the test fixture for model registration/setup.

Sequence Diagram(s)

sequenceDiagram
  participant Test
  participant Model
  participant RavelA
  participant RavelB
  participant LockGroup

  Test->>Model: create & register RavelA
  Test->>Model: create & register RavelB
  Test->>RavelA: create lock group (colour)
  RavelA->>LockGroup: associate (create)

  Test->>RavelA: set caliper/state
  Note right of LockGroup: LockGroup holds current state

  Test->>RavelB: joinLockGroup(colour)
  RavelB->>LockGroup: associate with existing group
  LockGroup->>LockGroup: initialBroadcast()
  LockGroup-->>RavelB: sync caliper/state
  LockGroup-->>RavelA: (no-op or confirm)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

A rabbit hops between two threads,
I stitch their states with gentle threads.
A broadcast bloom, a synchronized beat,
Two ravels meet—calipers complete.
I nibble code and give a cheer, hooray! 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly identifies the core fix by noting that joined ravels will now synchronize their state when joining existing lock groups, which directly reflects the added initialBroadcast call in joinLockGroup.
Linked Issues Check ✅ Passed The changes in model/ravelWrap.cc add the required initialBroadcast call in joinLockGroup to propagate state and the new test validates that ravels receive the lock group state upon joining, fully addressing issue #569.
Out of Scope Changes Check ✅ Passed All modifications strictly implement and test the state synchronization feature for joinLockGroup and there are no unrelated or extraneous changes outside the scope of issue #569.

Comment @coderabbitai help to get the list of available commands and usage tips.

Co-authored-by: highperformancecoder <3075825+highperformancecoder@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix joined ravels functionality not working Fix joined ravels not synchronizing state when joining existing lock groups Oct 8, 2025
Comment thread test/testLockGroup.cc Outdated

// Verify both ravels are in the same lock group
EXPECT_TRUE(a->lockGroup==b->lockGroup);
EXPECT_EQ(2, lockGroup->ravels().size());

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test does not exercise the joinLockGroup method, nor does it test that the fix works, which would be by setting calipers on one Ravel and checking that the two Ravel states are identical.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the test to actually call joinLockGroup() method and verify state synchronization. The test now:

  1. Adds ravels to the model so joinLockGroup() can find them via recursiveDo
  2. Creates a lock group with ravel a and sets caliper state on it
  3. Calls b->joinLockGroup(colour) to join the existing group
  4. Verifies both group membership and that caliper settings (displayFilterCaliper, minLabel, maxLabel) are synchronized between the ravels

Fixed in commit 72b963e.

…zation

Co-authored-by: highperformancecoder <3075825+highperformancecoder@users.noreply.github.com>
@highperformancecoder

Copy link
Copy Markdown
Owner

@CodeRabbit review

@highperformancecoder
highperformancecoder marked this pull request as ready for review October 8, 2025 03:24
Copilot AI review requested due to automatic review settings October 8, 2025 03:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Fixes a bug where ravels joining existing lock groups via the context menu were not synchronizing their state with other group members. The solution adds a single line to broadcast the lock group's state to all members after a ravel joins.

  • Adds initialBroadcast() call in joinLockGroup() method to synchronize state
  • Updates test to verify state synchronization using caliper settings
  • Ensures consistent behavior with existing lockRavelsInSelection() functionality

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
model/ravelWrap.cc Adds state synchronization call after joining lock group
test/testLockGroup.cc Adds comprehensive test for join functionality and state broadcast

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@coderabbitai

coderabbitai Bot commented Oct 8, 2025

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
test/testLockGroup.cc (1)

99-138: Test correctly verifies the state broadcast fix.

The test properly exercises joinLockGroup() and verifies that caliper state (displayFilterCaliper, minLabel, maxLabel) is synchronized from ravel a to ravel b when b joins the lock group. This addresses the previous review feedback and validates the fix in model/ravelWrap.cc.

Optional: Consider asserting that state was successfully set before the join.

While the current guards (if (!aState.handleStates.empty())) prevent test failures when ravels lack handles, you could add an assertion after line 121 to ensure the test actually exercises the synchronization logic:

// After line 121
ASSERT_FALSE(aState.handleStates.empty()) << "Test requires ravels with handles";

This ensures the test doesn't pass vacuously if ravels unexpectedly have no handles.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c4570ec and 72b963e.

📒 Files selected for processing (2)
  • model/ravelWrap.cc (1 hunks)
  • test/testLockGroup.cc (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: ubuntu-20.04
  • GitHub Check: ubuntu-20.04
  • GitHub Check: ubuntu-20.04
  • GitHub Check: ubuntu-20.04
  • GitHub Check: ubuntu-20.04
  • GitHub Check: ubuntu-20.04
🔇 Additional comments (1)
model/ravelWrap.cc (1)

596-596: LGTM! State synchronization fix is correct.

The addition of initialBroadcast() after adding the ravel to the lock group ensures that the newly joined ravel receives the group's current state (calipers, slice labels, etc.). This follows the same pattern used in Canvas::lockRavelsInSelection() and correctly addresses the issue where joined ravels were not synchronizing state.

@highperformancecoder

Copy link
Copy Markdown
Owner

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Oct 8, 2025

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
test/testLockGroup.cc (1)

134-135: Remove unused variable.

Variable bState is declared on line 134 but never used. Line 135 calls b->getState() directly instead.

Apply this diff to remove the dead code:

-  // Verify state was broadcast - check if b got a's caliper settings
-  auto bState=b->getState();
-  EXPECT_TRUE(b->getState()==aState);
+  // Verify state was broadcast - check if b got a's caliper settings
+  EXPECT_TRUE(b->getState()==aState);

Alternatively, use the variable:

   // Verify state was broadcast - check if b got a's caliper settings
   auto bState=b->getState();
-  EXPECT_TRUE(b->getState()==aState);
+  EXPECT_TRUE(bState==aState);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 72b963e and e392dfb.

📒 Files selected for processing (1)
  • test/testLockGroup.cc (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: ubuntu-20.04
  • GitHub Check: ubuntu-20.04
  • GitHub Check: ubuntu-20.04
  • GitHub Check: ubuntu-20.04
🔇 Additional comments (2)
test/testLockGroup.cc (2)

20-20: LGTM! Fixture changes support model registration.

The include and fixture modifications correctly enable the new test to register ravels with the model, which is necessary for joinLockGroup() to locate them via recursiveDo.

Also applies to: 35-36


99-136: Test correctly verifies the fix.

The test properly exercises joinLockGroup() and validates state synchronization through caliper settings, addressing the previous review feedback. The test structure is sound: it registers ravels with the model, creates a lock group with distinguishable state, calls joinLockGroup(), and verifies both group membership and state broadcast.

@highperformancecoder
highperformancecoder merged commit 71fc9f7 into master Oct 8, 2025
3 of 7 checks passed
@highperformancecoder
highperformancecoder deleted the copilot/fix-joined-ravels-functionality branch October 20, 2025 05:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Joined Ravels not working

3 participants