Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
c48f5e9
Base for shared style
Nov 23, 2020
072d56b
Merge branch 'master' into shareable-useAnimatedStyle
piaskowyk Dec 14, 2020
55fb2a7
Add mutable set type with basic options
piaskowyk Dec 15, 2020
53a47d8
Add initialization and clear()
piaskowyk Dec 16, 2020
3640c1a
Try to fix android build
piaskowyk Dec 16, 2020
7769393
Add support for web
piaskowyk Dec 16, 2020
dc2712a
Rename properties
piaskowyk Dec 17, 2020
8bb996f
Improvements after review
piaskowyk Dec 18, 2020
5d9480c
Merge
piaskowyk Dec 18, 2020
9f9de3a
Test with batch
piaskowyk Dec 23, 2020
588f7d2
V2
piaskowyk Dec 28, 2020
d873561
Version 3
piaskowyk Dec 28, 2020
f87fe47
Web support
piaskowyk Dec 28, 2020
0df3b77
Merge with new version
piaskowyk Dec 28, 2020
c1b5e42
Clean up
piaskowyk Dec 28, 2020
60f1af7
Merge branch 'master' into shareable-useAnimatedStyle
piaskowyk Jan 5, 2021
9c1eb71
Update name of descriptor
piaskowyk Jan 5, 2021
b4ccb49
Merge remote-tracking branch 'origin/master' into shareable-useAnimat…
Jan 18, 2021
bbdb7df
remove redundant changes
Jan 18, 2021
1efbb4e
Merge remote-tracking branch 'origin/master' into shareable-useAnimat…
Jan 19, 2021
fb93a18
merge
piaskowyk Feb 8, 2021
ad8bbc0
merge
piaskowyk Feb 8, 2021
734bd2f
Add to mapper dependency
piaskowyk Feb 8, 2021
5f929e5
Merge branch 'master' of github.com:software-mansion/react-native-rea…
piaskowyk Feb 10, 2021
94df713
Handling non rerendered components
piaskowyk Feb 12, 2021
67ff82d
indexOf -> incluses
piaskowyk Feb 12, 2021
6497a3a
Simplification of viewDescriptorsSet
piaskowyk Feb 12, 2021
08fc711
Remove unused variable
piaskowyk Feb 12, 2021
1623a8f
Add _viewTag proerty
piaskowyk Feb 12, 2021
6be168e
Before merge
piaskowyk Mar 5, 2021
afe316b
Merge
piaskowyk Mar 5, 2021
be97fbb
Fix initial style for multiple components
piaskowyk Mar 10, 2021
ac258c4
Resolve conflict
piaskowyk Mar 10, 2021
4068500
Remove debug logs
piaskowyk Mar 10, 2021
66fee65
Clean up
piaskowyk Mar 10, 2021
6f92856
Update web support
piaskowyk Mar 10, 2021
e8a085a
Update initial style for new components
piaskowyk Mar 11, 2021
7eedf0e
Sync with master
piaskowyk Jul 15, 2021
6ad3d84
Sync UpdateProps
piaskowyk Jul 15, 2021
7034ca3
Remove old JS files
piaskowyk Jul 15, 2021
e8411d2
Added support for optimalization
piaskowyk Jul 16, 2021
bb3963b
Update plugin
piaskowyk Jul 16, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 6 additions & 10 deletions Common/cpp/NativeModules/NativeReanimatedModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,7 @@ jsi::Value NativeReanimatedModule::startMapper(
const jsi::Value &inputs,
const jsi::Value &outputs,
const jsi::Value &updater,
const jsi::Value &tag,
const jsi::Value &name
)
const jsi::Value &viewDescriptors)
{
static unsigned long MAPPER_ID = 1;

Expand All @@ -136,8 +134,7 @@ jsi::Value NativeReanimatedModule::startMapper(
optimalizationLvl = optimalization.asNumber();
}
auto updaterSV = ShareableValue::adapt(rt, updater, this);
const int tagInt = tag.asNumber();
const std::string nameStr = name.asString(rt).utf8(rt);
auto viewDescriptorsSV = ShareableValue::adapt(rt, viewDescriptors, this);

scheduler->scheduleOnUI([=] {
auto mapperFunction = mapperShareable->getValue(*runtime).asObject(*runtime).asFunction(*runtime);
Expand All @@ -148,12 +145,11 @@ jsi::Value NativeReanimatedModule::startMapper(
newMapperId,
mapperFunctionPointer,
inputMutables,
outputMutables,
updaterSV,
tagInt,
nameStr,
optimalizationLvl
outputMutables
);
if(optimalizationLvl > 0) {
mapperPointer->enableFastMode(optimalizationLvl, updaterSV, viewDescriptorsSV);
}
mapperRegistry->startMapper(mapperPointer);
maybeRequestRender();
});
Expand Down
5 changes: 2 additions & 3 deletions Common/cpp/NativeModules/NativeReanimatedModuleSpec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ static jsi::Value __hostFunction_NativeReanimatedModuleSpec_startMapper(
std::move(args[1]),
std::move(args[2]),
std::move(args[3]),
std::move(args[4]),
std::move(args[5]));
std::move(args[4]));
}

