Uh oh!
There was an error while loading. Please reload this page.
Sticky blocks: an entrance after the roll, a release that ends nothing, an exit that finishes — and the Calendar Display taken out - #25
Merged
Conversation
…g, and an exit that finishes A sticky ending block could only ever arrive one way -- travelling up with the credits and stopping at the pin -- and could only ever be the end of the roll. Three changes, and a fix. **An entrance that waits.** `stickyEntrance` is either `WithRoll`, which is what a block has always done, or `AfterRoll`: not on screen at all while the credits go past, then fading up in place over `stickyFadeIn` seconds once the last of them has left the top. A beat of empty frame and then a card. "The rest of the roll" is the strip's last drawn pixel -- lead-out is blank and nobody watching counts it -- and it is the other blocks too, so a card that waits waits for the one ahead of it as well. The fade needed an opacity the base effect has no parameter for, so the blocks are now drawn through a pass of their own with the one shader in the plugin: libobs' own textured quad with the sampled alpha scaled. A device that will not compile it falls back to the base effect and draws every block solid, which loses the fade and nothing else. **A release that ends nothing.** `StickyRelease::ResumeOnly` leaves the screen and has no say in when the roll is over, which is what lets one card follow another: a thank-you that holds and moves off, and a second block that fades up behind it. The three predicates the playback loop is written against -- resumes, ends at the hold, ends at the exit -- answer for it, so nothing downstream had to learn a fourth name. **"Off screen" now means the picture, not the slot.** A block's picture is `margin` taller than its slot at each end, for the backdrop's outset and whatever its children paint outside their own boxes, and the release that waits for the block to leave was asking the slot. So the roll ended -- and the ending action fired -- over a card still showing the last band of itself. `StickyBlockPlacement::clearedFrame` and `offFrame` are now where that question is answered, so it cannot be asked of the slot by accident, and `ResumeThenEnd` ends the roll at the moment the whole picture has gone rather than a tick or two before. **And a block on its way out keeps going out.** `advanceStickyBlocks` took a bool for "is the roll rolling", and a released block stopped dead the moment the roll was called finished -- half off the top of the frame, and staying there. It now takes a `StickyClock`: rolling, coasting, paused or scrubbed. Coasting starts nothing new but carries a departure through to the end of itself. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vx4e1ndwDfczcjrpib7uQj
A schedule board is not a credit roll. It shipped here because it could reuse the model's typefaces, panels and gradients, but everything above that -- events, days, lanes, slots, categories, a five-layer style cascade, a free layer of decoration, five clock features, three answers to overflow, five presets, a column-mapped import and a designer window of its own -- is a second product carried inside the first. It goes to its own plugin later; the reuse it wanted is still there for it, because none of the shared pieces were ever written for the roll alone. Gone: the source and its registration, the board model and its presets, the board renderer, the board's designer and import windows, the tag-glyph table (nothing else read it), the fourteen board suites, and the 225 locale strings behind all of it. Nothing under the Credits Marquee changes. Nothing shared was touched: `CsvParser` still backs the roll's own import, `StyleLibrary`, `Background`, `Gradient`, `FontBundle`, `FontResolution`, `RenderThread`, `SvgArt`, `BackgroundPainter` and `ImageEffects` all had the roll as a caller already, and the check is that the whole harness still passes -- 97 suites, 6025 checks -- with the board's own suites the only ones missing from the count. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vx4e1ndwDfczcjrpib7uQj
…ere they are asked for Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vx4e1ndwDfczcjrpib7uQj
Uh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Four things: three on the Sticky Ending Block, and the Calendar Display removed.
An entrance that waits for the roll
stickyEntranceis eitherWithRoll— travel up with the credits and stop at the pin, which iswhat a block has always done and what every existing document loads as — or
AfterRoll: not onscreen at all while the credits go past, then fading up in place over
stickyFadeInseconds oncethe last of them has left the top. A beat of empty frame and then a card.
"The rest of the roll" is the strip's last drawn pixel (
stripHeightlessleadOut— lead-outis blank and nobody watching counts it as the roll), and it is the other blocks too: a block that
waits also waits for any block still on the frame, since back-to-back cards are what the entrance is
for and one fading up through another on its way out is not that.
The layout does not move for any of it. The block still takes its slot, so turning the entrance
around changes nothing above or below it.
The one new shader. A fade needs an opacity, and the base effect has no parameter for one, so
the blocks are now drawn through a pass of their own with libobs' textured quad and the sampled
alpha scaled. A device that will not compile it falls back to the base effect and draws every block
solid — the fade is lost, the blocks are not. The shader is a string in
CreditsSource.cppratherthan a
.effectfile, since a data file is one more thing to find at runtime on three platforms.A release that ends nothing
StickyRelease::ResumeOnly— Leave The Screen And Do Nothing — climbs off the top and has nosay in when the roll is over. That is what lets one card follow another: a thank-you that holds and
moves off, and a second block whose entrance waits, fading up behind it. It still holds the roll
open while it is on screen, so nothing ends underneath it.
The playback loop is written against three predicates rather than the enum — resumes, ends at the
hold, ends at the exit — and the new mode answers all three, so nothing downstream had to learn a
fourth name.
"Off screen" now means the picture, not the slot
This is the reported bug. A block's picture is
margintaller than its slot at each end, forthe backdrop's outset and whatever its children paint outside their own boxes — and the release that
waits for the block to leave was asking the slot. So the roll ended, and the ending action fired,
over a card still showing the last band of itself.
StickyBlockPlacement::clearedFrameandoffFrameare now where that question is answered, so itcannot be asked of the slot by accident, and every site that judged visibility by hand goes through
them.
ResumeThenEndnow ends the roll at the moment the whole picture has gone, which is what itsname has always promised.
And a block on its way out keeps going out.
advanceStickyBlockstook a bool for "is the rollrolling", and a released block stopped dead the moment the roll was called finished — half off the
top, and staying there. It now takes a
StickyClock: rolling, coasting, paused or scrubbed.Coasting starts nothing new but carries a departure through to the end of itself.
The Calendar Display is gone
A schedule board is not a credit roll. It shipped here because it could reuse the model's typefaces,
panels and gradients, but everything above that — events, days, lanes, slots, categories, a
five-layer style cascade, a free layer of decoration, five clock features, three answers to
overflow, five presets, a column-mapped import and a designer window of its own — is a second
product carried inside the first.
Removed: the source and its registration, the board model and its presets, the board renderer, the
board's designer and import windows, the tag-glyph table (nothing else read it), the fourteen board
suites, and the 225 locale strings behind all of it.
Nothing shared was touched.
CsvParserstill backs the roll's own import;StyleLibrary,Background,Gradient,FontBundle,FontResolution,RenderThread,SvgArt,BackgroundPainterandImageEffectsall had the roll as a caller already. The reuse a futurecalendar plugin would want is still there for it.
A note on what changed underneath an existing setting
ResumeThenEnd("Fire Ending Action After Leaving Screen") used to hold the roll open until theblock had left and then let the roll end naturally; it now ends the roll at the moment the block
clears the frame. For a block at the end of a roll — which is every one of them in practice, since
the roll has finished travelling long before the block's hold does — this is the same instant.
It differs only for a block with credits still scrolling below it, where the old behaviour let
those credits finish. If that turns out to be a roll somebody built, say so and it goes back to
waiting for both.
Checks
cmake --build build— the plugin and the harness, clean from scratch, no warnings../build/tests/closing-time-tests— 97 suites, 6025 checks, 0 failures. The board's ownfourteen suites are the only ones missing from the count.
sticky_release_modes(the three predicates and the id round trips for bothnew enums),
sticky_entrance_carried(the entrance reaches the compositor and moves no layout),sticky_leaving_screen(a block whose slot has just gone has not left the screen — this onefails against the old slot-based test, which is the point of it).
stickyEntranceandstickyFadeInadded to thepersistence suite.
clang-formatandgersemiclean on everything touched.What is not covered by the harness: the playback state machine and the fade shader both live in
CreditsSource.cpp, which needs a real OBS and a graphics device. The state machine's inputs areall pure functions the suites do reach; the shader is behind a fallback that costs the fade and
nothing else if it will not compile. Worth an eye on a real roll before merging.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Vx4e1ndwDfczcjrpib7uQj
Generated by Claude Code