Skip to content

Commit c66f486

Browse files
authored
refactor: split makeMutable to web and native implementations (software-mansion#6307)
## Summary Currently Web and Native implementations of `makeMutable` are bundled together and are hard to read. I split them for more clarity in the code, and also to prepare `makeMutable` for its further changes. ## Test plan - [x] Runtime tests pass.
1 parent cea368e commit c66f486

File tree

2 files changed

+87
-70
lines changed

2 files changed

+87
-70
lines changed

src/layoutReanimation/animationsManager.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22
import { withStyleAnimation } from '../animation/styleAnimation';
33
import type { SharedValue } from '../commonTypes';
4-
import { makeUIMutable } from '../mutables';
4+
import { makeMutableUI } from '../mutables';
55
import { LayoutAnimationType } from './animationBuilder';
66
import { runOnUIImmediately } from '../threads';
77
import type {
@@ -73,7 +73,7 @@ function createLayoutAnimationManager(): {
7373

7474
let value = mutableValuesForTag.get(tag);
7575
if (value === undefined) {
76-
value = makeUIMutable(style.initialValues);
76+
value = makeMutableUI(style.initialValues);
7777
mutableValuesForTag.set(tag, value);
7878
} else {
7979
stopObservingProgress(tag, value);

src/mutables.ts

Lines changed: 85 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,47 @@
11
'use strict';
22
import { shouldBeUseWeb } from './PlatformChecker';
33
import type { Mutable } from './commonTypes';
4-
import { makeShareableCloneRecursive } from './shareables';
54
import { shareableMappingCache } from './shareableMappingCache';
5+
import { makeShareableCloneRecursive } from './shareables';
66
import { executeOnUIRuntimeSync, runOnUI } from './threads';
77
import { valueSetter } from './valueSetter';
88

99
const SHOULD_BE_USE_WEB = shouldBeUseWeb();
1010

1111
type Listener<Value> = (newValue: Value) => void;
1212

13-
export function makeUIMutable<Value>(initial: Value): Mutable<Value> {
13+
export function makeMutableUI<Value>(initial: Value): Mutable<Value> {
1414
'worklet';
15-
1615
const listeners = new Map<number, Listener<Value>>();
1716
let value = initial;
1817

19-
const self: Mutable<Value> = {
20-
set value(newValue) {
21-
valueSetter(self, newValue);
22-
},
18+
const mutable: Mutable<Value> = {
2319
get value() {
2420
return value;
2521
},
22+
set value(newValue) {
23+
valueSetter(mutable, newValue);
24+
},
25+
2626
/**
2727
* _value prop should only be accessed by the valueSetter implementation
2828
* which may make the decision about updating the mutable value depending
2929
* on the provided new value. All other places should only attempt to modify
3030
* the mutable by assigning to value prop directly.
3131
*/
32+
get _value(): Value {
33+
return value;
34+
},
3235
set _value(newValue: Value) {
3336
value = newValue;
3437
listeners.forEach((listener) => {
3538
listener(newValue);
3639
});
3740
},
38-
get _value(): Value {
39-
return value;
40-
},
41+
4142
modify: (modifier, forceUpdate = true) => {
4243
valueSetter(
43-
self,
44+
mutable,
4445
modifier !== undefined ? modifier(value) : value,
4546
forceUpdate
4647
);
@@ -51,94 +52,110 @@ export function makeUIMutable<Value>(initial: Value): Mutable<Value> {
5152
removeListener: (id: number) => {
5253
listeners.delete(id);
5354
},
55+
5456
_animation: null,
5557
_isReanimatedSharedValue: true,
5658
};
57-
return self;
59+
return mutable;
5860
}
5961

60-
export function makeMutable<Value>(initial: Value): Mutable<Value> {
61-
let value: Value = initial;
62+
function makeMutableNative<Value>(initial: Value): Mutable<Value> {
6263
const handle = makeShareableCloneRecursive({
6364
__init: () => {
6465
'worklet';
65-
return makeUIMutable(initial);
66+
return makeMutableUI(initial);
6667
},
6768
});
68-
// listeners can only work on JS thread on Web and jest environments
69-
const listeners = SHOULD_BE_USE_WEB
70-
? new Map<number, Listener<Value>>()
71-
: undefined;
69+
7270
const mutable: Mutable<Value> = {
73-
set value(newValue) {
74-
if (SHOULD_BE_USE_WEB) {
75-
valueSetter(mutable, newValue);
76-
} else {
77-
runOnUI(() => {
78-
mutable.value = newValue;
79-
})();
80-
}
81-
},
8271
get value(): Value {
83-
if (SHOULD_BE_USE_WEB) {
84-
return value;
85-
}
8672
const uiValueGetter = executeOnUIRuntimeSync((sv: Mutable<Value>) => {
8773
return sv.value;
8874
});
8975
return uiValueGetter(mutable);
9076
},
91-
set _value(newValue: Value) {
92-
if (!SHOULD_BE_USE_WEB) {
93-
throw new Error(
94-
'[Reanimated] Setting `_value` directly is only possible on the UI runtime. Perhaps you want to assign to `value` instead?'
95-
);
96-
}
97-
value = newValue;
98-
listeners!.forEach((listener) => {
99-
listener(newValue);
100-
});
77+
set value(newValue) {
78+
runOnUI(() => {
79+
mutable.value = newValue;
80+
})();
10181
},
82+
10283
get _value(): Value {
103-
if (SHOULD_BE_USE_WEB) {
104-
return value;
105-
}
10684
throw new Error(
10785
'[Reanimated] Reading from `_value` directly is only possible on the UI runtime. Perhaps you passed an Animated Style to a non-animated component?'
10886
);
10987
},
88+
set _value(_newValue: Value) {
89+
throw new Error(
90+
'[Reanimated] Setting `_value` directly is only possible on the UI runtime. Perhaps you want to assign to `value` instead?'
91+
);
92+
},
93+
94+
modify: (modifier, forceUpdate = true) => {
95+
runOnUI(() => {
96+
mutable.modify(modifier, forceUpdate);
97+
})();
98+
},
99+
addListener: () => {
100+
throw new Error(
101+
'[Reanimated] Adding listeners is only possible on the UI runtime.'
102+
);
103+
},
104+
removeListener: () => {
105+
throw new Error(
106+
'[Reanimated] Removing listeners is only possible on the UI runtime.'
107+
);
108+
},
109+
110+
_isReanimatedSharedValue: true,
111+
};
112+
113+
shareableMappingCache.set(mutable, handle);
114+
return mutable;
115+
}
116+
117+
function makeMutableWeb<Value>(initial: Value): Mutable<Value> {
118+
let value: Value = initial;
119+
const listeners = new Map<number, Listener<Value>>();
120+
121+
const mutable: Mutable<Value> = {
122+
get value(): Value {
123+
return value;
124+
},
125+
set value(newValue) {
126+
valueSetter(mutable, newValue);
127+
},
128+
129+
get _value(): Value {
130+
return value;
131+
},
132+
set _value(newValue: Value) {
133+
value = newValue;
134+
listeners.forEach((listener) => {
135+
listener(newValue);
136+
});
137+
},
110138

111139
modify: (modifier, forceUpdate = true) => {
112-
if (!SHOULD_BE_USE_WEB) {
113-
runOnUI(() => {
114-
mutable.modify(modifier, forceUpdate);
115-
})();
116-
} else {
117-
valueSetter(
118-
mutable,
119-
modifier !== undefined ? modifier(mutable.value) : mutable.value,
120-
forceUpdate
121-
);
122-
}
140+
valueSetter(
141+
mutable,
142+
modifier !== undefined ? modifier(mutable.value) : mutable.value,
143+
forceUpdate
144+
);
123145
},
124146
addListener: (id: number, listener: Listener<Value>) => {
125-
if (!SHOULD_BE_USE_WEB) {
126-
throw new Error(
127-
'[Reanimated] Adding listeners is only possible on the UI runtime.'
128-
);
129-
}
130-
listeners!.set(id, listener);
147+
listeners.set(id, listener);
131148
},
132149
removeListener: (id: number) => {
133-
if (!SHOULD_BE_USE_WEB) {
134-
throw new Error(
135-
'[Reanimated] Removing listeners is only possible on the UI runtime.'
136-
);
137-
}
138-
listeners!.delete(id);
150+
listeners.delete(id);
139151
},
152+
140153
_isReanimatedSharedValue: true,
141154
};
142-
shareableMappingCache.set(mutable, handle);
155+
143156
return mutable;
144157
}
158+
159+
export const makeMutable = SHOULD_BE_USE_WEB
160+
? makeMutableWeb
161+
: makeMutableNative;

0 commit comments

Comments
 (0)