static jsi::Value __hostFunction_NativeReanimatedModuleSpec_stopMapper(
Expand Down Expand Up @@ -110,7 +109,7 @@ NativeReanimatedModuleSpec::NativeReanimatedModuleSpec(std::shared_ptr<CallInvok


methodMap_["startMapper"] = MethodMetadata{
6, __hostFunction_NativeReanimatedModuleSpec_startMapper};
5, __hostFunction_NativeReanimatedModuleSpec_startMapper};
methodMap_["stopMapper"] = MethodMetadata{
1, __hostFunction_NativeReanimatedModuleSpec_stopMapper};

Expand Down
49 changes: 33 additions & 16 deletions Common/cpp/Tools/Mapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,13 @@ Mapper::Mapper(NativeReanimatedModule *module,
unsigned long id,
std::shared_ptr<jsi::Function> mapper,
std::vector<std::shared_ptr<MutableValue>> inputs,
std::vector<std::shared_ptr<MutableValue>> outputs,
std::shared_ptr<ShareableValue> updater,
const int viewTag,
const std::string& viewName,
const int optimalizationLvl):
std::vector<std::shared_ptr<MutableValue>> outputs):
id(id),
module(module),
mapper(mapper),
inputs(inputs),
outputs(outputs),
viewTag(viewTag),
optimalizationLvl(optimalizationLvl)
outputs(outputs)
{
jsi::Runtime* rt = module->runtime.get();
this->viewName = jsi::Value(*rt, jsi::String::createFromUtf8(*rt, viewName));
updateProps = &module->updaterFunction;
userUpdater = std::make_shared<jsi::Function>(updater->getValue(*rt).asObject(*rt).asFunction(*rt));


auto markDirty = [this, module]() {
this->dirty = true;
module->maybeRequestRender();
Expand All @@ -39,11 +27,40 @@ optimalizationLvl(optimalizationLvl)
void Mapper::execute(jsi::Runtime &rt) {
dirty = false;
if(optimalizationLvl == 0) {
mapper->callWithThis(rt, *mapper);// call styleUpdater
mapper->callWithThis(rt, *mapper); // call styleUpdater
}
else {
(*updateProps)(rt, viewTag, viewName, userUpdater->call(rt).asObject(rt));
for(auto& viewDescriptor : viewDescriptors) {
(*updateProps)(rt, viewDescriptor.tag, viewDescriptor.name, userUpdater->call(rt).asObject(rt));
}
}
}

void Mapper::enableFastMode(
const int optimalizationLvl,
const std::shared_ptr<ShareableValue>& updater,
const std::shared_ptr<ShareableValue>& jsViewDescriptors
) {
if(optimalizationLvl == 0) {
return;
}
this->optimalizationLvl = optimalizationLvl;
updateProps = &module->updaterFunction;
jsi::Runtime* rt = module->runtime.get();
userUpdater = std::make_shared<jsi::Function>(updater->getValue(*rt).asObject(*rt).asFunction(*rt));
auto jsViewDescriptorArray = jsViewDescriptors->getValue(*rt)
.getObject(*rt)
.getProperty(*rt, "value")
.asObject(*rt)
.getArray(*rt);
for(int i = 0; i < jsViewDescriptorArray.length(*rt); ++i) {
auto jsViewDescriptor = jsViewDescriptorArray.getValueAtIndex(*rt, i).getObject(*rt);
viewDescriptors.push_back(ViewDescriptor {
(int)jsViewDescriptor.getProperty(*rt, "tag").asNumber(),
jsViewDescriptor.getProperty(*rt, "name"),
});
}

}

Mapper::~Mapper() {
Expand Down
3 changes: 1 addition & 2 deletions Common/cpp/headers/NativeModules/NativeReanimatedModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ class NativeReanimatedModule : public NativeReanimatedModuleSpec, public Runtime
const jsi::Value &inputs,
const jsi::Value &outputs,
const jsi::Value &updater,
const jsi::Value &tag,
const jsi::Value &name) override;
const jsi::Value &viewDescriptors) override;
void stopMapper(jsi::Runtime &rt, const jsi::Value &mapperId) override;

jsi::Value registerEventHandler(jsi::Runtime &rt, const jsi::Value &eventHash, const jsi::Value &worklet) override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ class JSI_EXPORT NativeReanimatedModuleSpec : public TurboModule {
const jsi::Value &inputs,
const jsi::Value &outputs,
const jsi::Value &updater,
const jsi::Value &tag,
const jsi::Value &name) = 0;
const jsi::Value &viewDescriptors) = 0;
virtual void stopMapper(jsi::Runtime &rt, const jsi::Value &mapperId) = 0;

