Skip to content

Commit d350857

Browse files
Caching bug fix + Flex Basis
1 parent f862181 commit d350857

File tree

14 files changed

+201
-62
lines changed

14 files changed

+201
-62
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.github.webicitybrowser.spec.css.parser.property.flex;
2+
3+
import com.github.webicitybrowser.spec.css.parser.TokenLike;
4+
import com.github.webicitybrowser.spec.css.parser.property.PropertyValueParseResult;
5+
import com.github.webicitybrowser.spec.css.parser.property.PropertyValueParser;
6+
import com.github.webicitybrowser.spec.css.parser.property.imp.PropertyValueParseResultImp;
7+
import com.github.webicitybrowser.spec.css.parser.property.shared.length.LengthValueParser;
8+
import com.github.webicitybrowser.spec.css.parser.tokens.IdentToken;
9+
import com.github.webicitybrowser.spec.css.property.CSSValue;
10+
import com.github.webicitybrowser.spec.css.property.shared.basic.AutoValue;
11+
12+
public class FlexBasisValueParser implements PropertyValueParser<CSSValue> {
13+
14+
private final LengthValueParser lengthValueParser = new LengthValueParser();
15+
16+
@Override
17+
public PropertyValueParseResult<CSSValue> parse(TokenLike[] tokens, int offset, int length) {
18+
if (offset > 0 && tokens[offset] instanceof IdentToken identToken && identToken.getValue().equals("content")) {
19+
return PropertyValueParseResultImp.of(new AutoValue(), 1);
20+
}
21+
22+
return lengthValueParser.parse(tokens, offset, length);
23+
}
24+
25+
}
Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,59 @@
11
package com.github.webicitybrowser.spec.css.parser.property.flex;
22

33
import com.github.webicitybrowser.spec.css.parser.TokenLike;
4-
import com.github.webicitybrowser.spec.css.parser.TokenStream;
5-
import com.github.webicitybrowser.spec.css.parser.imp.TokenStreamImp;
64
import com.github.webicitybrowser.spec.css.parser.property.PropertyValueParseResult;
75
import com.github.webicitybrowser.spec.css.parser.property.PropertyValueParser;
86
import com.github.webicitybrowser.spec.css.parser.property.imp.PropertyValueParseResultImp;
9-
import com.github.webicitybrowser.spec.css.parser.tokens.EOFToken;
107
import com.github.webicitybrowser.spec.css.parser.tokens.NumberToken;
11-
import com.github.webicitybrowser.spec.css.property.flexbox.FlexBasisValue;
8+
import com.github.webicitybrowser.spec.css.property.CSSValue;
129
import com.github.webicitybrowser.spec.css.property.flexbox.FlexFactorValue;
1310
import com.github.webicitybrowser.spec.css.property.flexbox.FlexValue;
1411

