Skip to content
This repository was archived by the owner on Jul 13, 2022. It is now read-only.

Commit 9f127d0

Browse files
committed
example assertion
1 parent 2cda660 commit 9f127d0

File tree

3 files changed

+27
-12
lines changed

3 files changed

+27
-12
lines changed

CanvasExample/App/DeclarativeUpdate.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import _ from 'lodash';
33
import React, { useRef } from 'react';
44
import { PanGestureHandler } from 'react-native-gesture-handler';
55
import RCanvas, { generatePathId, RCanvasRef, RPath, RPathData } from 'react-native-reanimated-canvas';
6-
import { styles } from './common';
6+
import { styles, usePathUpdateAssertion } from './common';
77
import { useState } from 'react';
88
import { useEffect } from 'react';
99

@@ -19,7 +19,8 @@ function genPathData(id = generatePathId()) {
1919
}
2020

2121
export default function CustomTouchHandling() {
22-
const refA = useRef<RCanvasRef & PanGestureHandler>();
22+
const ref = useRef<RCanvasRef & PanGestureHandler>();
23+
const onChange = usePathUpdateAssertion(ref);
2324
const [paths, setPaths] = useState(_.map(new Array(10).fill(0), () => genPathData()));
2425
useEffect(() => {
2526
let t = setInterval(() => {
@@ -32,9 +33,9 @@ export default function CustomTouchHandling() {
3233
style={styles.default}
3334
strokeColor='red'
3435
strokeWidth={20}
35-
ref={refA}
36+
ref={ref}
3637
renderToHardwareTextureAndroid={false}
37-
onChange={e => console.log(e.nativeEvent.paths)}
38+
onChange={onChange}
3839
>
3940
{_.map(paths, (data, i) => <RPath {...data} key={`DRPath${i}`} id={9001 + i * 3} />)}
4041
</RCanvas>

CanvasExample/App/Updater.tsx

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import _ from 'lodash';
33
import React, { useEffect, useRef, useState } from 'react';
44
import { Text } from 'react-native';
55
import RCanvas, { generatePathId, RCanvasRef, RPath, RPathData, PathChangeData } from 'react-native-reanimated-canvas';
6-
import { styles } from './common';
6+
import { styles, usePathUpdateAssertion } from './common';
77

88
const points = new Array(200).fill(0).map((v, i) => ({ x: i, y: i }));
99

@@ -17,7 +17,8 @@ function genPathData(id = generatePathId()) {
1717
}
1818

1919
export default function CustomTouchHandling() {
20-
const refA = useRef<RCanvasRef>();
20+
const ref = useRef<RCanvasRef>();
21+
const onChange = usePathUpdateAssertion(ref);
2122
const [renderToHWT, setHWT] = useState(false);
2223
const [paths, setPaths] = useState([genPathData()]);
2324
/*
@@ -46,17 +47,17 @@ export default function CustomTouchHandling() {
4647
{ id, value: genPathData(id) }
4748
];
4849

49-
if (refA.current && refA.current.getPaths().length > 0 && i % 2 === 0) {
50-
const size = refA.current.getPaths().length
51-
const path = refA.current.getPaths()[Math.round(Math.random() * size) % size];
50+
if (ref.current && ref.current.getPaths().length > 0 && i % 2 === 0) {
51+
const size = ref.current.getPaths().length
52+
const path = ref.current.getPaths()[Math.round(Math.random() * size) % size];
5253
updater.push({ id: path.id, value: null });
5354
}
5455

5556
if (i % (renderToHWT ? 2 : 5) === 0) {
5657
setHWT(!renderToHWT)
5758
}
5859

59-
refA.current && refA.current.update(updater);
60+
ref.current && ref.current.update(updater);
6061
}, 1000);
6162
return () => clearImmediate(t);
6263
}, [renderToHWT]);
@@ -67,9 +68,9 @@ export default function CustomTouchHandling() {
6768
style={styles.default}
6869
strokeColor='red'
6970
strokeWidth={20}
70-
ref={refA}
71+
ref={ref}
7172
renderToHardwareTextureAndroid={renderToHWT}
72-
onChange={e => console.log(e.nativeEvent)}
73+
onChange={onChange}
7374
>
7475
{_.map(paths, data => <RPath {...data} key={data.id} />)}
7576
</RCanvas>

CanvasExample/App/common.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import { useCallback, useRef } from 'react';
33
import { StyleSheet } from 'react-native';
44
import Animated, { block, Clock, clockRunning, cond, debug, Easing, greaterOrEq, not, set, spring, startClock, stopClock, sub, timing, Value } from 'react-native-reanimated';
5+
import { ChangeEvent, RCanvasRef, RPathData } from 'react-native-reanimated-canvas';
6+
import _ from 'lodash';
57

68
export function useRefGetter<T, R = T>(initialValue?: T, action: (ref: T) => R = (current) => (current as unknown as R)) {
79
const ref = useRef(initialValue);
@@ -17,6 +19,17 @@ export function useRefGetter<T, R = T>(initialValue?: T, action: (ref: T) => R =
1719
return [ref, getter, defaultGetter] as [typeof ref, typeof getter, typeof defaultGetter];
1820
}
1921

22+
export function usePathUpdateAssertion(ref: React.RefObject<RCanvasRef | undefined>) {
23+
return useCallback((e: ChangeEvent) => {
24+
const { paths, added, changed, removed } = e.nativeEvent;
25+
const refPaths = ref.current?.getPaths();
26+
const withoutRemoved = (paths?: RPathData[]) => _.intersectionWith(paths, _.concat(added, changed), (a, b) => a.id === b);
27+
const clean = _.intersectionWith(refPaths, removed, (a, b) => a.id === b).length === 0;
28+
const assert = _.isEqual(withoutRemoved(paths), withoutRemoved(refPaths)) && clean;
29+
if (!assert) throw new Error('assertion error: RCAnvas paths are not in sync with last update');
30+
}, [ref]);
31+
}
32+
2033
export function runSpring(clock: Animated.Clock, value: Animated.Adaptable<number>, dest: Animated.Adaptable<number>) {
2134
const state = {
2235
finished: new Value(0),

0 commit comments

Comments
 (0)