// events
Expand Down
19 changes: 12 additions & 7 deletions Common/cpp/headers/Tools/Mapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ namespace reanimated {

class MapperRegistry;

struct ViewDescriptor {
int tag;
jsi::Value name;
};

class Mapper : public std::enable_shared_from_this<Mapper> {
friend MapperRegistry;
private:
Expand All @@ -22,21 +27,21 @@ class Mapper : public std::enable_shared_from_this<Mapper> {
bool dirty = true;
std::shared_ptr<jsi::Function> userUpdater;
UpdaterFunction* updateProps;
jsi::Value viewName;
int viewTag;
std::vector<ViewDescriptor> viewDescriptors;
int optimalizationLvl = 0;

public:
Mapper(NativeReanimatedModule *module,
unsigned long id,
std::shared_ptr<jsi::Function> mapper,
std::vector<std::shared_ptr<MutableValue>> inputs,
std::vector<std::shared_ptr<MutableValue>> outputs,
std::shared_ptr<ShareableValue> updater,
const int viewTag,
const std::string& viewName,
const int optimalizationLvl);
std::vector<std::shared_ptr<MutableValue>> outputs);
void execute(jsi::Runtime &rt);
void enableFastMode(
const int optimalizationLvl,
const std::shared_ptr<ShareableValue>& updater,
const std::shared_ptr<ShareableValue>&jsViewDescriptors
);
virtual ~Mapper();
};

Expand Down
2 changes: 1 addition & 1 deletion Example/src/AnimatedStyleUpdateExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@ function AnimatedStyleUpdateExample(): React.ReactElement {
);
}

export default AnimatedStyleUpdateExample;
export default AnimatedStyleUpdateExample;
21 changes: 12 additions & 9 deletions plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ const blacklistedFunctions = new Set([
'apply',
'call',
'__callAsync',
'includes',
]);

const possibleOptFunction = new Set(['interpolate']);
Expand Down Expand Up @@ -275,7 +276,7 @@ function buildWorkletString(t, fun, closureVariables, name) {
return generate(workletFunction, { compact: true }).code;
}