1512
public class FlexShorthandValueParser implements PropertyValueParser<FlexValue> {
13+
14+
private FlexBasisValueParser basisValueParser = new FlexBasisValueParser();
1615

1716
@Override
1817
public PropertyValueParseResult<FlexValue> parse(TokenLike[] tokens, int offset, int length) {
19-
TokenStream stream = new TokenStreamImp(tokens, offset);
18+
if (tokens.length == 0) {
19+
return PropertyValueParseResultImp.empty();
20+
}
2021

21-
FlexBasisValue basisValue = stream.peek() instanceof NumberToken ?
22-
null :
23-
parseBasisValue(stream);
22+
int usedLength = 0;
23+
CSSValue basisValue = null;
24+
25+
if (!(tokens[offset] instanceof NumberToken)) {
26+
PropertyValueParseResult<CSSValue> result = basisValueParser.parse(tokens, offset, length);
27+
if (result.getResult().isPresent()) {
28+
basisValue = result.getResult().get();
29+
usedLength += result.getLength();
30+
}
31+
}
2432

2533
FlexFactorValue growFactor = null;
2634
FlexFactorValue shrinkFactor = null;
27-
if (stream.peek() instanceof NumberToken) {
28-
growFactor = new FlexFactorValue(((NumberToken) stream.read()).getValue().floatValue());
29-
if (stream.peek() instanceof NumberToken) {
30-
shrinkFactor = new FlexFactorValue(((NumberToken) stream.read()).getValue().floatValue());
31-
}
35+
if (usedLength < length && tokens[offset + usedLength] instanceof NumberToken numberToken) {
36+
growFactor = new FlexFactorValue(numberToken.getValue().floatValue());
37+
usedLength++;
38+
}
39+
if (usedLength < length && tokens[offset + usedLength] instanceof NumberToken numberToken) {
40+
shrinkFactor = new FlexFactorValue(numberToken.getValue().floatValue());
41+
usedLength++;
3242
}
3343

34-
if (basisValue == null && !(stream.peek() instanceof EOFToken)) {
35-
basisValue = parseBasisValue(stream);
44+
if (basisValue == null && usedLength < length) {
45+
PropertyValueParseResult<CSSValue> result = basisValueParser.parse(tokens, offset + usedLength, length - usedLength);
46+
if (result.getResult().isPresent()) {
47+
basisValue = result.getResult().get();
48+
usedLength += result.getLength();
49+
}
3650
}
3751

3852
if (basisValue == null && growFactor == null && shrinkFactor == null) {
3953
return PropertyValueParseResultImp.empty();
4054
}
4155

42-
int usedLength = stream.position() - offset;
4356
return PropertyValueParseResultImp.of(new FlexValue(growFactor, shrinkFactor, basisValue), usedLength);
4457
}
45-
46-
private FlexBasisValue parseBasisValue(TokenStream stream) {
47-
// TODO: Implement
48-
stream.read();
49-
return null;
50-
}
5158

5259
}

Spec/src/main/java/com/github/webicitybrowser/spec/css/property/flexbox/FlexBasisValue.java

Lines changed: 0 additions & 5 deletions
This file was deleted.

Spec/src/main/java/com/github/webicitybrowser/spec/css/property/flexbox/FlexValue.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
import com.github.webicitybrowser.spec.css.property.CSSValue;
44

5-
public record FlexValue(FlexFactorValue growFactor, FlexFactorValue shrinkFactor, FlexBasisValue basis) implements CSSValue {
5+
public record FlexValue(FlexFactorValue growFactor, FlexFactorValue shrinkFactor, CSSValue basis) implements CSSValue {
66

77
}

Thready/src/main/java/com/github/webicitybrowser/thready/gui/graphical/base/imp/GUIContentImp.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,16 @@ private void performRenderPipeline(ScreenContentRedrawContext redrawContext) {
125125
performBoxCycle();
126126
case RENDER:
127127
if (rootBox == null) return;
128-
long start = System.currentTimeMillis();
128+
long time1 = System.currentTimeMillis();
129+
renderCache.prepare();
130+
long time2 = System.currentTimeMillis();
129131
performRenderCycle(redrawContext);
132+
long time3 = System.currentTimeMillis();
130133
renderCache.swap();
131-
logger.info("Render cycle took: " + (System.currentTimeMillis() - start) + "ms");
134+
long time4 = System.currentTimeMillis();
135+
if (time4 - time1 > 100) {
136+
logger.info("Long render cycle took: " + (time4 - time1) + "ms (Inner " + (time3 - time2) + "ms)");
137+
}
132138
System.gc();
133139
case COMPOSITE:
134140
if (rootUnit == null) return;

Thready/src/main/java/com/github/webicitybrowser/thready/gui/graphical/base/imp/stage/render/RenderCacheImp.java

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,28 +40,12 @@ public <U extends Box, V extends RenderedUnit> V cachedRender(U box, GlobalRende
4040
cache.put(renderEntry, renderedUnit);
4141
}
4242
}
43-
if (renderedUnit != null && hasNoContextSwitches && box.componentUI().invalidationLevel().compareTo(InvalidationLevel.RENDER) < 0) {
43+
44+
if (renderedUnit != null && hasNoContextSwitches) {
4445
return (V) renderedUnit;
4546
}
4647

47-
RenderCache subCache = subCaches.get(box);
48-
if (subCache == null) {
49-
subCache = new RenderCacheImp();
50-
subCaches.put(box, subCache);
51-
}
52-
V result = display.renderBox(box, new GlobalRenderContext(
53-
globalRenderContext.viewportSize(), globalRenderContext.resourceLoader(),
54-
globalRenderContext.rootFontMetrics(), subCache), localRenderContext);
55-
//if (hasNoContextSwitches) {
56-
RenderEntry fitRenderEntry = new RenderEntry(box, result.fitSize());
57-
cache.put(renderEntry, result);
58-
cache.put(fitRenderEntry, result);
59-
subCache.swap();
60-
61-
box.componentUI().validateUpTo(InvalidationLevel.COMPOSITE);
62-
//}
63-
64-
return result;
48+
return cacheFallbackRender(display, box, globalRenderContext, localRenderContext);
6549
}
6650

6751

@@ -85,6 +69,16 @@ public <U extends Box> AbsoluteSize maxContentSize(U box, GlobalRenderContext gl
8569
return cachedRender(box, globalRenderContext, new LocalRenderContext(size, new ContextSwitch[0])).fitSize();
8670
}
8771

72+
@Override
73+
public void prepare() {
74+
// Remove all invalid entires
75+
cache.entrySet().removeIf(entry ->
76+
entry.getKey().box.componentUI().invalidationLevel().compareTo(InvalidationLevel.RENDER) >= 0);
77+
for (RenderCache subCache : subCaches.values()) {
78+
subCache.prepare();
79+
}
80+
}
81+
8882
@Override
8983
public void swap() {
9084
Map<RenderEntry, RenderedUnit> temp = cache;
@@ -101,6 +95,32 @@ public void swap() {
10195
}
10296
}
10397

98+
private <U extends Box, V extends RenderedUnit> V cacheFallbackRender(
99+
UIDisplay<?, U, V> display, U box, GlobalRenderContext globalRenderContext, LocalRenderContext localRenderContext
100+
) {
101+
RenderEntry renderEntry = new RenderEntry(box, localRenderContext.preferredSize());
102+
103+
RenderCache subCache = subCaches.get(box);
104+
if (subCache == null) {
105+
subCache = new RenderCacheImp();
106+
subCaches.put(box, subCache);
107+
}
108+
109+
V result = display.renderBox(box, new GlobalRenderContext(
110+
globalRenderContext.viewportSize(), globalRenderContext.resourceLoader(),
111+
globalRenderContext.rootFontMetrics(), subCache), localRenderContext);
112+
//if (hasNoContextSwitches) {
113+
RenderEntry fitRenderEntry = new RenderEntry(box, result.fitSize());
114+
cache.put(renderEntry, result);
115+
cache.put(fitRenderEntry, result);
116+
subCache.swap();
117+
118+
box.componentUI().validateUpTo(InvalidationLevel.COMPOSITE);
119+
//}
120+
121+
return result;
122+
}
123+
104124
private record RenderEntry(Box box, AbsoluteSize size) {}
105125

106126
}

Thready/src/main/java/com/github/webicitybrowser/thready/gui/graphical/lookandfeel/core/stage/render/RenderCache.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ public interface RenderCache {
1212

1313
<U extends Box> AbsoluteSize maxContentSize(U box, GlobalRenderContext globalRenderContext, boolean isHorizontal);
1414

15+
void prepare();
16+
1517
void swap();
1618

1719
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.github.webicitybrowser.threadyweb.graphical.directive.layout.flexbox;
2+
3+
import com.github.webicitybrowser.thready.gui.directive.core.Directive;
4+
import com.github.webicitybrowser.threadyweb.graphical.directive.layout.common.size.SizeCalculationDirective;
5+
import com.github.webicitybrowser.threadyweb.graphical.value.SizeCalculation;
6+
7+
public interface FlexBasisDirective extends SizeCalculationDirective {
8+
9+
@Override
10+
default Class<? extends Directive> getPrimaryType() {
11+
return FlexBasisDirective.class;
12+
}
13+
14+
static FlexBasisDirective of(SizeCalculation basis) {
15+
return () -> basis;
16+
}
17+
18+
}

ThreadyWeb/src/main/java/com/github/webicitybrowser/threadyweb/graphical/layout/flexbox/FlexMainSizeDetermination.java

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -84,21 +84,23 @@ private static void setLineInitialMainSize(LayoutRenderContext layoutManagerCont
8484
private static void determineMainSize(
8585
LayoutRenderContext layoutManagerContext, FlexItem flexItem, FlexDirection flexDirection
8686
) {
87-
// TODO: Check flex basis
87+
float preferredBaseSize = flexItem.getSizePreferences().getBaseSize();
8888
float preferredWidth = flexItem.getSizePreferences().getMainSize(flexDirection);
89-
if (preferredWidth != RelativeDimension.UNBOUNDED) {
89+
if (preferredBaseSize != RelativeDimension.UNBOUNDED) {
90+
flexItem.setBaseSize(preferredBaseSize);
91+
flexItem.setHypotheticalMainSize(clampMinMax(preferredBaseSize, flexItem, flexDirection));
92+
} else if (preferredWidth != RelativeDimension.UNBOUNDED) {
9093
flexItem.setBaseSize(preferredWidth);
9194
flexItem.setHypotheticalMainSize(clampMinMax(preferredWidth, flexItem, flexDirection));
92-
return;
95+
} else {
96+
GlobalRenderContext globalRenderContext = layoutManagerContext.globalRenderContext();
97+
FlexItemRenderer.FlexItemRenderContext flexItemRenderContext = new FlexItemRenderer.FlexItemRenderContext(
98+
globalRenderContext, flexDirection);
99+
AbsoluteSize fitSize = FlexItemRenderer.render(flexItem, flexItemRenderContext);
100+
FlexDimension flexDimension = FlexDimension.createFrom(fitSize, flexDirection);
101+
flexItem.setBaseSize(flexDimension.main());
102+
flexItem.setHypotheticalMainSize(clampMinMax(flexDimension.main(), flexItem, flexDirection));
93103
}
94-
95-
GlobalRenderContext globalRenderContext = layoutManagerContext.globalRenderContext();
96-
FlexItemRenderer.FlexItemRenderContext flexItemRenderContext = new FlexItemRenderer.FlexItemRenderContext(
97-
globalRenderContext, flexDirection);
98-
AbsoluteSize fitSize = FlexItemRenderer.render(flexItem, flexItemRenderContext);
99-
FlexDimension flexDimension = FlexDimension.createFrom(fitSize, flexDirection);
100-
flexItem.setBaseSize(flexDimension.main());
101-
flexItem.setHypotheticalMainSize(clampMinMax(flexDimension.main(), flexItem, flexDirection));
102104
}
103105

104106
private static float clampMinMax(float main, FlexItem flexItem, FlexDirection flexDirection) {

ThreadyWeb/src/main/java/com/github/webicitybrowser/threadyweb/graphical/layout/flexbox/item/FlexItemSizePreferences.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import com.github.webicitybrowser.threadyweb.graphical.directive.layout.common.size.MinHeightDirective;
1212
import com.github.webicitybrowser.threadyweb.graphical.directive.layout.common.size.MinWidthDirective;
1313
import com.github.webicitybrowser.threadyweb.graphical.directive.layout.common.size.WidthDirective;
14+
import com.github.webicitybrowser.threadyweb.graphical.directive.layout.flexbox.FlexBasisDirective;
1415
import com.github.webicitybrowser.threadyweb.graphical.directive.layout.flexbox.FlexDirectionDirective.FlexDirection;
1516
import com.github.webicitybrowser.threadyweb.graphical.layout.util.BoxOffsetDimensions;
1617
import com.github.webicitybrowser.threadyweb.graphical.layout.util.LayoutBorderWidthCalculations;
@@ -66,4 +67,8 @@ public float getCrossSize(FlexDirection flexDirection) {
6667
LayoutSizeUtils.computeSize(styleDirectives, WidthDirective.class, sizingContext);
6768
}
6869

70+
public float getBaseSize() {
71+
return LayoutSizeUtils.computeSize(styleDirectives, FlexBasisDirective.class, sizingContext);
72+
}
73+
6974
}

0 commit comments

Comments
 (0)