Synchronise motion systems and update user coordinates. Return true if synced, false if we need to wait longer.
| 5611 | // Synchronise motion systems and update user coordinates. |
| 5612 | // Return true if synced, false if we need to wait longer. |
| 5613 | bool GCodes::SyncWith(GCodeBuffer& thisGb, const GCodeBuffer& otherGb) noexcept |
| 5614 | { |
| 5615 | if (thisGb.ExecutingAll()) |
| 5616 | { |
| 5617 | return LockAllMovementSystemsAndWaitForStandstill(thisGb); |
| 5618 | } |
| 5619 | |
| 5620 | if (!LockMovementSystemAndWaitForStandstill(thisGb, thisGb.GetOwnQueueNumber())) |
| 5621 | { |
| 5622 | return false; |
| 5623 | } |
| 5624 | |
| 5625 | bool synced = false; // assume failure |
| 5626 | switch (thisGb.syncState) |
| 5627 | { |
| 5628 | case GCodeBuffer::SyncState::running: |
| 5629 | thisGb.syncState = GCodeBuffer::SyncState::syncing; // tell other input channels that we are waiting for sync |
| 5630 | //debugPrintf("Channel %u changed state to syncing, %u\n", thisGb.GetChannel().ToBaseType(), __LINE__); |
| 5631 | // no break |
| 5632 | case GCodeBuffer::SyncState::syncing: |
| 5633 | if (otherGb.syncState == GCodeBuffer::SyncState::running) |
| 5634 | { |
| 5635 | // The other input channel has either not caught up with us, or it has skipped this sync point, or it is not running |
| 5636 | if (otherGb.IsLaterThan(thisGb)) |
| 5637 | { |
| 5638 | // Other input channel has skipped this sync point |
| 5639 | GetMovementState(thisGb).UpdateCoordinatesFromLastKnownEndpoints(); |
| 5640 | thisGb.syncState = GCodeBuffer::SyncState::running; |
| 5641 | //debugPrintf("Channel %u changed state to running, %u\n", thisGb.GetChannel().ToBaseType(), __LINE__); |
| 5642 | synced = true; |
| 5643 | } |
| 5644 | // Else other input channel has not caught up with us yet, so wait for it |
| 5645 | break; |
| 5646 | } |
| 5647 | |
| 5648 | // If we get here then the other input channel is also syncing, so it's safe to use the machine axis coordinates of the axes it owns to update our user coordinates |
| 5649 | GetMovementState(thisGb).UpdateCoordinatesFromLastKnownEndpoints(); |
| 5650 | |
| 5651 | // Now that we no longer need to read axis coordinates from the other motion system, flag that we have finished syncing |
| 5652 | thisGb.syncState = GCodeBuffer::SyncState::synced; |
| 5653 | //debugPrintf("Channel %u changed state to synced, %u\n", thisGb.GetChannel().ToBaseType(), __LINE__); |
| 5654 | // no break |
| 5655 | case GCodeBuffer::SyncState::synced: |
| 5656 | switch (otherGb.syncState) |
| 5657 | { |
| 5658 | case GCodeBuffer::SyncState::running: |
| 5659 | // Other input channel has carried on. If we are the primary, we have finished syncing. |
| 5660 | if (thisGb.LatestMachineState().Executing() || !otherGb.OriginalMachineState().fileState.IsLive() || otherGb.IsLaterThan(thisGb)) |
| 5661 | { |
| 5662 | thisGb.syncState = GCodeBuffer::SyncState::running; |
| 5663 | //debugPrintf("Channel %u changed state to running, %u\n", thisGb.GetChannel().ToBaseType(), __LINE__); |
| 5664 | synced = true; |
| 5665 | } |
| 5666 | break; |
| 5667 | |
| 5668 | case GCodeBuffer::SyncState::syncing: |
| 5669 | // Other input channel hasn't noticed that we are fully synced yet |
| 5670 | break; |
nothing calls this directly
no test coverage detected