Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include <reanimated/CSS/configs/CSSKeyframesConfig.h>

#include <reanimated/CSS/configs/common.h>

#include <memory>
#include <string>

Expand Down Expand Up @@ -33,9 +35,10 @@ std::shared_ptr<KeyframeEasingFunctions> getKeyframeTimingFunctions(jsi::Runtime
CSSKeyframesConfig parseCSSAnimationKeyframesConfig(
jsi::Runtime &rt,
const jsi::Value &config,
const std::string &nativeComponentName,
const std::string &compoundComponentName,
const std::shared_ptr<ViewStylesRepository> &viewStylesRepository) {
const auto &configObj = config.asObject(rt);
const auto nativeComponentName = splitCompoundComponentName(compoundComponentName).first;

return {
createStyleInterpolator(rt, configObj, nativeComponentName, viewStylesRepository),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ struct CSSKeyframesConfig {
CSSKeyframesConfig parseCSSAnimationKeyframesConfig(
jsi::Runtime &rt,
const jsi::Value &config,
const std::string &nativeComponentName,
const std::string &compoundComponentName,
const std::shared_ptr<ViewStylesRepository> &viewStylesRepository);

} // namespace reanimated::css
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#include <reanimated/CSS/configs/common.h>

#include <react/renderer/componentregistry/componentNameByReactViewName.h>

using facebook::react::componentNameByReactViewName;

namespace reanimated::css {

double getDuration(jsi::Runtime &rt, const jsi::Object &config) {
Expand All @@ -14,4 +18,12 @@ double getDelay(jsi::Runtime &rt, const jsi::Object &config) {
return config.getProperty(rt, "delay").asNumber();
}

std::pair<std::string, std::string> splitCompoundComponentName(const std::string &compoundComponentName) {
const auto pos = compoundComponentName.find('$');
if (pos == std::string::npos) {
return {compoundComponentName, ""};
}
return {compoundComponentName.substr(0, pos), compoundComponentName.substr(pos + 1)};
}

} // namespace reanimated::css
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
#pragma once

#include <jsi/jsi.h>
#include <reanimated/CSS/easing/EasingFunctions.h>

#include <string>
Comment thread
MatiPl01 marked this conversation as resolved.
#include <utility>

namespace reanimated::css {

double getDuration(jsi::Runtime &rt, const jsi::Object &config);
Expand All @@ -10,4 +14,6 @@ EasingFunction getTimingFunction(jsi::Runtime &rt, const jsi::Object &config);

double getDelay(jsi::Runtime &rt, const jsi::Object &config);

std::pair<std::string, std::string> splitCompoundComponentName(const std::string &compoundComponentName);

} // namespace reanimated::css
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,32 @@ namespace reanimated::css {
CSSKeyframesRegistry::CSSKeyframesRegistry(const std::shared_ptr<ViewStylesRepository> &viewStylesRepository)
: viewStylesRepository_(viewStylesRepository) {}

const CSSKeyframesConfig &CSSKeyframesRegistry::get(
std::optional<std::reference_wrapper<const CSSKeyframesConfig>> CSSKeyframesRegistry::get(
const std::string &animationName,
const std::string &nativeComponentName) {
const auto &registryIt = registry_.find(animationName);
const std::string &compoundComponentName) {
const auto registryIt = registry_.find(animationName);
if (registryIt == registry_.end()) {
throw std::runtime_error("[Reanimated] No keyframes with name `" + animationName + "` were registered");
return std::nullopt;
}

const auto &keyframesByComponentName = registryIt->second;
const auto &keyframesByComponentNameIt = keyframesByComponentName.find(nativeComponentName);
if (keyframesByComponentNameIt == keyframesByComponentName.end()) {
throw std::runtime_error(
"[Reanimated] No keyframes with name `" + animationName + "` were registered for component `" +
nativeComponentName + "`");
const auto &keyframesByComponent = registryIt->second;
const auto keyframesByComponentIt = keyframesByComponent.find(compoundComponentName);
if (keyframesByComponentIt == keyframesByComponent.end()) {
return std::nullopt;
}

return keyframesByComponentNameIt->second;
return std::cref(keyframesByComponentIt->second);
}

void CSSKeyframesRegistry::set(
const std::string &animationName,
const std::string &nativeComponentName,
const std::string &compoundComponentName,
CSSKeyframesConfig &&config) {
registry_[animationName][nativeComponentName] = std::move(config);
registry_[animationName][compoundComponentName] = std::move(config);
}

void CSSKeyframesRegistry::remove(const std::string &animationName, const std::string &nativeComponentName) {
registry_[animationName].erase(nativeComponentName);
void CSSKeyframesRegistry::remove(const std::string &animationName, const std::string &compoundComponentName) {
registry_[animationName].erase(compoundComponentName);
if (registry_[animationName].empty()) {
registry_.erase(animationName);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
#include <reanimated/CSS/interpolation/styles/AnimationStyleInterpolator.h>
#include <reanimated/CSS/misc/ViewStylesRepository.h>

#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <unordered_map>
#include <utility>
Expand All @@ -15,14 +17,22 @@ class CSSKeyframesRegistry {
public:
explicit CSSKeyframesRegistry(const std::shared_ptr<ViewStylesRepository> &viewStylesRepository);

const CSSKeyframesConfig &get(const std::string &animationName, const std::string &nativeComponentName);
void set(const std::string &animationName, const std::string &nativeComponentName, CSSKeyframesConfig &&config);
void remove(const std::string &animationName, const std::string &nativeComponentName);
std::optional<std::reference_wrapper<const CSSKeyframesConfig>> get(
const std::string &animationName,
const std::string &compoundComponentName);
Comment thread
tjzel marked this conversation as resolved.
void set(const std::string &animationName, const std::string &compoundComponentName, CSSKeyframesConfig &&config);
void remove(const std::string &animationName, const std::string &compoundComponentName);

private:
using ConfigsByComponentName = std::unordered_map<std::string, CSSKeyframesConfig>;

std::unordered_map<std::string, ConfigsByComponentName> registry_;
// Maps compound component name to CSSKeyframesConfig. The same keyframes object may be
// interpolated differently per component (different interpolators) even when the
// keyframes look identical. CSSKeyframesConfig holds a component-specific
// styleInterpolator, so configs must be stored separately per component.
// Compound component name combines native and JS component names (caller must build it).
using KeyframesByCompoundComponentName = std::unordered_map<std::string, CSSKeyframesConfig>;

// Top level: animation name. Inner level: compound component name -> config.
std::unordered_map<std::string, KeyframesByCompoundComponentName> registry_;
const std::shared_ptr<ViewStylesRepository> viewStylesRepository_;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ void UpdatesRegistryManager::collectPropsToRevertBySurface(std::unordered_map<Su
continue;
}

const auto &componentName = shadowNode->getComponentName();
const auto &interpolators = getComponentInterpolators(componentName);
const auto &nativeComponentName = shadowNode->getComponentName();
const auto &interpolators = getComponentInterpolators(nativeComponentName);
const auto &it = interpolators.find(propName);

if (it != interpolators.end()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#include <jsi/jsi.h>
#include <react/renderer/scheduler/Scheduler.h>
#include <react/renderer/uimanager/UIManagerBinding.h>
#include <reanimated/Events/UIEventHandler.h>
Expand Down Expand Up @@ -363,26 +362,27 @@ void ReanimatedModuleProxy::unmarkNodeAsRemovable(jsi::Runtime &rt, const jsi::V
void ReanimatedModuleProxy::registerCSSKeyframes(
jsi::Runtime &rt,
const jsi::Value &animationName,
const jsi::Value &reactViewName,
const jsi::Value &compoundComponentName,
const jsi::Value &keyframesConfig) {
const auto nativeComponentName = componentNameByReactViewName(reactViewName.asString(rt).utf8(rt));
const auto compoundComponentNameStr = compoundComponentName.asString(rt).utf8(rt);
cssAnimationKeyframesRegistry_->set(
animationName.asString(rt).utf8(rt),
nativeComponentName,
parseCSSAnimationKeyframesConfig(rt, keyframesConfig, nativeComponentName, viewStylesRepository_));
compoundComponentNameStr,
parseCSSAnimationKeyframesConfig(rt, keyframesConfig, compoundComponentNameStr, viewStylesRepository_));
}

void ReanimatedModuleProxy::unregisterCSSKeyframes(
jsi::Runtime &rt,
const jsi::Value &animationName,
const jsi::Value &reactViewName) {
const jsi::Value &compoundComponentName) {
cssAnimationKeyframesRegistry_->remove(
animationName.asString(rt).utf8(rt), componentNameByReactViewName(reactViewName.asString(rt).utf8(rt)));
animationName.asString(rt).utf8(rt), compoundComponentName.asString(rt).utf8(rt));
}

void ReanimatedModuleProxy::applyCSSAnimations(
jsi::Runtime &rt,
const jsi::Value &shadowNodeWrapper,
const jsi::Value &compoundComponentName,
const jsi::Value &animationUpdates) {
auto shadowNode = shadowNodeFromValue(rt, shadowNodeWrapper);
const auto timestamp = getCssTimestamp();
Expand All @@ -401,10 +401,20 @@ void ReanimatedModuleProxy::applyCSSAnimations(
}

const auto &animationName = animationNames[index];
const auto &keyframesConfig = cssAnimationKeyframesRegistry_->get(animationName, shadowNode->getComponentName());
const auto nativeComponentName = shadowNode->getComponentName();
const auto compoundComponentNameStr = compoundComponentName.asString(rt).utf8(rt);
const auto keyframesConfigOpt = cssAnimationKeyframesRegistry_->get(animationName, compoundComponentNameStr);

if (!keyframesConfigOpt) {
throw std::runtime_error(
"[Reanimated] No keyframes with name `" + animationName + "` were registered for component `" +
splitCompoundComponentName(compoundComponentNameStr).second + "` (" + nativeComponentName + ")");
}

newAnimations.emplace(
index, std::make_shared<CSSAnimation>(rt, shadowNode, animationName, keyframesConfig, settings, timestamp));
index,
std::make_shared<CSSAnimation>(
rt, shadowNode, animationName, keyframesConfigOpt->get(), settings, timestamp));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,18 @@ class ReanimatedModuleProxy : public ReanimatedModuleProxySpec,
void registerCSSKeyframes(
jsi::Runtime &rt,
const jsi::Value &animationName,
const jsi::Value &reactViewName,
const jsi::Value &compoundComponentName,
const jsi::Value &keyframesConfig) override;
void unregisterCSSKeyframes(jsi::Runtime &rt, const jsi::Value &animationName, const jsi::Value &reactViewName)
override;
void unregisterCSSKeyframes(
jsi::Runtime &rt,
const jsi::Value &animationName,
const jsi::Value &compoundComponentName) override;

void applyCSSAnimations(jsi::Runtime &rt, const jsi::Value &shadowNodeWrapper, const jsi::Value &animationUpdates)
override;
void applyCSSAnimations(
jsi::Runtime &rt,
const jsi::Value &shadowNodeWrapper,
const jsi::Value &compoundComponentName,
const jsi::Value &animationUpdates) override;
void unregisterCSSAnimations(const jsi::Value &viewTag) override;

void runCSSTransition(jsi::Runtime &rt, const jsi::Value &shadowNodeWrapper, const jsi::Value &transitionConfig)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ static jsi::Value REANIMATED_SPEC_PREFIX(
static jsi::Value REANIMATED_SPEC_PREFIX(
applyCSSAnimations)(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value *args, size_t) {
static_cast<ReanimatedModuleProxySpec *>(&turboModule)
->applyCSSAnimations(rt, std::move(args[0]), std::move(args[1]));
->applyCSSAnimations(rt, std::move(args[0]), std::move(args[1]), std::move(args[2]));
return jsi::Value::undefined();
}

Expand Down Expand Up @@ -162,7 +162,7 @@ ReanimatedModuleProxySpec::ReanimatedModuleProxySpec(const std::shared_ptr<CallI
methodMap_["registerCSSKeyframes"] = MethodMetadata{3, REANIMATED_SPEC_PREFIX(registerCSSKeyframes)};
methodMap_["unregisterCSSKeyframes"] = MethodMetadata{2, REANIMATED_SPEC_PREFIX(unregisterCSSKeyframes)};

methodMap_["applyCSSAnimations"] = MethodMetadata{2, REANIMATED_SPEC_PREFIX(applyCSSAnimations)};
methodMap_["applyCSSAnimations"] = MethodMetadata{3, REANIMATED_SPEC_PREFIX(applyCSSAnimations)};
methodMap_["unregisterCSSAnimations"] = MethodMetadata{1, REANIMATED_SPEC_PREFIX(unregisterCSSAnimations)};

methodMap_["runCSSTransition"] = MethodMetadata{2, REANIMATED_SPEC_PREFIX(runCSSTransition)};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,19 @@ class JSI_EXPORT ReanimatedModuleProxySpec : public TurboModule {
virtual void registerCSSKeyframes(
jsi::Runtime &rt,
const jsi::Value &animationName,
const jsi::Value &reactViewName,
const jsi::Value &compoundComponentName,
const jsi::Value &keyframesConfig) = 0;
virtual void
unregisterCSSKeyframes(jsi::Runtime &rt, const jsi::Value &animationName, const jsi::Value &reactViewName) = 0;
virtual void unregisterCSSKeyframes(
jsi::Runtime &rt,
const jsi::Value &animationName,
const jsi::Value &compoundComponentName) = 0;

// CSS animations
virtual void
applyCSSAnimations(jsi::Runtime &rt, const jsi::Value &shadowNodeWrapper, const jsi::Value &animationUpdates) = 0;
virtual void applyCSSAnimations(
jsi::Runtime &rt,
const jsi::Value &shadowNodeWrapper,
const jsi::Value &compoundComponentName,
const jsi::Value &animationUpdates) = 0;
virtual void unregisterCSSAnimations(const jsi::Value &viewTag) = 0;

// CSS transitions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,26 +201,31 @@ See https://docs.swmansion.com/react-native-reanimated/docs/guides/troubleshooti

registerCSSKeyframes(
animationName: string,
viewName: string,
compoundComponentName: string,
keyframesConfig: NormalizedCSSAnimationKeyframesConfig
) {
this.#reanimatedModuleProxy.registerCSSKeyframes(
animationName,
viewName,
compoundComponentName,
keyframesConfig
);
}

unregisterCSSKeyframes(animationName: string, viewName: string) {
this.#reanimatedModuleProxy.unregisterCSSKeyframes(animationName, viewName);
unregisterCSSKeyframes(animationName: string, compoundComponentName: string) {
this.#reanimatedModuleProxy.unregisterCSSKeyframes(
animationName,
compoundComponentName
);
}

applyCSSAnimations(
shadowNodeWrapper: ShadowNodeWrapper,
compoundComponentName: string,
animationUpdates: CSSAnimationUpdates
) {
this.#reanimatedModuleProxy.applyCSSAnimations(
shadowNodeWrapper,
compoundComponentName,
animationUpdates
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,22 +289,26 @@ class JSReanimated implements IReanimatedModule {

registerCSSKeyframes(
_animationName: string,
_viewName: string,
_compoundComponentName: string,
_keyframesConfig: NormalizedCSSAnimationKeyframesConfig
): void {
throw new ReanimatedError(
'`registerCSSKeyframes` is not available in JSReanimated.'
);
}

unregisterCSSKeyframes(_animationName: string, _viewName: string): void {
unregisterCSSKeyframes(
_animationName: string,
_compoundComponentName: string
): void {
throw new ReanimatedError(
'`unregisterCSSKeyframes` is not available in JSReanimated.'
);
}

applyCSSAnimations(
_shadowNodeWrapper: ShadowNodeWrapper,
_compoundComponentName: string,
_animationUpdates: CSSAnimationUpdates
) {
throw new ReanimatedError(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,18 @@ export interface ReanimatedModuleProxy {

registerCSSKeyframes(
animationName: string,
viewName: string,
compoundComponentName: string,
keyframesConfig: NormalizedCSSAnimationKeyframesConfig
): void;

unregisterCSSKeyframes(animationName: string, viewName: string): void;
unregisterCSSKeyframes(
animationName: string,
compoundComponentName: string
): void;

applyCSSAnimations(
shadowNodeWrapper: ShadowNodeWrapper,
compoundComponentName: string,
animationUpdates: CSSAnimationUpdates
): void;

Expand Down
Loading