( screen: Screen, charPool: CharPool, hyperlinkPool: HyperlinkPool, )
| 552 | * O(width * height) but only called occasionally (e.g., between conversation turns). |
| 553 | */ |
| 554 | export function migrateScreenPools( |
| 555 | screen: Screen, |
| 556 | charPool: CharPool, |
| 557 | hyperlinkPool: HyperlinkPool, |
| 558 | ): void { |
| 559 | const oldCharPool = screen.charPool |
| 560 | const oldHyperlinkPool = screen.hyperlinkPool |
| 561 | if (oldCharPool === charPool && oldHyperlinkPool === hyperlinkPool) return |
| 562 | |
| 563 | const size = screen.width * screen.height |
| 564 | const cells = screen.cells |
| 565 | |
| 566 | // Re-intern chars and hyperlinks in a single pass, stride by 2 |
| 567 | for (let ci = 0; ci < size << 1; ci += 2) { |
| 568 | // Re-intern charId (word0) |
| 569 | const oldCharId = cells[ci]! |
| 570 | cells[ci] = charPool.intern(oldCharPool.get(oldCharId)) |
| 571 | |
| 572 | // Re-intern hyperlinkId (packed in word1) |
| 573 | const word1 = cells[ci + 1]! |
| 574 | const oldHyperlinkId = (word1 >>> HYPERLINK_SHIFT) & HYPERLINK_MASK |
| 575 | if (oldHyperlinkId !== 0) { |
| 576 | const oldStr = oldHyperlinkPool.get(oldHyperlinkId) |
| 577 | const newHyperlinkId = hyperlinkPool.intern(oldStr) |
| 578 | // Repack word1 with new hyperlinkId, preserving styleId and width |
| 579 | const styleId = word1 >>> STYLE_SHIFT |
| 580 | const width = word1 & WIDTH_MASK |
| 581 | cells[ci + 1] = packWord1(styleId, newHyperlinkId, width) |
| 582 | } |
| 583 | } |
| 584 | |
| 585 | screen.charPool = charPool |
| 586 | screen.hyperlinkPool = hyperlinkPool |
| 587 | } |
| 588 | |
| 589 | /** |
| 590 | * Get a Cell view at the given position. Returns a new object each call - |
no test coverage detected