Module: Tuile::StrictLayout
- Defined in:
- lib/tuile/strict_layout.rb,
sig/tuile.rbs
Overview
The stale-rect diagnostic: a Component#rect read taken while an ancestor still owes a Component#relayout says so, instead of handing back the previous pass's rectangle in silence. On wherever a FakeScreen is the installed screen — a spec suite needs no setup to get it — and off in an app, which strict_layout overrides either way:
holder.constrain(pane, Rect.new(0, 0, 100, 26))
pane.left.rect # => Tuile::Error: read the rect of #<Tuile::Component::Label
# rect=(0,0 80x50)> while #<TwoPane rect=(0,0 100x26)> owes a
# relayout … at spec/two_pane_spec.rb:42
:warn logs the same line to logger and hands the rectangle over,
for watching a running app; :raise is the default and what a spec wants,
since the backtrace names the read and a suite that never set a logger
would see nothing at all. For the read that is pre-settle on purpose,
without_strict_layout.
Reading size, width, height, local_rect, absolute_rect or
to_screen reports too — they all go through the one reader.
Only reads the app makes are reported (PLUMBING): a read lib/ makes
on the app's behalf mid-handler is not the app's to fix.
Implementation details
strict_layout= and FakeScreen prepend this module into
Component, so rect stays the bare attr_reader — the hottest read in
the toolkit — in every process that never asks. Nothing unprepends; turning
the mode off leaves the check inert. See D_strict_layout.
Constant Summary collapse
- LIB_DIR =
Where the gem's own frames live, so the site the message names is the app's —
to_screenand thesize/width/heighttrio all readrectfrom insidecomponent.rb. File.("..", __dir__)
- REPORTING =
The thread-local marking a report in progress: Component#inspect prints the rect, so building the message re-enters
recton the very component that is being complained about. :tuile_strict_layout_reporting- PLUMBING =
The readers that only forward to
rect. A frame of one of these between the read and the app's own code carries no decision of the framework's, so the read still counts as the app's. %w[rect size width height local_rect local_extent_rect absolute_rect absolute_extent_rect to_screen to_local].freeze
Class Method Summary collapse
-
.install ⇒ void
Makes Component#rect consult strict_layout — idempotent, and permanent for the process.
-
.report(component, ancestor, mode) ⇒ void
Reports
component's rect read as stale, the waymodeasks for.
Instance Method Summary collapse
-
#rect ⇒ Rect
Component#rect, reporting first when it is about to answer the previous pass's rectangle.
Class Method Details
.install ⇒ void
This method returns an undefined value.
Makes Component#rect consult Tuile.strict_layout — idempotent, and permanent for the process.
57 |
# File 'lib/tuile/strict_layout.rb', line 57 def install = Component.prepend(self) |
.report(component, ancestor, mode) ⇒ void
This method returns an undefined value.
Reports component's rect read as stale, the way mode asks for.
@param component — the component whose rect was read.
@param ancestor — the ancestor owing the relayout.
@param mode — :raise or :warn.
66 67 68 69 70 71 72 73 |
# File 'lib/tuile/strict_layout.rb', line 66 def report(component, ancestor, mode) return unless app_read? = (component, ancestor) raise Error, if mode == :raise Tuile.logger.warn() end |
Instance Method Details
#rect ⇒ Rect
Component#rect, reporting first when it is about to answer the previous pass's rectangle.
118 119 120 121 122 123 124 125 |
# File 'lib/tuile/strict_layout.rb', line 118 def rect mode = Tuile.strict_layout if mode && !Thread.current[REPORTING] ancestor = stale_layout_ancestor StrictLayout.report(self, ancestor, mode) unless ancestor.nil? end super end |