function processWorkletFunction(t, fun, fileName, options = {}) {
function processWorkletFunction(t, fun, fileName) {
if (!t.isFunctionParent(fun)) {
return;
}
Expand All @@ -284,6 +285,7 @@ function processWorkletFunction(t, fun, fileName, options = {}) {
const closure = new Map();
const outputs = new Set();
const closureGenerator = new ClosureGenerator();
const options = {};

// We use copy because some of the plugins don't update bindings and
// some even break them
Expand All @@ -302,7 +304,13 @@ function processWorkletFunction(t, fun, fileName, options = {}) {
babelrc: false,
configFile: false,
});

if (
fun.parent &&
fun.parent.callee &&
fun.parent.callee.name === 'useAnimatedStyle'
) {
options.optFlags = isPossibleOptimization(transformed.ast);
}
traverse(transformed.ast, {
ReferencedIdentifier(path) {
const name = path.node.name;
Expand Down Expand Up @@ -498,12 +506,7 @@ function processIfWorkletNode(t, fun, fileName) {
directive.value.value === 'worklet'
)
) {
const flags = isPossibleOptimization(fun);
if (flags) {
processWorkletFunction(t, fun, fileName, { optFlags: flags });
} else {
processWorkletFunction(t, fun, fileName);
}
processWorkletFunction(t, fun, fileName);
}
}
},
Expand Down Expand Up @@ -547,7 +550,7 @@ const STATEMENTLESS_FLAG = 0b00000010;
function isPossibleOptimization(fun) {
let isFunctionCall = false;
let isSteatements = false;
fun.scope.path.traverse({
traverse(fun, {
CallExpression(path) {
if (!possibleOptFunction.has(path.node.callee.name)) {
isFunctionCall = true;
Expand Down
57 changes: 39 additions & 18 deletions src/createAnimatedComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ export default function createAnimatedComponent(Component, options = {}) {

class AnimatedComponent extends React.Component {
_invokeAnimatedPropsCallbackOnMount = false;
_styles = null;
_viewTag = -1;

constructor(props) {
super(props);
Expand All @@ -87,6 +89,7 @@ export default function createAnimatedComponent(Component, options = {}) {
this._detachPropUpdater();
this._propsAnimated && this._propsAnimated.__detach();
this._detachNativeEvents();
this._detachStyles();
this.sv = null;
}

Expand Down Expand Up @@ -143,6 +146,25 @@ export default function createAnimatedComponent(Component, options = {}) {
}
}

_detachStyles() {
if (Platform.OS === 'web') {
for (const style of this._styles) {
if (style.viewsRef) {
style.viewsRef.remove(this);
}
}
} else if (this._viewTag !== -1) {
for (const style of this._styles) {
if (style?.viewDescriptors) {
style.viewDescriptors.remove(this._viewTag);
}
}
if (this.props.animatedProps?.viewDescriptors) {
this.props.animatedProps.viewDescriptors.remove(this._viewTag);
}
}
}

_reattachNativeEvents(prevProps) {
const node = this._getEventViewRef();
const attached = new Set();
Expand Down Expand Up @@ -261,6 +283,7 @@ export default function createAnimatedComponent(Component, options = {}) {
? this.props.style
: [this.props.style];
styles = flattenArray(styles);
this._styles = styles;
let viewTag, viewName;
if (Platform.OS === 'web') {
viewTag = findNodeHandle(this);
Expand Down Expand Up @@ -289,10 +312,11 @@ export default function createAnimatedComponent(Component, options = {}) {
adaptViewConfig(hostInstance.viewConfig);
}
}
this._viewTag = viewTag;

styles.forEach((style) => {
if (style?.viewDescriptor) {
style.viewDescriptor.value = { tag: viewTag, name: viewName };
if (style?.viewDescriptors) {
style.viewDescriptors.add({ tag: viewTag, name: viewName });
if (process.env.JEST_WORKER_ID) {
/**
* We need to connect Jest's TestObject instance whose contains just props object
Expand All @@ -302,29 +326,29 @@ export default function createAnimatedComponent(Component, options = {}) {
*/
this.animatedStyle.value = {
...this.animatedStyle.value,
...style.initial,
...style.initial.value,
};
style.animatedStyle.current = this.animatedStyle;
}
}
});
// attach animatedProps property
if (this.props.animatedProps?.viewDescriptor) {
this.props.animatedProps.viewDescriptor.value = {
if (this.props.animatedProps?.viewDescriptors) {
this.props.animatedProps.viewDescriptors.add({
tag: viewTag,
name: viewName,
};
});
}
}

_hasReanimated2Props(flattenStyles) {
if (this.props.animatedProps?.viewDescriptor) {
if (this.props.animatedProps?.viewDescriptors) {
return true;
}
if (this.props.style) {
for (const style of flattenStyles) {
// eslint-disable-next-line no-prototype-builtins
if (style?.hasOwnProperty('viewDescriptor')) {
if (style?.hasOwnProperty('viewDescriptors')) {
return true;
}
}
Expand All @@ -345,6 +369,7 @@ export default function createAnimatedComponent(Component, options = {}) {
this._reattachNativeEvents(prevProps);

this._propsAnimated && this._propsAnimated.setNativeView(this._component);
this._attachAnimatedStyles();
}

_setComponentRef = setAndForwardRef({
Expand Down Expand Up @@ -430,12 +455,10 @@ export default function createAnimatedComponent(Component, options = {}) {
if (key === 'style') {
const styles = Array.isArray(value) ? value : [value];
const processedStyle = styles.map((style) => {
if (style && style.viewDescriptor) {
if (style && style.viewDescriptors) {
// this is how we recognize styles returned by useAnimatedStyle
if (style.viewRef.current === null) {
style.viewRef.current = this;
}
return style.initial;
style.viewsRef.add(this);
return style.initial.value;
} else {
return style;
}
Expand All @@ -444,11 +467,9 @@ export default function createAnimatedComponent(Component, options = {}) {
StyleSheet.flatten(processedStyle)
);
} else if (key === 'animatedProps') {
Object.keys(value.initial).forEach((key) => {
props[key] = value.initial[key];
if (value.viewRef.current === null) {
value.viewRef.current = this;
}
Object.keys(value.initial.value).forEach((key) => {
props[key] = value.initial.value[key];
value.viewsRef.add(this);
});
} else if (value instanceof AnimatedEvent) {
// we cannot filter out event listeners completely as some components
Expand Down
Loading