Namespace NinjaTools.FlexBuilder.LayoutAlgorithms
Classes
CSSAvailableLength
CSSAvailableSpace
Spec 9.2.2 calculates an "available space" concept, which is made up of two values, each of which is either a 'length' (pixels) or a 'constraint' (MAX_CONTENT, MIN_CONTENT)
TODO: this will be merged into CSSContainerSize in a future release; this class is the legacy one, but I want to maintain some of the typesafety specifically around the point where a CSSContainerSize specified as the container's 'size' converts to being the container's 'inner size' / 'content-size' (ie CSSAvailableSpace)
CSSAvailableSpace2
Spec 9.2.2 calculates an "available space" concept, which is made up of two values, each of which is either a 'length' (pixels) or a 'constraint' (MAX_CONTENT, MIN_CONTENT).
The Flexbox spec is badly written, and has an incomplete 'example-based' definition, which is:
https://www.w3.org/TR/css-flexbox-1/#algo-available "For each dimension, if that dimension of the flex container’s content box is a definite size, use that; if that dimension of the flex container is being sized under a min or max-content constraint, the available space in that dimension is that constraint; otherwise, subtract the flex container’s margin, border, and padding from the space available to the flex container in that dimension and use that value. This might result in an infinite value."
CSS3 defines AvailableSpace as: float, infinite, or constraint:
https://www.w3.org/TR/css-sizing-3/#available "A size representing the space into which a box is laid out, as determined by the rules of the formatting context in which it participates. The space available to a box is usually either a measurement of its containing block (if that is definite) or an infinite size (when it is indefinite). Available space can alternatively be either a min-content constraint or a max-content constraint, which forces boxes laid into it to be laid out under that constraint."
CSSContainerLength
Maintains an 'isValid' flag that is reset to 'true' whenever you assign a value OR a mode/constraint -- this is mainly used to provide a way for a size to be explicitly 'invalid' eg when in the middle of a layout operation and performing a recursive sub-layout of child containers whose sizes aren't fully knowable yet.
CSSContainerSize
Used for storing the 'known' incoming size of a container at the start of layout / before doing layout
CSSContentLengthConstrainable
Combines
EphemeralCaches
Lower-quality caching for when Relayout-Tracking is disabled or not present (Relayout-Tracking maintains finer-grained caches and disposes of them immediately when not needed any more).
EphemeralLayoutCache<T1, T2>
NOTE: the Key (T1) must never be a struct - or else all requests will return 'cache hit' with an empty value
ExperimentalDelayUpdates2
FlexBuilder normally guarantees that the layout tree is 'always correct' (unlike Unity, which frequently has a corrupt layout tree, and in many cases it CANNOT be uncorrupted). This works great, but causes a loss of performance in cases where you are making a large number of changes all in the same frame, and want FlexBuilder to temporarily stop doing relayouts until you finish the last change.
It is impossible for FlexBuilder to ignore your early changes because it has no way of knowing which change in your script was the 'last' one (earlier versions attempted to watch the tree and insert a last-minuted 'emergency relayout' during LateUpdate, but there were edge-cases where flaws in Unity's MonoBehaviour lifecycle allowed some layouts to miss this emergency layout, or to flicker due to Unity displaying incomplete renders).
This class offers a solution: it allows you to programmatically declare a section of code that FlexBuilder will watch your changes but do nothing until the section ends, at which point it will do the minimum number of relayout operations possible to bring the layout back to correct state.
Usage
This class can only be used with a C#
using( .. ) { ... }
statement. You create an instance of this
class in the '( )' brackets, and put all your own code in the '{ }' brackets.
e.g.
using( new ExperimentalDelayUpdates2() )
{
/// normally these three lines would cause 3 relayouts
/// ... but the 'using' causes only 1 relayout to be executed
myFlexItem.flexGrow = 1;
myFlexItem.flexShrink = 0;
myFlexItem.cssWidth = 50f;
}
Implementation/design
Whenever you change any field/property/setting of any FlexItem or FlexContainer, it will trigger a relayout of all affected items and UI elements - for many algorithms, that forces a ripple-effect of relayouts all the way up to the top of the tree.
When this class is active (see 'Usage' above) those triggers are all saved but not executed, until the class instance is disposed by C#, at which point all triggers execute in a single step.
ExperimentalDelayUpdates2.DelayedCall
ExperimentalDelayUpdates2.DelayedCompleter
FlexboxLayoutAlgorithm410
Summer 2022: Current/most recommended Layout Algorithm (this is the official algorithm for the 4.0.0 release of FlexBuilder) available in the standard (non-Pro) release.
Implements the CSS3 FlexBox Specification following the suggested algorithm in the specification itself (which is not 100% optimal in performance, but produces the 'most correct' visual results).
FlexboxLayoutAlgorithm440
Summer 2023: Adds detailed complex fixes for edge-cases around scrollviews and percentages-of-percentages-or-auto-sizes Fixes issues with WRAPPED layouts mis-reporting their sizes in ways that confuses the calculations of Unity Scrollviews
Implements the CSS3 FlexBox Specification following the suggested algorithm in the specification itself (which is not 100% optimal in performance, but produces the 'most correct' visual results).
FlexboxLayoutAlgorithm450
Summer 2023: Adds detailed complex fixes for edge-cases around scrollviews and percentages-of-percentages-or-auto-sizes Fixes issues with WRAPPED layouts mis-reporting their sizes in ways that confuses the calculations of Unity Scrollviews
Implements the CSS3 FlexBox Specification following the suggested algorithm in the specification itself (which is not 100% optimal in performance, but produces the 'most correct' visual results).
FlexboxLayoutAlgorithm460
Autumn 2023: Adds experimental support for "gap" in CSS3
Implements the CSS3 FlexBox Specification following the suggested algorithm in the specification itself (which is not 100% optimal in performance, but produces the 'most correct' visual results).
FlexboxLayoutAlgorithm470
Autumn 2023: Adds experimental support for "gap" in CSS3
Implements the CSS3 FlexBox Specification following the suggested algorithm in the specification itself (which is not 100% optimal in performance, but produces the 'most correct' visual results).
FlexLine
Used internally by Flexbox LayoutAlgorithms when arranging flexitems into lines (following the advice of CSS3 Specification)
IFlexboxLayoutAlgorithm
Core of FlexBuilder: the layout algorithm object performs all layout, according to CSS3 Flexbox rules.
There are multiple implementations of this, with different performance/accuracy tradeoffs, with newer releases adding new instances with higher version numbers so that you can always preserve and optionally continue using old versions if eg some of your UI design was coded based on their quirks.
ILayoutAlgorithmV2
Legacy layout algorithms use this class - highly recommended to replace them ASAP with v4 or later algorithms
ILayoutAlgorithmV2.FlexRelayoutEvent
ILayoutAlgorithmV3
Legacy layout algorithms use this class - highly recommended to replace them ASAP with v4 or later algorithms
ILayoutAlgorithmV3.FlexRelayoutEvent
ILayoutAlgorithmV4
There are three phases to flex-layout in the v4 Algorithms, based on decomposing the Flexbox system and carefully looking at which bits can be shared, which can be re-used, which can be cached - and which must not.
For any non-FlexContainer: none of this applies: it calculates (but does not itself use) a default size (or none), and is later force-sized by its parent. For any definite FlexContainer: NB: 'definite' has magic-meaning in CSS3 -- halfway between the non-FlexContainers and the FlexContainers For all other FlexContainers:
Layout-self: If you already know your size: if it's different from your current size: Phase 1: Calculate all children-sizes, and 'virtually' lay them out internally into Flex-lines, using grow/shrunk, but NOT overwriting any values Phase 3: set size of all children, and position all children if it's the same as your current size: Phase 0: do nothing
If you don't know your size yet, called by something else: Phase 1: Calculate all children-sizes, and 'virtually' lay them out internally into Flex-lines, returning the result, and wait If you don't know your size yet, called by yourself: Phase 1: Calculate all children-sizes, and 'virtually' lay them out internally into Flex-lines Phase 2: Set size of self, using the child-sizes + flex-lines from phase 1 Phase 3: set size of all children, and position all children
Notes:
- Phase3 requires that you ALREADY HAVE SET YOUR FINAL SIZE (because positioning requires knowing the correct, final, self-size)
- Phase1 MUST NOT change any sizes/positions/etc (because sometimes it's purely information-gathering)
- Phase2 only happens if you are self-sizing AND your basis is a variation of CONTENT (e.g. CONTENT or AUTO-but-no-width/height)
ILayoutAlgorithmV4.AxesConstraints
ILayoutAlgorithmV44xPlus
Extends the basic contract of all ILayoutAlgorithmV4 algorithms by adding a large number of optimizations, extra features, etc that apply to Algorithms numbered v4.1.x - but which are likely to be replaced or superceded by later algorithms in the v4.x line
ILayoutAlgorithmV4x1
Extends the basic contract of all ILayoutAlgorithmV4 algorithms by adding a large number of optimizations, extra features, etc that apply to Algorithms numbered v4.1.x - but which are likely to be replaced or superceded by later algorithms in the v4.x line
ITreeUpdateAlgorithm
The TreeUpdate algorithms provide huge optimizations in avoiding relayouting items that haven't changed, and add powerful features that auto-detect when the Unity Editor needs to relayout part (or all) of the UI.
ITreeUpdateAlgorithmV4
This file contains the 'start a layout / relayout / detect a relayout / optimize relayout' parts.
ITreeUpdateAlgorithmV45plus
This file contains the 'start a layout / relayout / detect a relayout / optimize relayout' parts.
ModularInspectorAttribute
Allows us to build custom Inspectors using a modular approach, making them easier to maintain and easier to extend
PerformanceTrackerForLayoutAlgorithms
Tracing performance on a large UI project is almost impossible using Unity's tools - they are too simplistic.
TEMPORARY CLASS WHILE ADDING SOME SUBTLE PERFORMANCE IMPROVEMENTS
The most basic performance work needs something that can track "for each invocation of each method, what parameters did it have, and were they unique?" - which Unity hasn't achieved yet. This class provides a way to track that information, and couple it with "what are the hotspots in our code -- where did the hot methods GET CALLED FROM?"
This is a MUCH, MUCH simpler system than the HierarchicalLog / NinjaTreeLog (which records EVERYTHING and is a much faster alternative to Unity's built-in logging). This is ONLY designed to capture the most important, critical calls that are semantically important in FlexBuilder (e.g. 'size of item', 'size of container', etc).
Usage:
- The LayoutAlgorithm has to support it internally - critical calls have to be decorated with calls to ".liveLog.StartMethod()" and "... .liveLog.EndMethod()"
- Make sure the log is enabled! ".isEnabled = true" -- by default it is ALWAYS DISABLED to preserve performance in non-debugging situations.
- At runtime, call .liveLog.Wipe() (to clear out any cached/previous perf data)
- At runtime, perform your FlexBuilder layout
- At rutnime, call .liveLog.Output
PerformanceTrackerForLayoutAlgorithms.PerformanceTrackerHotMethod
TreeAlgorithm43
This file contains the 'start a layout / relayout / detect a relayout / optimize relayout' parts.
TreeAlgorithm43.PerformanceTreeLogLine
TreeAlgorithm45
This file contains the 'start a layout / relayout / detect a relayout / optimize relayout' parts.
TreeAlgorithm4beta2
This file contains the 'start a layout / relayout / detect a relayout / optimize relayout' parts.
ValidatorForV4AlgorithmAttribute
ValidatorForV4x
Runs the validation checks for all V4LayoutAlgorithms
Structs
ILayoutAlgorithmV4.Phase0Output
ILayoutAlgorithmV4.Phase1Output
Interfaces
IFlexboxDescribableLayoutAlgorithm
Optional (but highly recommended) feature of LayoutAlgorithms that makes them self-describing; this info is auto-detected in the UnityEditor by our custom inspectors, and presented to the user when they are choosing which LayoutAlgorithm to use, or when auto-creating a new one if their project is missing that specific version/instance.
IModularInspector
Enums
AvailableLengthMode
PerformanceTrackerForLayoutAlgorithms.OutputMode
RefreshLayoutMode
Only used by legacy v2 and v3 algorithms, see ILayoutAlgorithmV2 and ILayoutAlgorithmV3