jmp
Coordinating Signals in a Layout System
@bigmistqke I'm finally getting around to using tokens! So far everything has been mostly smooth, but I'm wondering how to use higher-order components with tokenized children? I wrap all my components in some contexts to implicitly pass & generate ids
I've tried something like this (as well as the commented out version)
WrappedComponent
is a token.
I get the "Tokens can only be rendered with resolveTokens" error.
I need the context here b/c I'm inspecting the name
prop before it is passed to the wrapped component.33 replies
setting signal inside createRenderEffect
I guess I'm not sure what dependency graph you have in mind?
do you want "render" to run every time
other
is updated or only when other
is updated by count
? If the latter, maybe there's another way to express that dependency graph5 replies
setting signal inside createRenderEffect
I'm not sure if this would work for your use case, but if you make "render" dependent on updates to
other
rather than updates to count
, you'll get properly alternating effects and renders: https://playground.solidjs.com/anonymous/231201e1-546a-4621-9124-b345fea0caf95 replies
Coordinating Signals in a Layout System
That looks very cool! I'm having some trouble understanding what the expressiveness of jsx-tokenizer is. What is an example of something I can't do with effects but that I can do with jsx-tokenizer? e.g. are you trying to walk the canvas tree in the same order every frame?
33 replies
Coordinating Signals in a Layout System
Out of curiosity, do you know what breaks when you write signals from
createMemo
?
The docs say:
The memo function should not change other signals by calling setters (it should be "pure"). This enables Solid to optimize the execution order of memo updates according to their dependency graph, so that all memos can update at most once in response to a dependency change.Does that mean if I write signals but can ensure the memo won't run a second time in response to those changes, then it's safe?
33 replies
Coordinating Signals in a Layout System
Thanks for the thoughts! The SVG tiler looks cool.
I do share your worries about the layout update order. My previous system prototype only supported static diagrams so there was no problem with ordering.
My current approaches are either (i) have parent layouts call child layouts to enforce a layout order or (ii) ensure that layouts can happen in any order. (i) is how mobile frameworks and CSS (I think) accomplish this so whenever a parent is stale they re-run that layout and also check if the child layouts are stale. Maybe I can implement a different caching system just for the layout functions. (ii) might be possible thanks to the ownership properties on each bbox. Those are established on first render. (I haven't thought about what happens on subsequent renders when the graph might change, though.) After they're established, the layouts can run in any order it might just be faster or slower since layouts may have to run multiple times before converging. But I haven't implemented flexbox in this new system, so I'm not 100% sure if it works with the ownership model.
But yeah I was hoping there would be a more Solid-native way of ensuring this. I'll keep thinking about it.
33 replies
Coordinating Signals in a Layout System
This works alright for a lot of things, but one tricky addition is making it so that you can adapt to screen size. For example, you might want to shrink a
Rect
so that it fits inside the screen. To accomplish this in Jetpack Compose, they pass width and height information from the parent to the child, which is used during the child's layout. Here's a simplified example of that:
But notice that this changes how layout
s are run. Now the parent controls when the child layout happens. This is useful in some cases like for implementing flexbox. In that case you have a flow sort of like this:
So parent and child layout computations are interleaved in a way that I don't think is possible using createEffect
?
Another route to take is to store maxHeight
and maxWidth
in a local context for each child. This can be useful so that you can change the structure of the component based on those constraints. E.g.
This seems pretty expressive and a lot nicer than writing layout functions directly, but I haven't figured out how the API would work if you could also write stuff like child0.layout({ maxHeight: 5000, maxWidth: 3000})
. I think the problem is that within a layout function you want the child's layout computation to have settled after the child0.layout
call is complete, and I'm finding it pretty hard to reason about when that happens.33 replies
Coordinating Signals in a Layout System
Basically I have a store
It sets up a DAG of scenegraph nodes. The bbox and transform (and ownership of the properties within those fields) is updated by
setBBox
. For example, I may have an AlignLeft
parent that sets the left
bbox property of each of its children and obtains ownership of each of its children's left
bbox property.
The ref
nodes allow indirection so multiple nodes in the scenegraph can modify the same bbox and transforms. (This is why I can't derive bbox and transform information directly from the layout functions and just memo that.)
The ownership information ensures that even when a node is written to by multiple parents, the properties are uniquely writable by a single parent so there are no edit conflicts.
Suppose I have a component like this:
Then the first Rect
will run its layout, setting its width, height, and y values. The AlignLeft
's layout will run later, thus filling in the x
value.33 replies
Coordinating Signals in a Layout System
Hi Erik, thanks for the help!
The scenegraph is a Solid store and updateBBox calls
setScenegraph
, so the layout effect has a Solid-specific side effect.
But swapping the order of the jsx and effect did the trick!
In terms of moving the layout functions into the scenegraph store I was mostly wondering if there was a way to keep the reactive computation in the store so it can be called by other components. Right now I'm dependent on the Solid effect queue for layout updates.
That being said, all the layout scheduling problems I've run into so far can be solved by the jsx-effect swap trick. So I'll just stick with that for now.
Thanks again!33 replies