[android] Remove traverseChildren, NodeRunnable, SvgViewShadowNode

Simplify RenderableViewManager, SvgView
Remove redundant generics
This commit is contained in:
Mikael Sand
2018-10-15 01:19:47 +03:00
parent 0bdca66e2d
commit a4e4b2af7c
7 changed files with 114 additions and 245 deletions
@@ -26,6 +26,7 @@ class DefinitionView extends VirtualView {
super(reactContext);
}
@SuppressWarnings("EmptyMethod")
void draw(Canvas canvas, Paint paint, float opacity) {}
@Override
@@ -27,26 +27,14 @@ class DefsView extends DefinitionView {
}
@Override
void draw(Canvas canvas, Paint paint, float opacity) {
NodeRunnable markUpdateSeenRecursive = new NodeRunnable() {
public void run(View node) {
if (node instanceof VirtualView) {
((VirtualView) node).traverseChildren(this);
} else if (node instanceof SvgView) {
((SvgView) node).traverseChildren(this);
}
}
};
traverseChildren(markUpdateSeenRecursive);
}
void draw(Canvas canvas, Paint paint, float opacity) {}
void saveDefinition() {
traverseChildren(new NodeRunnable() {
public void run(View node) {
if (node instanceof VirtualView) {
((VirtualView)node).saveDefinition();
}
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (child instanceof VirtualView) {
((VirtualView)child).saveDefinition();
}
});
}
}
}
@@ -86,36 +86,35 @@ class GroupView extends RenderableView {
final SvgView svg = getSvgView();
final GroupView self = this;
final RectF groupRect = new RectF();
traverseChildren(new NodeRunnable() {
public void run(View lNode) {
if (lNode instanceof VirtualView) {
VirtualView node = ((VirtualView)lNode);
if (node instanceof RenderableView) {
((RenderableView)node).mergeProperties(self);
}
int count = node.saveAndSetupCanvas(canvas);
node.render(canvas, paint, opacity * mOpacity);
RectF r = node.getClientRect();
if (r != null) {
groupRect.union(r);
}
node.restoreCanvas(canvas, count);
if (node instanceof RenderableView) {
((RenderableView)node).resetProperties();
}
if (node.isResponsible()) {
svg.enableTouchEvents();
}
} else if (lNode instanceof SvgView) {
SvgView svgView = (SvgView)lNode;
svgView.drawChildren(canvas);
for (int i = 0; i < getChildCount(); i++) {
View lNode = getChildAt(i);
if (lNode instanceof VirtualView) {
VirtualView node = ((VirtualView)lNode);
if (node instanceof RenderableView) {
((RenderableView)node).mergeProperties(self);
}
int count = node.saveAndSetupCanvas(canvas);
node.render(canvas, paint, opacity * mOpacity);
RectF r = node.getClientRect();
if (r != null) {
groupRect.union(r);
}
node.restoreCanvas(canvas, count);
if (node instanceof RenderableView) {
((RenderableView)node).resetProperties();
}
if (node.isResponsible()) {
svg.enableTouchEvents();
}
} else if (lNode instanceof SvgView) {
SvgView svgView = (SvgView)lNode;
svgView.drawChildren(canvas);
}
});
}
this.setClientRect(groupRect);
popGlyphContext();
}
@@ -128,15 +127,14 @@ class GroupView extends RenderableView {
Path getPath(final Canvas canvas, final Paint paint) {
final Path path = new Path();
traverseChildren(new NodeRunnable() {
public void run(View node) {
if (node instanceof VirtualView) {
VirtualView n = (VirtualView)node;
Matrix transform = n.mMatrix;
path.addPath(n.getPath(canvas, paint), transform);
}
for (int i = 0; i < getChildCount(); i++) {
View node = getChildAt(i);
if (node instanceof VirtualView) {
VirtualView n = (VirtualView)node;
Matrix transform = n.mMatrix;
path.addPath(n.getPath(canvas, paint), transform);
}
});
}
return path;
}
@@ -146,45 +144,42 @@ class GroupView extends RenderableView {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
final Path.Op pop = Path.Op.valueOf(op.name());
traverseChildren(new NodeRunnable() {
@SuppressLint("NewApi")
public void run(View node) {
if (node instanceof VirtualView) {
VirtualView n = (VirtualView)node;
Matrix transform = n.mMatrix;
Path p2;
if (n instanceof GroupView) {
p2 = ((GroupView)n).getPath(canvas, paint, op);
} else {
p2 = n.getPath(canvas, paint);
}
p2.transform(transform);
path.op(p2, pop);
for (int i = 0; i < getChildCount(); i++) {
View node = getChildAt(i);
if (node instanceof VirtualView) {
VirtualView n = (VirtualView)node;
Matrix transform = n.mMatrix;
Path p2;
if (n instanceof GroupView) {
p2 = ((GroupView)n).getPath(canvas, paint, op);
} else {
p2 = n.getPath(canvas, paint);
}
p2.transform(transform);
path.op(p2, pop);
}
});
}
} else {
Rect clipBounds = canvas.getClipBounds();
final Region bounds = new Region(clipBounds);
final Region r = new Region();
traverseChildren(new NodeRunnable() {
public void run(View node) {
if (node instanceof VirtualView) {
VirtualView n = (VirtualView)node;
Matrix transform = n.mMatrix;
Path p2;
if (n instanceof GroupView) {
p2 = ((GroupView)n).getPath(canvas, paint, op);
} else {
p2 = n.getPath(canvas, paint);
}
p2.transform(transform);
Region r2 = new Region();
r2.setPath(p2, bounds);
r.op(r2, op);
for (int i = 0; i < getChildCount(); i++) {
View node = getChildAt(i);
if (node instanceof VirtualView) {
VirtualView n = (VirtualView)node;
Matrix transform = n.mMatrix;
Path p2;
if (n instanceof GroupView) {
p2 = ((GroupView)n).getPath(canvas, paint, op);
} else {
p2 = n.getPath(canvas, paint);
}
p2.transform(transform);
Region r2 = new Region();
r2.setPath(p2, bounds);
r.op(r2, op);
}
});
}
path.addPath(r.getBoundaryPath());
}
@@ -236,23 +231,21 @@ class GroupView extends RenderableView {
getSvgView().defineTemplate(this, mName);
}
traverseChildren(new NodeRunnable() {
public void run(View node) {
if (node instanceof VirtualView) {
((VirtualView)node).saveDefinition();
}
for (int i = 0; i < getChildCount(); i++) {
View node = getChildAt(i);
if (node instanceof VirtualView) {
((VirtualView)node).saveDefinition();
}
});
}
}
@Override
void resetProperties() {
traverseChildren(new NodeRunnable() {
public void run(View node) {
if (node instanceof RenderableView) {
((RenderableView)node).resetProperties();
}
for (int i = 0; i < getChildCount(); i++) {
View node = getChildAt(i);
if (node instanceof RenderableView) {
((RenderableView)node).resetProperties();
}
});
}
}
}
@@ -40,9 +40,7 @@ import static com.horcrux.svg.RenderableView.FILL_RULE_NONZERO;
import static com.horcrux.svg.RenderableView.JOIN_ROUND;
/**
* ViewManager for all shadowed RNSVG views: Group, Path and Text. Since these never get rendered
* into native views and don't need any logic (all the logic is in {@link SvgView}), this
* "stubbed" ViewManager is used for all of them.
* ViewManager for all RNSVG views
*/
class RenderableViewManager extends ViewGroupManager<VirtualView> {
@@ -987,15 +985,4 @@ class RenderableViewManager extends ViewGroupManager<VirtualView> {
throw new IllegalStateException("Unexpected type " + svgClass.toString());
}
}
@Override
public void updateExtraData(VirtualView root, Object extraData) {
throw new IllegalStateException("SVG elements does not map into a native view");
}
@Override
public void onDropViewInstance(VirtualView view) {
super.onDropViewInstance(view);
}
}
@@ -14,7 +14,6 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
@@ -26,7 +25,6 @@ import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.DisplayMetricsHolder;
import com.facebook.react.uimanager.ReactCompoundView;
import com.facebook.react.uimanager.ReactCompoundViewGroup;
import com.facebook.react.uimanager.ReactShadowNodeImpl;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.views.view.ReactViewGroup;
@@ -93,46 +91,11 @@ public class SvgView extends ReactViewGroup implements ReactCompoundView, ReactC
canvas.drawBitmap(mBitmap, 0, 0, null);
}
private SvgViewShadowNode getShadowNode() {
return SvgViewManager.getShadowNodeByTag(getId());
}
@Override
public int reactTagForTouch(float touchX, float touchY) {
return hitTest(new Point((int) touchX, (int) touchY));
return hitTest(touchX, touchY);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
ReactShadowNodeImpl node = getShadowNode();
for (int i = 0; i < this.getChildCount(); i++) {
View child = this.getChildAt(i);
if (child instanceof VirtualView) {
continue;
}
if (child instanceof ReactViewGroup) {
int id = child.getId();
for (int j = 0; j < node.getChildCount(); j++) {
ReactShadowNodeImpl nodeChild = node.getChildAt(j);
if (nodeChild.getReactTag() != id) {
continue;
}
float x = nodeChild.getLayoutX();
float y = nodeChild.getLayoutY();
float nr = x + nodeChild.getLayoutWidth();
float nb = y + nodeChild.getLayoutHeight();
child.layout(Math.round(x), Math.round(y), Math.round(nr), Math.round(nb));
break;
}
} else {
child.layout(l, t, r , b);
}
}
}
private boolean mResponsible = false;
private final Map<String, VirtualView> mDefinedClipPaths = new HashMap<>();
@@ -160,14 +123,13 @@ public class SvgView extends ReactViewGroup implements ReactCompoundView, ReactC
return;
}
mRendered = false;
traverseChildren(new VirtualView.NodeRunnable() {
public void run(View node) {
if (node instanceof VirtualView) {
VirtualView n = ((VirtualView)node);
n.releaseCachedPath();
}
for (int i = 0; i < getChildCount(); i++) {
View node = getChildAt(i);
if (node instanceof VirtualView) {
VirtualView n = ((VirtualView)node);
n.releaseCachedPath();
}
});
}
}
@ReactProp(name = "tintColor", customType = "Color")
@@ -291,28 +253,26 @@ public class SvgView extends ReactViewGroup implements ReactCompoundView, ReactC
paint.setTypeface(Typeface.DEFAULT);
traverseChildren(new VirtualView.NodeRunnable() {
public void run(View node) {
if (node instanceof VirtualView) {
((VirtualView)node).saveDefinition();
for (int i = 0; i < getChildCount(); i++) {
View node = getChildAt(i);
if (node instanceof VirtualView) {
((VirtualView)node).saveDefinition();
}
}
for (int i = 0; i < getChildCount(); i++) {
View lNode = getChildAt(i);
if (lNode instanceof VirtualView) {
VirtualView node = (VirtualView)lNode;
int count = node.saveAndSetupCanvas(canvas);
node.render(canvas, paint, 1f);
node.restoreCanvas(canvas, count);
if (node.isResponsible() && !mResponsible) {
mResponsible = true;
}
}
});
traverseChildren(new VirtualView.NodeRunnable() {
public void run(View lNode) {
if (lNode instanceof VirtualView) {
VirtualView node = (VirtualView)lNode;
int count = node.saveAndSetupCanvas(canvas);
node.render(canvas, paint, 1f);
node.restoreCanvas(canvas, count);
if (node.isResponsible() && !mResponsible) {
mResponsible = true;
}
}
}
});
}
}
private RectF getViewBox() {
@@ -339,12 +299,12 @@ public class SvgView extends ReactViewGroup implements ReactCompoundView, ReactC
}
}
private int hitTest(Point point) {
private int hitTest(float touchX, float touchY) {
if (!mResponsible || !mInvertible) {
return getId();
}
float[] transformed = { point.x, point.y };
float[] transformed = { touchX, touchY };
mInvViewBoxMatrix.mapPoints(transformed);
int count = getChildCount();
@@ -395,12 +355,4 @@ public class SvgView extends ReactViewGroup implements ReactCompoundView, ReactC
VirtualView getDefinedMask(String maskRef) {
return mDefinedMasks.get(maskRef);
}
void traverseChildren(VirtualView.NodeRunnable runner) {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
runner.run(child);
}
}
}
@@ -15,10 +15,6 @@ import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.views.view.ReactViewGroup;
import com.facebook.react.views.view.ReactViewManager;
import com.facebook.yoga.YogaMeasureFunction;
import com.facebook.yoga.YogaMeasureMode;
import com.facebook.yoga.YogaMeasureOutput;
import com.facebook.yoga.YogaNode;
import javax.annotation.Nullable;
@@ -30,25 +26,8 @@ class SvgViewManager extends ReactViewManager {
private static final String REACT_CLASS = "RNSVGSvgView";
private static final YogaMeasureFunction MEASURE_FUNCTION = new YogaMeasureFunction() {
@Override
public long measure(
YogaNode node,
float width,
YogaMeasureMode widthMode,
float height,
YogaMeasureMode heightMode) {
return YogaMeasureOutput.make(width, height);
}
};
private static final SparseArray<SvgViewShadowNode> mTagToShadowNode = new SparseArray<>();
private static final SparseArray<SvgView> mTagToSvgView = new SparseArray<>();
static void setShadowNode(SvgViewShadowNode shadowNode) {
mTagToShadowNode.put(shadowNode.getReactTag(), shadowNode);
}
static void setSvgView(SvgView svg) {
mTagToSvgView.put(svg.getId(), svg);
}
@@ -57,27 +36,11 @@ class SvgViewManager extends ReactViewManager {
return mTagToSvgView.get(tag);
}
static @Nullable SvgViewShadowNode getShadowNodeByTag(int tag) {
return mTagToShadowNode.get(tag);
}
@Override
public String getName() {
return REACT_CLASS;
}
@Override
public Class<SvgViewShadowNode> getShadowNodeClass() {
return SvgViewShadowNode.class;
}
@Override
public SvgViewShadowNode createShadowNodeInstance() {
SvgViewShadowNode node = new SvgViewShadowNode();
node.setMeasureFunction(MEASURE_FUNCTION);
return node;
}
@Override
public SvgView createViewInstance(ThemedReactContext reactContext) {
return new SvgView(reactContext);
@@ -92,10 +55,7 @@ class SvgViewManager extends ReactViewManager {
@Override
public void onDropViewInstance(ReactViewGroup view) {
super.onDropViewInstance(view);
int tag = view.getId();
mTagToShadowNode.remove(tag);
mTagToSvgView.remove(tag);
mTagToSvgView.remove(view.getId());
}
@Override
@@ -29,7 +29,7 @@ import javax.annotation.Nullable;
import static com.horcrux.svg.FontData.DEFAULT_FONT_SIZE;
@SuppressLint("ViewConstructor")
abstract public class VirtualView<T extends VirtualView> extends ViewGroup {
abstract public class VirtualView extends ViewGroup {
final ReactContext mContext;
VirtualView(ReactContext reactContext) {
@@ -110,13 +110,12 @@ abstract public class VirtualView<T extends VirtualView> extends ViewGroup {
void releaseCachedPath() {
clearPath();
traverseChildren(new NodeRunnable() {
public void run(View node) {
if (node instanceof VirtualView) {
((VirtualView)node).releaseCachedPath();
}
for (int i = 0; i < getChildCount(); i++) {
View node = getChildAt(i);
if (node instanceof VirtualView) {
((VirtualView)node).releaseCachedPath();
}
});
}
}
@Nullable
@@ -384,17 +383,6 @@ abstract public class VirtualView<T extends VirtualView> extends ViewGroup {
}
}
interface NodeRunnable {
void run(View node);
}
void traverseChildren(NodeRunnable runner) {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
runner.run(child);
}
}
void setClientRect(RectF rect) {
if (mClientRect != null && mClientRect.equals(rect)) {
return;