Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
107 commits
Select commit Hold shift + click to select a range
bc75ddf
Init
piaskowyk Nov 16, 2023
a88ce0a
Implement PoC
piaskowyk Nov 18, 2023
20b1195
Refactor files
piaskowyk Nov 20, 2023
3c084c9
Update name
piaskowyk Nov 20, 2023
26912c9
Refactor part 2
piaskowyk Nov 20, 2023
6539b14
First commit
Nov 23, 2023
1f1a22e
Fix lint
Nov 23, 2023
c66ce67
Refactor
Nov 27, 2023
b157b9f
Fix for android
Nov 27, 2023
22b80c9
Add switch on android
Nov 27, 2023
4359587
Small adjustments
Nov 27, 2023
4ee628a
Add callTracker and sharedValueRegistry
piaskowyk Nov 30, 2023
db36e89
Number presets and other stuff
Nov 30, 2023
e0e2d94
Pass shadowNode to getViewProp
Dec 6, 2023
69fd445
Width & opacity for Fabric getViewProp
Dec 6, 2023
b9b56ee
Width & opacity for Fabric getViewProp
Dec 6, 2023
56c5391
Add colors to logs
Dec 6, 2023
451b5a7
Add support for color testing
Dec 8, 2023
0c7d24c
Color test
Dec 8, 2023
d37ddaa
Lint
Dec 11, 2023
fdc7a90
Fix types
Dec 11, 2023
4887d60
Merge branch 'main' into acynk/runtime-tests
Dec 12, 2023
b710063
Fix errors on CI
Dec 12, 2023
298f1e3
Fix errors on CI
Dec 12, 2023
7d827da
fix NaN = NaN
Dec 12, 2023
bbb9b74
Use install_modules_dependencies (#5334)
piaskowyk Nov 21, 2023
977307b
Merge to main
Dec 18, 2023
040fa76
Merge branch 'main' into @piaskowyk/runtime-tests
piaskowyk Dec 19, 2023
7ea67c1
Merge branch '@piaskowyk/runtime-tests' into acynk/runtime-tests
piaskowyk Dec 19, 2023
a748cb9
More Farbic props
Dec 21, 2023
cd64e77
More tests
Dec 21, 2023
1e5594b
Apply suggestions from code review
Latropos Dec 21, 2023
3066f6b
Update app/src/examples/RuntimeTests/ReanimatedRuntimeTestsRunner/Pre…
Latropos Dec 21, 2023
4916c6e
Clean podfile
Dec 21, 2023
ace92af
Merge branch 'main' into acynk/runtime-tests
piaskowyk Dec 28, 2023
8464a38
Color formatting on Fabric
Jan 3, 2024
8c6b020
Merge branch 'main' into acynk/runtime-tests
Jan 3, 2024
1c00155
Rename test files
Jan 3, 2024
5f1666c
Lint
Jan 3, 2024
9338e96
Fix build on macos
Jan 3, 2024
3e7720d
Fix if clause
Jan 3, 2024
42bc247
Add _Nullable of _Nonnull
Jan 3, 2024
28d0342
Fix on macos
Jan 3, 2024
73cfdf3
Use TS in `jestUtils.ts` (#5529)
tjzel Jan 2, 2024
9c17d39
Fix imports
Jan 3, 2024
3215fc8
Add missing import
Jan 4, 2024
dc5527d
Omit type UIColor on macOS
Jan 4, 2024
34a8e35
format
Jan 4, 2024
d8f4e5b
Refactor
Jan 4, 2024
3fc21cb
Refactor
Jan 4, 2024
fa35e28
Refactor
Jan 4, 2024
59b9cdd
Refactor
Jan 4, 2024
654dfef
Added blink detection
piaskowyk Jan 5, 2024
13735d2
Merge branch 'acynk/runtime-tests' of github.com:software-mansion/rea…
piaskowyk Jan 8, 2024
ecf7143
Merge branch 'main' into acynk/runtime-tests
piaskowyk Jan 8, 2024
611088b
Fix CI v1
piaskowyk Jan 8, 2024
a087bc7
Fix CI v2
piaskowyk Jan 8, 2024
6845f5f
Restore main branch changes
piaskowyk Jan 8, 2024
bb29479
Moved matchers to another file
piaskowyk Jan 8, 2024
c194f0d
Added summary
piaskowyk Jan 8, 2024
ebd275b
Improve TS
piaskowyk Jan 8, 2024
db712b9
Improve TS
piaskowyk Jan 8, 2024
8422492
merge
piaskowyk Jan 8, 2024
cf7bf50
Fix lint
piaskowyk Jan 8, 2024
c7c928f
Restore changes
piaskowyk Jan 8, 2024
d686f22
Improvements before review
piaskowyk Jan 9, 2024
d7b2e81
Merge with main
Feb 1, 2024
0a8aa28
Merge branch 'main' into acynk/runtime-tests
piaskowyk Feb 5, 2024
b57855a
Improve error messages
piaskowyk Feb 5, 2024
be3a20e
First part of review improvements
piaskowyk Feb 7, 2024
7612296
Public API Typescrip improvements
piaskowyk Feb 7, 2024
1105d37
Improve snapshot matching and some other refactors
piaskowyk Feb 7, 2024
8b35001
Add move comparators to separate file and run liner
piaskowyk Feb 7, 2024
6331825
Restore Java syntax
piaskowyk Feb 7, 2024
2cb0017
Fix git cache
piaskowyk Feb 7, 2024
866c8df
Update some names
piaskowyk Feb 7, 2024
7750198
Use jsi::Value in obtainProp
piaskowyk Feb 7, 2024
c999060
Fix Fabric shadowNodeWrapper
piaskowyk Feb 7, 2024
2a72709
Fix CI
piaskowyk Feb 8, 2024
a71261f
Merge branch 'main' into acynk/runtime-tests
Feb 13, 2024
5517943
Update Common/cpp/NativeModules/NativeReanimatedModule.cpp
Latropos Feb 13, 2024
ecb92b2
Separate getViewProp on Fabric and Paper
Feb 13, 2024
eff3b4b
Use auto type wherever possible
Feb 14, 2024
8ed8ac6
Change Java files
Feb 14, 2024
da99842
Apply suggestions from code review
Latropos Feb 14, 2024
ea20220
Further separation of Paper and Fabric code
Feb 14, 2024
2a5fabe
Better error message
Feb 14, 2024
e290221
Merge branch 'main' into acynk/runtime-tests
Feb 20, 2024
838b444
Fix color on macOS
Feb 20, 2024
13199fc
Merge branch 'main' into acynk/runtime-tests
Feb 21, 2024
45b3845
Merge branch 'main' into acynk/runtime-tests
Feb 21, 2024
fd3ad1a
Merge branch 'main' into acynk/runtime-tests
Latropos Feb 22, 2024
8f3f1c8
Merge branch 'main' into acynk/runtime-tests
Feb 22, 2024
ebbb375
Merge branch 'main' into acynk/runtime-tests
Feb 23, 2024
651d9db
Merge branch 'main' into acynk/runtime-tests
Feb 26, 2024
04e861a
Code review
Feb 26, 2024
9c1fd57
Code Review 2
Feb 26, 2024
e87dc0d
Code review 3
Feb 26, 2024
cd47cb3
Make fabric only
Feb 26, 2024
8c26ff8
Fix typo in comments
Latropos Feb 26, 2024
0abb8c5
Merge branch 'main' into acynk/runtime-tests
Mar 11, 2024
74d04f5
Code review
Mar 11, 2024
12bbb8e
Refactor tests
Feb 20, 2024
3be0c06
Merge branch 'main' into acynk/runtime-tests
Mar 12, 2024
56673ce
Remove _Nonnull
Mar 12, 2024
2e19b6c
Replace ' with `
Mar 12, 2024
1dd7052
Fix macos
Mar 12, 2024
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
148 changes: 123 additions & 25 deletions Common/cpp/NativeModules/NativeReanimatedModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
#endif

#include <functional>
#include <iomanip>
#include <memory>
#include <sstream>
#include <string>
#include <thread>
#include <unordered_map>

Expand Down Expand Up @@ -112,18 +115,27 @@ NativeReanimatedModule::NativeReanimatedModule(
const jsi::Value &argsValue) {
this->dispatchCommand(rt, shadowNodeValue, commandNameValue, argsValue);
};

auto obtainProp = [this](
jsi::Runtime &rt,
const jsi::Value &shadowNodeWrapper,
const jsi::Value &propName) {
return this->obtainProp(rt, shadowNodeWrapper, propName);
};
#endif

jsi::Runtime &uiRuntime = uiWorkletRuntime_->getJSIRuntime();
UIRuntimeDecorator::decorate(
uiRuntime,
#ifdef RCT_NEW_ARCH_ENABLED
removeFromPropsRegistry,
obtainProp,
updateProps,
measure,
dispatchCommand,
#else
platformDepMethodsHolder.scrollToFunction,
platformDepMethodsHolder.obtainPropFunction,
platformDepMethodsHolder.updatePropsFunction,
platformDepMethodsHolder.measureFunction,
platformDepMethodsHolder.dispatchCommandFunction,
Expand Down Expand Up @@ -230,23 +242,95 @@ void NativeReanimatedModule::unregisterEventHandler(
[=] { eventHandlerRegistry_->unregisterEventHandler(id); });
}

#ifdef RCT_NEW_ARCH_ENABLED
static inline std::string intColorToHex(const int val) {
std::stringstream ss;
ss << '#' << std::setfill('0') << std::setw(6) << std::hex << (val);
return ss.str();
}

std::string NativeReanimatedModule::obtainPropFromShadowNode(
jsi::Runtime &rt,
const std::string &propName,
const ShadowNode::Shared &shadowNode) {
auto newestCloneOfShadowNode =
uiManager_->getNewestCloneOfShadowNode(*shadowNode);

if (propName == "width" || propName == "height" || propName == "top" ||
propName == "left") {
// These props are calculated from frame
auto layoutableShadowNode =
traitCast<LayoutableShadowNode const *>(newestCloneOfShadowNode.get());
const auto &frame = layoutableShadowNode->layoutMetrics_.frame;

if (propName == "width") {
return std::to_string(frame.size.width);
} else if (propName == "height") {
return std::to_string(frame.size.height);
} else if (propName == "top") {
return std::to_string(frame.origin.y);
} else if (propName == "left") {
return std::to_string(frame.origin.x);
}
} else {
// These props are calculated from viewProps
auto props = newestCloneOfShadowNode->getProps();
auto viewProps = std::static_pointer_cast<const ViewProps>(props);
if (propName == "opacity") {
return std::to_string(viewProps->opacity);
} else if (propName == "zIndex") {
if (viewProps->zIndex.has_value()) {
return std::to_string(*viewProps->zIndex);
}
} else if (propName == "backgroundColor") {
return intColorToHex(*viewProps->backgroundColor);
}
}

throw std::runtime_error(std::string(
"Getting property `" + propName +
"` with function `getViewProp` is not supported"));
}

jsi::Value NativeReanimatedModule::getViewProp(
jsi::Runtime &rnRuntime,
const jsi::Value &viewTag,
const jsi::Value &shadowNodeWrapper,
const jsi::Value &propName,
const jsi::Value &callback) {
#ifdef RCT_NEW_ARCH_ENABLED
throw std::runtime_error(
"[Reanimated] getViewProp is not implemented on Fabric yet");
const auto propNameStr = propName.asString(rnRuntime).utf8(rnRuntime);
const auto funPtr = std::make_shared<jsi::Function>(
callback.getObject(rnRuntime).asFunction(rnRuntime));
const auto shadowNode = shadowNodeFromValue(rnRuntime, shadowNodeWrapper);
uiScheduler_->scheduleOnUI([=]() {
jsi::Runtime &uiRuntime = uiWorkletRuntime_->getJSIRuntime();
const auto resultStr =
obtainPropFromShadowNode(uiRuntime, propNameStr, shadowNode);

jsScheduler_->scheduleOnJS([=](jsi::Runtime &rnRuntime) {
const auto resultValue =
jsi::String::createFromUtf8(rnRuntime, resultStr);
funPtr->call(rnRuntime, resultValue);
});
});
return jsi::Value::undefined();
}

#else
const int viewTagInt = viewTag.asNumber();

jsi::Value NativeReanimatedModule::getViewProp(
jsi::Runtime &rnRuntime,
const jsi::Value &viewTag,
const jsi::Value &propName,
const jsi::Value &callback) {
const auto propNameStr = propName.asString(rnRuntime).utf8(rnRuntime);
const auto funPtr = std::make_shared<jsi::Function>(
callback.getObject(rnRuntime).asFunction(rnRuntime));

const int viewTagInt = viewTag.asNumber();

uiScheduler_->scheduleOnUI([=]() {
jsi::Runtime &uiRuntime = uiWorkletRuntime_->getJSIRuntime();
const auto propNameValue =
const jsi::Value propNameValue =
jsi::String::createFromUtf8(uiRuntime, propNameStr);
const auto resultValue =
obtainPropFunction_(uiRuntime, viewTagInt, propNameValue);
Expand All @@ -258,11 +342,11 @@ jsi::Value NativeReanimatedModule::getViewProp(
funPtr->call(rnRuntime, resultValue);
});
});

return jsi::Value::undefined();
#endif
}

#endif

jsi::Value NativeReanimatedModule::enableLayoutAnimations(
jsi::Runtime &,
const jsi::Value &config) {
Expand Down Expand Up @@ -461,10 +545,11 @@ bool NativeReanimatedModule::handleRawEvent(
double currentTime) {
const EventTarget *eventTarget = rawEvent.eventTarget.get();
if (eventTarget == nullptr) {
// after app reload scrollview is unmounted and its content offset is set to
// 0 and view is thrown into recycle pool setting content offset triggers
// scroll event eventTarget is null though, because it's unmounting we can
// just ignore this event, because it's an event on unmounted component
// after app reload scrollview is unmounted and its content offset is set
// to 0 and view is thrown into recycle pool setting content offset
// triggers scroll event eventTarget is null though, because it's
// unmounting we can just ignore this event, because it's an event on
// unmounted component
return false;
}

Expand All @@ -485,8 +570,8 @@ bool NativeReanimatedModule::handleRawEvent(
auto res = handleEvent(eventType, tag, std::move(payload), currentTime);
// TODO: we should call performOperations conditionally if event is handled
// (res == true), but for now handleEvent always returns false. Thankfully,
// performOperations does not trigger a lot of code if there is nothing to be
// done so this is fine for now.
// performOperations does not trigger a lot of code if there is nothing to
// be done so this is fine for now.
performOperations();
return res;
}
Expand Down Expand Up @@ -531,8 +616,8 @@ void NativeReanimatedModule::performOperations() {
tagsToRemove_.clear();
}

// Even if only non-layout props are changed, we need to store the update in
// PropsRegistry anyway so that React doesn't overwrite it in the next
// Even if only non-layout props are changed, we need to store the update
// in PropsRegistry anyway so that React doesn't overwrite it in the next
// render. Currently, only opacity and transform are treated in a special
// way but backgroundColor, shadowOpacity etc. would get overwritten (see
// `_propKeysManagedByAnimated_DO_NOT_USE_THIS_IS_BROKEN`).
Expand Down Expand Up @@ -578,9 +663,9 @@ void NativeReanimatedModule::performOperations() {
if (propsRegistry_->shouldReanimatedSkipCommit()) {
// It may happen that `performOperations` is called on the UI thread
// while React Native tries to commit a new tree on the JS thread.
// In this case, we should skip the commit here and let React Native do it.
// The commit will include the current values from PropsRegistry
// which will be applied in ReanimatedCommitHook.
// In this case, we should skip the commit here and let React Native do
// it. The commit will include the current values from PropsRegistry which
// will be applied in ReanimatedCommitHook.
return;
}

Expand All @@ -603,9 +688,10 @@ void NativeReanimatedModule::performOperations() {
react_native_assert(family.getSurfaceId() == surfaceId_);

#if REACT_NATIVE_MINOR_VERSION >= 73
// Fix for catching nullptr returned from commit hook was introduced
// in 0.72.4 but we have only check for minor version of React
// Native so enable that optimization in React Native >= 0.73
// Fix for catching nullptr returned from commit hook was
// introduced in 0.72.4 but we have only check for minor version
// of React Native so enable that optimization in React Native >=
// 0.73
if (propsRegistry_->shouldReanimatedSkipCommit()) {
return nullptr;
}
Expand Down Expand Up @@ -659,6 +745,18 @@ void NativeReanimatedModule::dispatchCommand(
uiManager_->dispatchCommand(shadowNode, commandName, args);
}

jsi::String NativeReanimatedModule::obtainProp(
jsi::Runtime &rt,
const jsi::Value &shadowNodeWrapper,
const jsi::Value &propName) {
jsi::Runtime &uiRuntime = uiWorkletRuntime_->getJSIRuntime();
const auto propNameStr = propName.asString(rt).utf8(rt);
const auto shadowNode = shadowNodeFromValue(rt, shadowNodeWrapper);
const auto resultStr =
obtainPropFromShadowNode(uiRuntime, propNameStr, shadowNode);
return jsi::String::createFromUtf8(rt, resultStr);
}

jsi::Value NativeReanimatedModule::measure(
jsi::Runtime &rt,
const jsi::Value &shadowNodeValue) {
Expand All @@ -669,9 +767,9 @@ jsi::Value NativeReanimatedModule::measure(
*shadowNode, nullptr, {/* .includeTransform = */ true});

if (layoutMetrics == EmptyLayoutMetrics) {
// Originally, in this case React Native returns `{0, 0, 0, 0, 0, 0}`, most
// likely due to the type of measure callback function which accepts just an
// array of numbers (not null). In Reanimated, `measure` returns
// Originally, in this case React Native returns `{0, 0, 0, 0, 0, 0}`,
// most likely due to the type of measure callback function which accepts
// just an array of numbers (not null). In Reanimated, `measure` returns
// `MeasuredDimensions | null`.
return jsi::Value::null();
}
Expand Down
14 changes: 14 additions & 0 deletions Common/cpp/NativeModules/NativeReanimatedModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,11 @@ class NativeReanimatedModule : public NativeReanimatedModuleSpec {

jsi::Value getViewProp(
jsi::Runtime &rt,
#ifdef RCT_NEW_ARCH_ENABLED
const jsi::Value &shadowNodeWrapper,
#else
const jsi::Value &viewTag,
#endif
const jsi::Value &propName,
const jsi::Value &callback) override;

Expand Down Expand Up @@ -127,9 +131,19 @@ class NativeReanimatedModule : public NativeReanimatedModuleSpec {
const jsi::Value &commandNameValue,
const jsi::Value &argsValue);

jsi::String obtainProp(
jsi::Runtime &rt,
const jsi::Value &shadowNodeWrapper,
const jsi::Value &propName);

jsi::Value measure(jsi::Runtime &rt, const jsi::Value &shadowNodeValue);

void initializeFabric(const std::shared_ptr<UIManager> &uiManager);

std::string obtainPropFromShadowNode(
jsi::Runtime &rt,
const std::string &propName,
const ShadowNode::Shared &shadowNode);
#endif

jsi::Value registerSensor(
Expand Down
4 changes: 4 additions & 0 deletions Common/cpp/NativeModules/NativeReanimatedModuleSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,11 @@ class JSI_EXPORT NativeReanimatedModuleSpec : public TurboModule {
// views
virtual jsi::Value getViewProp(
jsi::Runtime &rt,
#ifdef RCT_NEW_ARCH_ENABLED
const jsi::Value &shadowNodeWrapper,
#else
const jsi::Value &viewTag,
#endif
const jsi::Value &propName,
const jsi::Value &callback) = 0;

Expand Down
8 changes: 6 additions & 2 deletions Common/cpp/Tools/PlatformDepMethodsHolder.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ using UpdatePropsFunction =
std::function<void(jsi::Runtime &rt, const jsi::Value &operations)>;
using RemoveFromPropsRegistryFunction =
std::function<void(jsi::Runtime &rt, const jsi::Value &viewTags)>;
using ObtainPropFunction = std::function<jsi::Value(
jsi::Runtime &rt,
const jsi::Value &shadowNodeWrapper,
const jsi::Value &propName)>;
using DispatchCommandFunction = std::function<void(
jsi::Runtime &rt,
const jsi::Value &shadowNodeValue,
Expand All @@ -46,13 +50,13 @@ using DispatchCommandFunction = std::function<void(
const jsi::Value &argsValue)>;
using MeasureFunction =
std::function<std::vector<std::pair<std::string, double>>(int)>;
using ObtainPropFunction =
std::function<jsi::Value(jsi::Runtime &, const int, const jsi::Value &)>;

#endif // RCT_NEW_ARCH_ENABLED

using RequestRenderFunction =
std::function<void(std::function<void(const double)>, jsi::Runtime &)>;
using ObtainPropFunction =
std::function<jsi::Value(jsi::Runtime &, const int, const jsi::String &)>;
using GetAnimationTimestampFunction = std::function<double(void)>;

using ProgressLayoutAnimationFunction =
Expand Down
6 changes: 6 additions & 0 deletions Common/cpp/Tools/UIRuntimeDecorator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ void UIRuntimeDecorator::decorate(
#else
const ScrollToFunction scrollTo,
#endif
const ObtainPropFunction obtainPropFunction,
const UpdatePropsFunction updateProps,
const MeasureFunction measure,
const DispatchCommandFunction dispatchCommand,
Expand Down Expand Up @@ -44,6 +45,8 @@ void UIRuntimeDecorator::decorate(
}
return resultObject;
});
jsi_utils::installJsiFunction(
uiRuntime, "_obtainPropPaper", obtainPropFunction);
#endif // RCT_NEW_ARCH_ENABLED

jsi_utils::installJsiFunction(
Expand All @@ -59,6 +62,9 @@ void UIRuntimeDecorator::decorate(
jsi_utils::installJsiFunction(uiRuntime, "_setGestureState", setGestureState);
jsi_utils::installJsiFunction(
uiRuntime, "_maybeFlushUIUpdatesQueue", maybeFlushUIUpdatesQueue);

jsi_utils::installJsiFunction(
uiRuntime, "_obtainPropFabric", obtainPropFunction);
}

} // namespace reanimated
1 change: 1 addition & 0 deletions Common/cpp/Tools/UIRuntimeDecorator.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class UIRuntimeDecorator {
#else
const ScrollToFunction scrollTo,
#endif
const ObtainPropFunction obtainPropFunction,
const UpdatePropsFunction updateProps,
const MeasureFunction measure,
const DispatchCommandFunction dispatchCommand,
Expand Down
4 changes: 2 additions & 2 deletions android/src/main/cpp/NativeProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,12 +216,12 @@ void NativeProxy::maybeFlushUIUpdatesQueue() {
jsi::Value NativeProxy::obtainProp(
jsi::Runtime &rt,
const int viewTag,
const jsi::String &propName) {
const jsi::Value &propName) {
static const auto method =
getJniMethod<jni::local_ref<JString>(int, jni::local_ref<JString>)>(
"obtainProp");
local_ref<JString> propNameJStr =
jni::make_jstring(propName.utf8(rt).c_str());
jni::make_jstring(propName.asString(rt).utf8(rt).c_str());
auto result = method(javaPart_.get(), viewTag, propNameJStr);
std::string str = result->toStdString();
return jsi::Value(rt, jsi::String::createFromAscii(rt, str));
Expand Down
2 changes: 1 addition & 1 deletion android/src/main/cpp/NativeProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ class NativeProxy : public jni::HybridClass<NativeProxy> {
// nothing
#else
jsi::Value
obtainProp(jsi::Runtime &rt, const int viewTag, const jsi::String &propName);
obtainProp(jsi::Runtime &rt, const int viewTag, const jsi::Value &propName);
void configureProps(
jsi::Runtime &rt,
const jsi::Value &uiProps,
Expand Down
Loading