DrawingGroup resets coordinates to avoid unnecessarily calling Position when portions of the UI move uniformly. To support this:
DrawingGroupprovidesdrawingGroup:AbsolutePosition()to move local coordinates to a global context. E.g., comparing bounds v.s. interaction inResponder.- (Internal detail: To performantly propagate changes to a
DrawingGroup's position,DrawingGroupwill calldrawingGroup:SetParentGroupPosition(x, y)on its children, to inform of the new result that would be returned bydrawingGroup:AbsolutePosition()) - (Internal detail:
GeometryTargets will now also register with their parentDrawingGroup(drawingGroup.childGeometryTargets) to receivegeometryTarget:SetParentGroupPosition(x, y), again as a performance optimisation) GeometryTargetno longer providesCachedPosition. Instead, this functionality is split out into the following API:geometryTarget:CachedPositionRemainingInLocalContext()geometryTarget:CachedPositionTranslatedToGlobalContext()geometryTarget:CachedPositionTranslatedToContext(callerDrawingGroup)geometryTarget:ContainsAbsolutePoint(x, y)geometryTarget:ContainsPoint(x, y, callerDrawingGroup)
(seeLayout/GeometryTarget.luafor further details.)_debug_mouseOveris now a separate event listed inframework.events.
Other architectural changes:
Responder,PrimaryFrame,WrappingText, andBackgroundnow inherit fromGeometryTarget. SeeGeometryTargetfor expanded interface.Tooltipnow inherits fromResponder, andtooltipis now listed inframework.events.Componentnow has a single associated drawing group. Let me stress, then the importance of making sure reusable tools inherit fromDrawer, notComponent! (Componentmust necessarily be contained in one single drawing group for reasons I can't remember. Maybe convenience, then.)DrawingGroupadvertisesCachedSizenow to go withAbsolutePosition- but do not be fooled, this is NOT a full implementation ofGeometryTarget.- Remove
framework.viewportDidChange. It was unused, and other, more robust methods can be used to respond to updates (e.g.AutoScalingDimension). drawingGroup.needsRedrawis not set indrawingGroup:UpdateLayout(calledByParent), since it's already set indrawingGroup:UpdatePosition()- (Internal detail:
drawingGroup.groupsNeedingLayoutanddrawingGroup.groupsNeedingPositionwill not remove any groups until directly beforedrawingGroup:UpdatePosition()is called, to allowdrawingGroup:Position(x, y)to triggerdrawingGroup:UpdatePosition()if necessary.)
Text Highlight API:
WrappingTextnow handles the selection highlight drawing forTextEntrywith a public API! See documentation inWrappingText.lua:wrappingText:HighlightRange(color, startIndex, endIndex, reuseLast)wrappingText:UpdateHighlight(id, color, startIndex, endIndex, reuseLast)wrappingText:RemoveHighlight(id)
TextGroupnow callswrappingText:DrawText(glFont)rather thanwrappingText:Draw(glFont)to avoid collision whenDrawingGroupcallswrappingText:Draw()
Additions:
DialogandConfirmationDialog- Selected mode for
Button. Seebutton:SetSelected(newSelected),button:GetSelected()
Visual changes:
- Squared-off corners at the edge of the screen have been disabled, due to drawing no longer knowing whether it's actually at the edge of the screen.
- Round fonts to the nearest pixel size (to prevent blurry text).
- Swap
color.selectedColorandcolor.pressColor
Debug changes:
- Add
component._debugIdentifierfor easier logging - Remove redundant
Internal._debug_currentElementKeyin favour ofInternal.activeElement.key. - Add argument & return value validation for
Position&Layout. - Include stacktrace for framework error messages (debug mode must be enabled, because this comes with a significant performance cost).
- Add some tests matched to some solved
dimension:Update(...)bugs. - Inject some profiling only when debug mode is enabled. Other profiling has been removed.
- Some error catching has been made less fine-grained for performance reasons. With stacktraces enabled, this should not tangibly hamper debugging.
- Drawing will terminate completely after an error, rather than completing the other passes in the element's final frame.
Bug fixes:
- Hide
MovableFramehandle when releasing outside bounds) - Fix over-cropping for
OffsettedViewport. (I suspect this happens with height too, but so far I haven't been able to verify. There's chance the error's something else, idk.) - Fix bug where, when a font stopped being used in a
TextGroup, it would cancel drawing for all following fonts. - Fix continuous updating being incompatible with calling
drawingGroup:DrawerUpdated(drawer) - Fixed invalid declaration of
Blending
Performance improvements:
-
DrawingGroupcancels drawing when it knows it will not be visible (e.g. outside of current viewport or scissor). -
Improved caching for
wrappingText:CoordinateToCharacterDisplayIndex(x, y) -
wrappingText:DisplayIndexToRawIndex(displayIndex, addedCharactersIndex, removedSpacesIndex, computedOffset)makes use of an index cache, when a partial result isn't returned. Even when not using the cache, other optimisations have sped it up around 3x. -
wrappingText:RawIndexToDisplayIndex(rawIndex, addedCharactersIndex, removedSpacesIndex, computedOffset)makes use of an index cache generated for trivial cost duringwrappingText:Layout, when a partial result isn't returned. Likely, even for small intervals (above 4), this caching is faster than the existing partial-result mechanism in place. In the committed test, this speeds up from 0.11s @ 100 executions, to 0.061s @ 100000 executions. That's 1800x faster! -
MouseMoveis now buffered to receive only one call per draw frame. If you need more frequent updates, setdragListener.doNotBufferMouseMoveto true.
Tests:
- Introduced a test for benchmarking
WrappingTextmethods.
Also includes further non-breaking (hopefully) optimisations and fixes.