Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Static component for rendering permanent output #66

Merged
merged 2 commits into from
Sep 6, 2022

Conversation

bnorm
Copy link
Contributor

@bnorm bnorm commented Aug 19, 2022

Resolves #65

Probably went a little overboard on the jest sample updates so let me know if you want me to roll anything back. Also I'm not stuck on any naming, so if you have suggestions let me know.

Copy link
Owner

@JakeWharton JakeWharton left a comment

Choose a reason for hiding this comment

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

Super slick!

Comment on lines +97 to +102
if (other.width > 0 && other.height > 0) {
canvas.static.add(other)
}

// Propagate any static content of the display.
canvas.static.addAll(other.static)
Copy link
Owner

Choose a reason for hiding this comment

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

This is my least favorite part of the change. The fact that a render causes a side-effect to collect these other renders and then something at the call site magically emits that first.

It's hard to argue with the output, but I think I would like to try and find something better for this. I'm not going to block merging here because the output is truly fantastic and it's all implementation detail.

Render (well, renderTo) is a tree walk, and I think perhaps we separate out the static tree walk to its own function which can be less reliant on side-effects + mutation. It also hopefully means the canvas isn't aware of these static renders.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, this was definitely a result of not wanting to make a bunch of render things Static specific or introduce multiple render passes. Thankfully as you said it is all implementation detail so can definitely be iterated.

Render (well, renderTo) is a tree walk, and I think perhaps we separate out the static tree walk to its own function which can be less reliant on side-effects + mutation.

Are you thinking something like 2 renderTo passes, one for static and the other for "normal" content? Or find all the Static nodes in the render function and render those to the canvas first somehow? I can try a couple different things - if you want - but maybe a little pseudocode of what you are thinking might help.

It also hopefully means the canvas isn't aware of these static renders.

The tricky part here was that AnsiOutput needs to know the static and non-static parts so it can set the lastHeight to only the non-static part. So whatever gets sent to the output, needs to know that additional detail.

Copy link
Owner

Choose a reason for hiding this comment

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

I was thinking a whole separate function, like renderTo() and renderStaticTo() or something. Basically just splitting the responsibilities and each node would only realistically implement one of them.

Comment on lines +34 to +35
// Remove any items which have been rendered.
pending.removeIf { it.rendered }
Copy link
Owner

Choose a reason for hiding this comment

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

This isn't super efficient but it's probably fine. One thing to note is that the trues are contiguous starting at index 0 so we could find the first false index and then do subList(0, firstFalse).clear() for an operation that is likely the most optimal.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's a good idea. I always forget that modifications on subList are reflected in the full list. Also worth noting that just pending.clear() worked in all of the test samples I created but I wasn't convinced that would work in all cases so I added the wrapper Item class to be safe.

@JakeWharton JakeWharton merged commit c512de1 into JakeWharton:trunk Sep 6, 2022
@JakeWharton
Copy link
Owner

Slamming it home. We can iterate as needed. Thanks for this!

@bnorm bnorm deleted the static branch September 6, 2022 20:40
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.

Mixing console logging with mosaic
2 participants