( screen: Screen, charPool: CharPool, hyperlinkPool: HyperlinkPool, )
| 593 | * O(width * height) but only called occasionally (e.g., between conversation turns). |
| 594 | */ |
| 595 | export function migrateScreenPools( |
| 596 | screen: Screen, |
| 597 | charPool: CharPool, |
| 598 | hyperlinkPool: HyperlinkPool, |
| 599 | ): void { |
| 600 | const oldCharPool = screen.charPool |
| 601 | const oldHyperlinkPool = screen.hyperlinkPool |
| 602 | if (oldCharPool === charPool && oldHyperlinkPool === hyperlinkPool) return |
| 603 | |
| 604 | const size = screen.width * screen.height |
| 605 | const cells = screen.cells |
| 606 | |
| 607 | // Re-intern chars and hyperlinks in a single pass, stride by 2 |
| 608 | for (let ci = 0; ci < size << 1; ci += 2) { |
| 609 | // Re-intern charId (word0) |
| 610 | const oldCharId = cells[ci]! |
| 611 | cells[ci] = charPool.intern(oldCharPool.get(oldCharId)) |
| 612 | |
| 613 | // Re-intern hyperlinkId (packed in word1) |
| 614 | const word1 = cells[ci + 1]! |
| 615 | const oldHyperlinkId = (word1 >>> HYPERLINK_SHIFT) & HYPERLINK_MASK |
| 616 | if (oldHyperlinkId !== 0) { |
| 617 | const oldStr = oldHyperlinkPool.get(oldHyperlinkId) |
| 618 | const newHyperlinkId = hyperlinkPool.intern(oldStr) |
| 619 | // Repack word1 with new hyperlinkId, preserving styleId and width |
| 620 | const styleId = word1 >>> STYLE_SHIFT |
| 621 | const width = word1 & WIDTH_MASK |
| 622 | cells[ci + 1] = packWord1(styleId, newHyperlinkId, width) |
| 623 | } |
| 624 | } |
| 625 | |
| 626 | screen.charPool = charPool |
| 627 | screen.hyperlinkPool = hyperlinkPool |
| 628 | } |
| 629 | |
| 630 | /** |
| 631 | * Get a Cell view at the given position. Returns a new object each call - |
no test coverage detected