yeet
This commit is contained in:
15
node_modules/react-native-reanimated/android/README.md
generated
vendored
Normal file
15
node_modules/react-native-reanimated/android/README.md
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
|
||||
README
|
||||
======
|
||||
|
||||
If you want to publish the lib as a maven dependency, follow these steps before publishing a new version to npm:
|
||||
|
||||
1. Be sure to have the Android [SDK](https://developer.android.com/studio/index.html) and [NDK](https://developer.android.com/ndk/guides/index.html) installed
|
||||
2. Be sure to have a `local.properties` file in this folder that points to the Android SDK and NDK
|
||||
```
|
||||
ndk.dir=/Users/{username}/Library/Android/sdk/ndk-bundle
|
||||
sdk.dir=/Users/{username}/Library/Android/sdk
|
||||
```
|
||||
3. Delete the `maven` folder
|
||||
4. Run `sudo ./gradlew installArchives`
|
||||
5. Verify that latest set of generated files is in the maven folder with the correct version number
|
133
node_modules/react-native-reanimated/android/build.gradle
generated
vendored
Normal file
133
node_modules/react-native-reanimated/android/build.gradle
generated
vendored
Normal file
@ -0,0 +1,133 @@
|
||||
def safeExtGet(prop, fallback) {
|
||||
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
||||
}
|
||||
|
||||
buildscript {
|
||||
if (project == rootProject) {
|
||||
// The Android Gradle plugin is only required when opening the android folder stand-alone.
|
||||
// This avoids unnecessary downloads and potential conflicts when the library is included as a
|
||||
// module dependency in an application project.
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.5.2'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'maven'
|
||||
|
||||
android {
|
||||
compileSdkVersion safeExtGet('compileSdkVersion', 28)
|
||||
buildToolsVersion safeExtGet('buildToolsVersion', '28.0.3')
|
||||
defaultConfig {
|
||||
minSdkVersion safeExtGet('minSdkVersion', 16)
|
||||
targetSdkVersion safeExtGet('targetSdkVersion', 28)
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
maven {
|
||||
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
||||
url "$rootDir/../node_modules/react-native/android"
|
||||
}
|
||||
maven {
|
||||
// Android JSC is installed from npm
|
||||
url "$rootDir/../node_modules/jsc-android/dist"
|
||||
}
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
//noinspection GradleDynamicVersion
|
||||
implementation 'com.facebook.react:react-native:+' // From node_modules
|
||||
implementation "androidx.transition:transition:1.1.0"
|
||||
}
|
||||
|
||||
def configureReactNativePom(def pom) {
|
||||
def packageJson = new groovy.json.JsonSlurper().parseText(file('../package.json').text)
|
||||
|
||||
pom.project {
|
||||
name packageJson.title
|
||||
artifactId packageJson.name
|
||||
version = packageJson.version
|
||||
group = "com.swmansion.reanimated"
|
||||
description packageJson.description
|
||||
url packageJson.repository.baseUrl
|
||||
|
||||
licenses {
|
||||
license {
|
||||
name packageJson.license
|
||||
url packageJson.repository.baseUrl + '/blob/master/' + packageJson.licenseFilename
|
||||
distribution 'repo'
|
||||
}
|
||||
}
|
||||
|
||||
developers {
|
||||
developer {
|
||||
id packageJson.author.username
|
||||
name packageJson.author.name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
afterEvaluate { project ->
|
||||
|
||||
task androidJavadoc(type: Javadoc) {
|
||||
source = android.sourceSets.main.java.srcDirs
|
||||
classpath += files(android.bootClasspath)
|
||||
classpath += files(project.getConfigurations().getByName('compile').asList())
|
||||
include '**/*.java'
|
||||
}
|
||||
|
||||
task androidJavadocJar(type: Jar, dependsOn: androidJavadoc) {
|
||||
classifier = 'javadoc'
|
||||
from androidJavadoc.destinationDir
|
||||
}
|
||||
|
||||
task androidSourcesJar(type: Jar) {
|
||||
classifier = 'sources'
|
||||
from android.sourceSets.main.java.srcDirs
|
||||
include '**/*.java'
|
||||
}
|
||||
|
||||
android.libraryVariants.all { variant ->
|
||||
def compileTask
|
||||
if (variant.hasProperty('javaCompileProvider')){
|
||||
compileTask = variant.javaCompileProvider.get()
|
||||
}else{
|
||||
compileTask = variant.javaCompile
|
||||
}
|
||||
|
||||
def name = variant.name.capitalize()
|
||||
task "jar${name}"(type: Jar, dependsOn: compileTask) {
|
||||
from compileTask.destinationDir
|
||||
}
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives androidSourcesJar
|
||||
archives androidJavadocJar
|
||||
}
|
||||
|
||||
task installArchives(type: Upload) {
|
||||
configuration = configurations.archives
|
||||
repositories.mavenDeployer {
|
||||
// Deploy to react-native-event-bridge/maven, ready to publish to npm
|
||||
repository url: "file://${projectDir}/../android/maven"
|
||||
|
||||
configureReactNativePom pom
|
||||
}
|
||||
}
|
||||
}
|
5
node_modules/react-native-reanimated/android/src/main/AndroidManifest.xml
generated
vendored
Normal file
5
node_modules/react-native-reanimated/android/src/main/AndroidManifest.xml
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.swmansion.reanimated">
|
||||
|
||||
</manifest>
|
14
node_modules/react-native-reanimated/android/src/main/java/com/facebook/react/uimanager/UIManagerReanimatedHelper.java
generated
vendored
Normal file
14
node_modules/react-native-reanimated/android/src/main/java/com/facebook/react/uimanager/UIManagerReanimatedHelper.java
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
package com.facebook.react.uimanager;
|
||||
|
||||
/**
|
||||
* This class provides a way to workaround limited visibility of UIViewOperationQueue#getUIViewOperationQueue.
|
||||
* We rely on accessing that method to check if operation queue is empty or not. This in turn indicates if
|
||||
* we are in a middle of processing batch of operations from JS. In such a case we can rely on the enqueued update
|
||||
* operations to be flushed onto the shadow view hierarchy. Otherwise we want to trigger "dispatchViewUpdates" and
|
||||
* enforce flush immediately.
|
||||
*/
|
||||
public class UIManagerReanimatedHelper {
|
||||
public static boolean isOperationQueueEmpty(UIImplementation uiImplementation) {
|
||||
return uiImplementation.getUIViewOperationQueue().isEmpty();
|
||||
}
|
||||
}
|
28
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/MapUtils.java
generated
vendored
Normal file
28
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/MapUtils.java
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
package com.swmansion.reanimated;
|
||||
|
||||
import com.facebook.react.bridge.JSApplicationCausedNativeException;
|
||||
import com.facebook.react.bridge.NoSuchKeyException;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.ReadableType;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class MapUtils {
|
||||
public static int getInt(ReadableMap map, @Nonnull String name, String errorMsg) {
|
||||
try {
|
||||
return map.getInt(name);
|
||||
} catch (NoSuchKeyException e) {
|
||||
throw new JSApplicationCausedNativeException(errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getString(ReadableMap map, @Nonnull String name, String errorMsg) {
|
||||
try {
|
||||
return map.getString(name);
|
||||
} catch (NoSuchKeyException e) {
|
||||
throw new JSApplicationCausedNativeException(errorMsg);
|
||||
}
|
||||
}
|
||||
}
|
414
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/NodesManager.java
generated
vendored
Normal file
414
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/NodesManager.java
generated
vendored
Normal file
@ -0,0 +1,414 @@
|
||||
package com.swmansion.reanimated;
|
||||
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.Callback;
|
||||
import com.facebook.react.bridge.GuardedRunnable;
|
||||
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.UiThreadUtil;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
import com.facebook.react.modules.core.ReactChoreographer;
|
||||
import com.facebook.react.uimanager.GuardedFrameCallback;
|
||||
import com.facebook.react.uimanager.ReactShadowNode;
|
||||
import com.facebook.react.uimanager.UIImplementation;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
import com.facebook.react.uimanager.UIManagerReanimatedHelper;
|
||||
import com.facebook.react.uimanager.events.Event;
|
||||
import com.facebook.react.uimanager.events.EventDispatcherListener;
|
||||
import com.swmansion.reanimated.nodes.AlwaysNode;
|
||||
import com.swmansion.reanimated.nodes.BezierNode;
|
||||
import com.swmansion.reanimated.nodes.BlockNode;
|
||||
import com.swmansion.reanimated.nodes.ClockNode;
|
||||
import com.swmansion.reanimated.nodes.ClockOpNode;
|
||||
import com.swmansion.reanimated.nodes.ConcatNode;
|
||||
import com.swmansion.reanimated.nodes.CondNode;
|
||||
import com.swmansion.reanimated.nodes.DebugNode;
|
||||
import com.swmansion.reanimated.nodes.EventNode;
|
||||
import com.swmansion.reanimated.nodes.JSCallNode;
|
||||
import com.swmansion.reanimated.nodes.Node;
|
||||
import com.swmansion.reanimated.nodes.NoopNode;
|
||||
import com.swmansion.reanimated.nodes.OperatorNode;
|
||||
import com.swmansion.reanimated.nodes.PropsNode;
|
||||
import com.swmansion.reanimated.nodes.SetNode;
|
||||
import com.swmansion.reanimated.nodes.StyleNode;
|
||||
import com.swmansion.reanimated.nodes.TransformNode;
|
||||
import com.swmansion.reanimated.nodes.ValueNode;
|
||||
import com.swmansion.reanimated.nodes.ParamNode;
|
||||
import com.swmansion.reanimated.nodes.FunctionNode;
|
||||
import com.swmansion.reanimated.nodes.CallFuncNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class NodesManager implements EventDispatcherListener {
|
||||
|
||||
private static final Double ZERO = Double.valueOf(0);
|
||||
|
||||
public interface OnAnimationFrame {
|
||||
void onAnimationFrame();
|
||||
}
|
||||
|
||||
private final SparseArray<Node> mAnimatedNodes = new SparseArray<>();
|
||||
private final Map<String, EventNode> mEventMapping = new HashMap<>();
|
||||
private final UIImplementation mUIImplementation;
|
||||
private final DeviceEventManagerModule.RCTDeviceEventEmitter mEventEmitter;
|
||||
private final ReactChoreographer mReactChoreographer;
|
||||
private final GuardedFrameCallback mChoreographerCallback;
|
||||
private final UIManagerModule.CustomEventNamesResolver mCustomEventNamesResolver;
|
||||
private final AtomicBoolean mCallbackPosted = new AtomicBoolean();
|
||||
private final NoopNode mNoopNode;
|
||||
private final ReactContext mContext;
|
||||
private final UIManagerModule mUIManager;
|
||||
|
||||
private List<OnAnimationFrame> mFrameCallbacks = new ArrayList<>();
|
||||
private ConcurrentLinkedQueue<Event> mEventQueue = new ConcurrentLinkedQueue<>();
|
||||
private boolean mWantRunUpdates;
|
||||
|
||||
public double currentFrameTimeMs;
|
||||
public final UpdateContext updateContext;
|
||||
public Set<String> uiProps = Collections.emptySet();
|
||||
public Set<String> nativeProps = Collections.emptySet();
|
||||
|
||||
private final class NativeUpdateOperation {
|
||||
public int mViewTag;
|
||||
public WritableMap mNativeProps;
|
||||
public NativeUpdateOperation(int viewTag, WritableMap nativeProps) {
|
||||
mViewTag = viewTag;
|
||||
mNativeProps = nativeProps;
|
||||
}
|
||||
}
|
||||
private Queue<NativeUpdateOperation> mOperationsInBatch = new LinkedList<>();
|
||||
|
||||
public NodesManager(ReactContext context) {
|
||||
mContext = context;
|
||||
mUIManager = context.getNativeModule(UIManagerModule.class);
|
||||
updateContext = new UpdateContext();
|
||||
mUIImplementation = mUIManager.getUIImplementation();
|
||||
mCustomEventNamesResolver = mUIManager.getDirectEventNamesResolver();
|
||||
mEventEmitter = context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class);
|
||||
|
||||
mReactChoreographer = ReactChoreographer.getInstance();
|
||||
mChoreographerCallback = new GuardedFrameCallback(context) {
|
||||
@Override
|
||||
protected void doFrameGuarded(long frameTimeNanos) {
|
||||
onAnimationFrame(frameTimeNanos);
|
||||
}
|
||||
};
|
||||
|
||||
mNoopNode = new NoopNode(this);
|
||||
|
||||
// We register as event listener at the end, because we pass `this` and we haven't finished contructing an object yet.
|
||||
// This lead to a crash described in https://github.com/software-mansion/react-native-reanimated/issues/604 which was caused by Nodes Manager being constructed on UI thread and registering for events.
|
||||
// Events are handled in the native modules thread in the `onEventDispatch()` method.
|
||||
// This method indirectly uses `mChoreographerCallback` which was created after event registration, creating race condition
|
||||
mUIManager.getEventDispatcher().addListener(this);
|
||||
}
|
||||
|
||||
public void onHostPause() {
|
||||
if (mCallbackPosted.get()) {
|
||||
stopUpdatingOnAnimationFrame();
|
||||
mCallbackPosted.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void onHostResume() {
|
||||
if (mCallbackPosted.getAndSet(false)) {
|
||||
startUpdatingOnAnimationFrame();
|
||||
}
|
||||
}
|
||||
|
||||
private void startUpdatingOnAnimationFrame() {
|
||||
if (!mCallbackPosted.getAndSet(true)) {
|
||||
mReactChoreographer.postFrameCallback(
|
||||
ReactChoreographer.CallbackType.NATIVE_ANIMATED_MODULE,
|
||||
mChoreographerCallback);
|
||||
}
|
||||
}
|
||||
|
||||
private void stopUpdatingOnAnimationFrame() {
|
||||
if (mCallbackPosted.getAndSet(false)) {
|
||||
mReactChoreographer.removeFrameCallback(
|
||||
ReactChoreographer.CallbackType.NATIVE_ANIMATED_MODULE,
|
||||
mChoreographerCallback);
|
||||
}
|
||||
}
|
||||
|
||||
private void onAnimationFrame(long frameTimeNanos) {
|
||||
currentFrameTimeMs = frameTimeNanos / 1000000.;
|
||||
|
||||
while (!mEventQueue.isEmpty()) {
|
||||
handleEvent(mEventQueue.poll());
|
||||
}
|
||||
|
||||
if (!mFrameCallbacks.isEmpty()) {
|
||||
List<OnAnimationFrame> frameCallbacks = mFrameCallbacks;
|
||||
mFrameCallbacks = new ArrayList<>(frameCallbacks.size());
|
||||
for (int i = 0, size = frameCallbacks.size(); i < size; i++) {
|
||||
frameCallbacks.get(i).onAnimationFrame();
|
||||
}
|
||||
}
|
||||
|
||||
if (mWantRunUpdates) {
|
||||
Node.runUpdates(updateContext);
|
||||
}
|
||||
|
||||
if (!mOperationsInBatch.isEmpty()) {
|
||||
final Queue<NativeUpdateOperation> copiedOperationsQueue = mOperationsInBatch;
|
||||
mOperationsInBatch = new LinkedList<>();
|
||||
mContext.runOnNativeModulesQueueThread(
|
||||
// FIXME replace `mContext` with `mContext.getExceptionHandler()` after RN 0.59 support is dropped
|
||||
new GuardedRunnable(mContext) {
|
||||
@Override
|
||||
public void runGuarded() {
|
||||
boolean shouldDispatchUpdates = UIManagerReanimatedHelper.isOperationQueueEmpty(mUIImplementation);
|
||||
while (!copiedOperationsQueue.isEmpty()) {
|
||||
NativeUpdateOperation op = copiedOperationsQueue.remove();
|
||||
ReactShadowNode shadowNode = mUIImplementation.resolveShadowNode(op.mViewTag);
|
||||
if (shadowNode != null) {
|
||||
mUIManager.updateView(op.mViewTag, shadowNode.getViewClass(), op.mNativeProps);
|
||||
}
|
||||
}
|
||||
if (shouldDispatchUpdates) {
|
||||
mUIImplementation.dispatchViewUpdates(-1); // no associated batchId
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
mCallbackPosted.set(false);
|
||||
mWantRunUpdates = false;
|
||||
|
||||
if (!mFrameCallbacks.isEmpty() || !mEventQueue.isEmpty()) {
|
||||
// enqueue next frame
|
||||
startUpdatingOnAnimationFrame();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Null-safe way of getting node's value. If node is not present we return 0. This also matches
|
||||
* iOS behavior when the app won't just crash.
|
||||
*/
|
||||
public Object getNodeValue(int nodeID) {
|
||||
Node node = mAnimatedNodes.get(nodeID);
|
||||
if (node != null) {
|
||||
return node.value();
|
||||
}
|
||||
return ZERO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Null-safe way of getting node reference. This method always returns non-null instance. If the
|
||||
* node is not present we try to return a "no-op" node that allows for "set" calls and always
|
||||
* returns 0 as a value.
|
||||
*/
|
||||
public <T extends Node> T findNodeById(int id, Class<T> type) {
|
||||
Node node = mAnimatedNodes.get(id);
|
||||
if (node == null) {
|
||||
if (type == Node.class || type == ValueNode.class) {
|
||||
return (T) mNoopNode;
|
||||
}
|
||||
throw new IllegalArgumentException("Requested node with id " + id + " of type " + type +
|
||||
" cannot be found");
|
||||
}
|
||||
if (type.isInstance(node)) {
|
||||
return (T) node;
|
||||
}
|
||||
throw new IllegalArgumentException("Node with id " + id + " is of incompatible type " +
|
||||
node.getClass() + ", requested type was " + type);
|
||||
}
|
||||
|
||||
public void createNode(int nodeID, ReadableMap config) {
|
||||
if (mAnimatedNodes.get(nodeID) != null) {
|
||||
throw new JSApplicationIllegalArgumentException("Animated node with ID " + nodeID +
|
||||
" already exists");
|
||||
}
|
||||
String type = config.getString("type");
|
||||
final Node node;
|
||||
if ("props".equals(type)) {
|
||||
node = new PropsNode(nodeID, config, this, mUIImplementation);
|
||||
} else if ("style".equals(type)) {
|
||||
node = new StyleNode(nodeID, config, this);
|
||||
} else if ("transform".equals(type)) {
|
||||
node = new TransformNode(nodeID, config, this);
|
||||
} else if ("value".equals(type)) {
|
||||
node = new ValueNode(nodeID, config, this);
|
||||
} else if ("block".equals(type)) {
|
||||
node = new BlockNode(nodeID, config, this);
|
||||
} else if ("cond".equals(type)) {
|
||||
node = new CondNode(nodeID, config, this);
|
||||
} else if ("op".equals(type)) {
|
||||
node = new OperatorNode(nodeID, config, this);
|
||||
} else if ("set".equals(type)) {
|
||||
node = new SetNode(nodeID, config, this);
|
||||
} else if ("debug".equals(type)) {
|
||||
node = new DebugNode(nodeID, config, this);
|
||||
} else if ("clock".equals(type)) {
|
||||
node = new ClockNode(nodeID, config, this);
|
||||
} else if ("clockStart".equals(type)) {
|
||||
node = new ClockOpNode.ClockStartNode(nodeID, config, this);
|
||||
} else if ("clockStop".equals(type)) {
|
||||
node = new ClockOpNode.ClockStopNode(nodeID, config, this);
|
||||
} else if ("clockTest".equals(type)) {
|
||||
node = new ClockOpNode.ClockTestNode(nodeID, config, this);
|
||||
} else if ("call".equals(type)) {
|
||||
node = new JSCallNode(nodeID, config, this);
|
||||
} else if ("bezier".equals(type)) {
|
||||
node = new BezierNode(nodeID, config, this);
|
||||
} else if ("event".equals(type)) {
|
||||
node = new EventNode(nodeID, config, this);
|
||||
} else if ("always".equals(type)) {
|
||||
node = new AlwaysNode(nodeID, config, this);
|
||||
} else if ("concat".equals(type)) {
|
||||
node = new ConcatNode(nodeID, config, this);
|
||||
} else if ("param".equals(type)) {
|
||||
node = new ParamNode(nodeID, config, this);
|
||||
} else if ("func".equals(type)) {
|
||||
node = new FunctionNode(nodeID, config, this);
|
||||
} else if ("callfunc".equals(type)) {
|
||||
node = new CallFuncNode(nodeID, config, this);
|
||||
} else {
|
||||
throw new JSApplicationIllegalArgumentException("Unsupported node type: " + type);
|
||||
}
|
||||
mAnimatedNodes.put(nodeID, node);
|
||||
}
|
||||
|
||||
public void dropNode(int tag) {
|
||||
mAnimatedNodes.remove(tag);
|
||||
}
|
||||
|
||||
public void connectNodes(int parentID, int childID) {
|
||||
Node parentNode = mAnimatedNodes.get(parentID);
|
||||
Node childNode = mAnimatedNodes.get(childID);
|
||||
if (childNode == null) {
|
||||
throw new JSApplicationIllegalArgumentException("Animated node with ID " + childID +
|
||||
" does not exists");
|
||||
}
|
||||
parentNode.addChild(childNode);
|
||||
}
|
||||
|
||||
public void disconnectNodes(int parentID, int childID) {
|
||||
Node parentNode = mAnimatedNodes.get(parentID);
|
||||
Node childNode = mAnimatedNodes.get(childID);
|
||||
if (childNode == null) {
|
||||
throw new JSApplicationIllegalArgumentException("Animated node with ID " + childID +
|
||||
" does not exists");
|
||||
}
|
||||
parentNode.removeChild(childNode);
|
||||
}
|
||||
|
||||
public void connectNodeToView(int nodeID, int viewTag) {
|
||||
Node node = mAnimatedNodes.get(nodeID);
|
||||
if (node == null) {
|
||||
throw new JSApplicationIllegalArgumentException("Animated node with ID " + nodeID +
|
||||
" does not exists");
|
||||
}
|
||||
if (!(node instanceof PropsNode)) {
|
||||
throw new JSApplicationIllegalArgumentException("Animated node connected to view should be" +
|
||||
"of type " + PropsNode.class.getName());
|
||||
}
|
||||
((PropsNode) node).connectToView(viewTag);
|
||||
}
|
||||
|
||||
public void disconnectNodeFromView(int nodeID, int viewTag) {
|
||||
Node node = mAnimatedNodes.get(nodeID);
|
||||
if (node == null) {
|
||||
throw new JSApplicationIllegalArgumentException("Animated node with ID " + nodeID +
|
||||
" does not exists");
|
||||
}
|
||||
if (!(node instanceof PropsNode)) {
|
||||
throw new JSApplicationIllegalArgumentException("Animated node connected to view should be" +
|
||||
"of type " + PropsNode.class.getName());
|
||||
}
|
||||
((PropsNode) node).disconnectFromView(viewTag);
|
||||
}
|
||||
|
||||
public void enqueueUpdateViewOnNativeThread(int viewTag, WritableMap nativeProps) {
|
||||
mOperationsInBatch.add(new NativeUpdateOperation(viewTag, nativeProps));
|
||||
}
|
||||
|
||||
public void attachEvent(int viewTag, String eventName, int eventNodeID) {
|
||||
String key = viewTag + eventName;
|
||||
|
||||
EventNode node = (EventNode) mAnimatedNodes.get(eventNodeID);
|
||||
if (node == null) {
|
||||
throw new JSApplicationIllegalArgumentException("Event node " + eventNodeID + " does not exists");
|
||||
}
|
||||
if (mEventMapping.containsKey(key)) {
|
||||
throw new JSApplicationIllegalArgumentException("Event handler already set for the given view and event type");
|
||||
}
|
||||
|
||||
mEventMapping.put(key, node);
|
||||
}
|
||||
|
||||
public void detachEvent(int viewTag, String eventName, int eventNodeID) {
|
||||
String key = viewTag + eventName;
|
||||
mEventMapping.remove(key);
|
||||
}
|
||||
|
||||
public void configureProps(Set<String> nativePropsSet, Set<String> uiPropsSet) {
|
||||
nativeProps = nativePropsSet;
|
||||
uiProps = uiPropsSet;
|
||||
}
|
||||
|
||||
public void getValue(int nodeID, Callback callback) {
|
||||
callback.invoke(mAnimatedNodes.get(nodeID).value());
|
||||
}
|
||||
|
||||
public void postRunUpdatesAfterAnimation() {
|
||||
mWantRunUpdates = true;
|
||||
startUpdatingOnAnimationFrame();
|
||||
}
|
||||
|
||||
public void postOnAnimation(OnAnimationFrame onAnimationFrame) {
|
||||
mFrameCallbacks.add(onAnimationFrame);
|
||||
startUpdatingOnAnimationFrame();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEventDispatch(Event event) {
|
||||
// Events can be dispatched from any thread so we have to make sure handleEvent is run from the
|
||||
// UI thread.
|
||||
if (UiThreadUtil.isOnUiThread()) {
|
||||
handleEvent(event);
|
||||
} else {
|
||||
mEventQueue.offer(event);
|
||||
startUpdatingOnAnimationFrame();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleEvent(Event event) {
|
||||
if (!mEventMapping.isEmpty()) {
|
||||
// If the event has a different name in native convert it to it's JS name.
|
||||
String eventName = mCustomEventNamesResolver.resolveCustomEventName(event.getEventName());
|
||||
int viewTag = event.getViewTag();
|
||||
String key = viewTag + eventName;
|
||||
EventNode node = mEventMapping.get(key);
|
||||
if (node != null) {
|
||||
event.dispatch(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void sendEvent(String name, WritableMap body) {
|
||||
mEventEmitter.emit(name, body);
|
||||
}
|
||||
|
||||
public void setValue(int nodeID, Double newValue) {
|
||||
Node node = mAnimatedNodes.get(nodeID);
|
||||
if (node != null) {
|
||||
((ValueNode) node).setValue(newValue);
|
||||
}
|
||||
}
|
||||
}
|
226
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/ReanimatedModule.java
generated
vendored
Normal file
226
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/ReanimatedModule.java
generated
vendored
Normal file
@ -0,0 +1,226 @@
|
||||
package com.swmansion.reanimated;
|
||||
|
||||
import com.facebook.react.bridge.Callback;
|
||||
import com.facebook.react.bridge.LifecycleEventListener;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import com.facebook.react.uimanager.NativeViewHierarchyManager;
|
||||
import com.facebook.react.uimanager.UIBlock;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
import com.facebook.react.uimanager.UIManagerModuleListener;
|
||||
import com.swmansion.reanimated.transitions.TransitionModule;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@ReactModule(name = ReanimatedModule.NAME)
|
||||
public class ReanimatedModule extends ReactContextBaseJavaModule implements
|
||||
LifecycleEventListener, UIManagerModuleListener {
|
||||
|
||||
public static final String NAME = "ReanimatedModule";
|
||||
|
||||
private interface UIThreadOperation {
|
||||
void execute(NodesManager nodesManager);
|
||||
}
|
||||
|
||||
private ArrayList<UIThreadOperation> mOperations = new ArrayList<>();
|
||||
|
||||
private @Nullable NodesManager mNodesManager;
|
||||
private @Nullable TransitionModule mTransitionManager;
|
||||
|
||||
public ReanimatedModule(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
ReactApplicationContext reactCtx = getReactApplicationContext();
|
||||
UIManagerModule uiManager = reactCtx.getNativeModule(UIManagerModule.class);
|
||||
reactCtx.addLifecycleEventListener(this);
|
||||
uiManager.addUIManagerListener(this);
|
||||
mTransitionManager = new TransitionModule(uiManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHostPause() {
|
||||
if (mNodesManager != null) {
|
||||
mNodesManager.onHostPause();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHostResume() {
|
||||
if (mNodesManager != null) {
|
||||
mNodesManager.onHostResume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHostDestroy() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void willDispatchViewUpdates(final UIManagerModule uiManager) {
|
||||
if (mOperations.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
final ArrayList<UIThreadOperation> operations = mOperations;
|
||||
mOperations = new ArrayList<>();
|
||||
uiManager.addUIBlock(new UIBlock() {
|
||||
@Override
|
||||
public void execute(NativeViewHierarchyManager nativeViewHierarchyManager) {
|
||||
NodesManager nodesManager = getNodesManager();
|
||||
for (UIThreadOperation operation : operations) {
|
||||
operation.execute(nodesManager);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
private NodesManager getNodesManager() {
|
||||
if (mNodesManager == null) {
|
||||
mNodesManager = new NodesManager(getReactApplicationContext());
|
||||
}
|
||||
|
||||
return mNodesManager;
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void animateNextTransition(int tag, ReadableMap config) {
|
||||
mTransitionManager.animateNextTransition(tag, config);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void createNode(final int tag, final ReadableMap config) {
|
||||
mOperations.add(new UIThreadOperation() {
|
||||
@Override
|
||||
public void execute(NodesManager nodesManager) {
|
||||
nodesManager.createNode(tag, config);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void dropNode(final int tag) {
|
||||
mOperations.add(new UIThreadOperation() {
|
||||
@Override
|
||||
public void execute(NodesManager nodesManager) {
|
||||
nodesManager.dropNode(tag);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void connectNodes(final int parentID, final int childID) {
|
||||
mOperations.add(new UIThreadOperation() {
|
||||
@Override
|
||||
public void execute(NodesManager nodesManager) {
|
||||
nodesManager.connectNodes(parentID, childID);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void disconnectNodes(final int parentID, final int childID) {
|
||||
mOperations.add(new UIThreadOperation() {
|
||||
@Override
|
||||
public void execute(NodesManager nodesManager) {
|
||||
nodesManager.disconnectNodes(parentID, childID);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void connectNodeToView(final int nodeID, final int viewTag) {
|
||||
mOperations.add(new UIThreadOperation() {
|
||||
@Override
|
||||
public void execute(NodesManager nodesManager) {
|
||||
nodesManager.connectNodeToView(nodeID, viewTag);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void disconnectNodeFromView(final int nodeID, final int viewTag) {
|
||||
mOperations.add(new UIThreadOperation() {
|
||||
@Override
|
||||
public void execute(NodesManager nodesManager) {
|
||||
nodesManager.disconnectNodeFromView(nodeID, viewTag);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void attachEvent(final int viewTag, final String eventName, final int eventNodeID) {
|
||||
mOperations.add(new UIThreadOperation() {
|
||||
@Override
|
||||
public void execute(NodesManager nodesManager) {
|
||||
nodesManager.attachEvent(viewTag, eventName, eventNodeID);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void detachEvent(final int viewTag, final String eventName, final int eventNodeID) {
|
||||
mOperations.add(new UIThreadOperation() {
|
||||
@Override
|
||||
public void execute(NodesManager nodesManager) {
|
||||
nodesManager.detachEvent(viewTag, eventName, eventNodeID);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void configureProps(ReadableArray nativePropsArray, ReadableArray uiPropsArray) {
|
||||
int size = nativePropsArray.size();
|
||||
final Set<String> nativeProps = new HashSet<>(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
nativeProps.add(nativePropsArray.getString(i));
|
||||
}
|
||||
|
||||
size = uiPropsArray.size();
|
||||
final Set<String> uiProps = new HashSet<>(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
uiProps.add(uiPropsArray.getString(i));
|
||||
}
|
||||
mOperations.add(new UIThreadOperation() {
|
||||
@Override
|
||||
public void execute(NodesManager nodesManager) {
|
||||
nodesManager.configureProps(nativeProps, uiProps);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void getValue(final int nodeID, final Callback callback) {
|
||||
mOperations.add(new UIThreadOperation() {
|
||||
@Override
|
||||
public void execute(NodesManager nodesManager) {
|
||||
nodesManager.getValue(nodeID, callback);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setValue(final int nodeID, final Double newValue) {
|
||||
mOperations.add(new UIThreadOperation() {
|
||||
@Override
|
||||
public void execute(NodesManager nodesManager) {
|
||||
nodesManager.setValue(nodeID, newValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
21
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/ReanimatedPackage.java
generated
vendored
Normal file
21
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/ReanimatedPackage.java
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
package com.swmansion.reanimated;
|
||||
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class ReanimatedPackage implements ReactPackage {
|
||||
@Override
|
||||
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
|
||||
return Arrays.<NativeModule>asList(new ReanimatedModule(reactContext));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
|
||||
return Arrays.asList();
|
||||
}
|
||||
}
|
13
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/UpdateContext.java
generated
vendored
Normal file
13
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/UpdateContext.java
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
package com.swmansion.reanimated;
|
||||
|
||||
import com.swmansion.reanimated.nodes.Node;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class UpdateContext {
|
||||
|
||||
public long updateLoopID = 0;
|
||||
public String callID = "";
|
||||
public final ArrayList<Node> updatedNodes = new ArrayList<>();
|
||||
|
||||
}
|
31
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/Utils.java
generated
vendored
Normal file
31
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/Utils.java
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
package com.swmansion.reanimated;
|
||||
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.ReadableMapKeySetIterator;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Utils {
|
||||
|
||||
public static Map<String, Integer> processMapping(ReadableMap style) {
|
||||
ReadableMapKeySetIterator iter = style.keySetIterator();
|
||||
HashMap<String, Integer> mapping = new HashMap<>();
|
||||
while (iter.hasNextKey()) {
|
||||
String propKey = iter.nextKey();
|
||||
int nodeIndex = style.getInt(propKey);
|
||||
mapping.put(propKey, nodeIndex);
|
||||
}
|
||||
return mapping;
|
||||
}
|
||||
|
||||
public static int[] processIntArray(ReadableArray ary) {
|
||||
int size = ary.size();
|
||||
int[] res = new int[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
res[i] = ary.getInt(i);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
25
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/AlwaysNode.java
generated
vendored
Normal file
25
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/AlwaysNode.java
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
package com.swmansion.reanimated.nodes;
|
||||
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.swmansion.reanimated.MapUtils;
|
||||
import com.swmansion.reanimated.NodesManager;
|
||||
|
||||
public class AlwaysNode extends Node implements FinalNode {
|
||||
public AlwaysNode(int nodeID, ReadableMap config, NodesManager nodesManager) {
|
||||
super(nodeID, config, nodesManager);
|
||||
mNodeToBeEvaluated = MapUtils.getInt(config, "what", "Reanimated: Argument passed to always node is either of wrong type or is missing.");
|
||||
}
|
||||
|
||||
private int mNodeToBeEvaluated;
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
this.value();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Double evaluate() {
|
||||
mNodesManager.findNodeById(mNodeToBeEvaluated, Node.class).value();
|
||||
return ZERO;
|
||||
}
|
||||
}
|
84
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/BezierNode.java
generated
vendored
Normal file
84
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/BezierNode.java
generated
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
package com.swmansion.reanimated.nodes;
|
||||
|
||||
import android.graphics.PointF;
|
||||
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.swmansion.reanimated.MapUtils;
|
||||
import com.swmansion.reanimated.NodesManager;
|
||||
|
||||
public class BezierNode extends Node {
|
||||
|
||||
private static class CubicBezierInterpolator {
|
||||
|
||||
protected PointF start;
|
||||
protected PointF end;
|
||||
protected PointF a = new PointF();
|
||||
protected PointF b = new PointF();
|
||||
protected PointF c = new PointF();
|
||||
|
||||
public CubicBezierInterpolator(PointF start, PointF end) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
public CubicBezierInterpolator(float startX, float startY, float endX, float endY) {
|
||||
this(new PointF(startX, startY), new PointF(endX, endY));
|
||||
}
|
||||
|
||||
public float getInterpolation(float time) {
|
||||
return getBezierCoordinateY(getXForTime(time));
|
||||
}
|
||||
|
||||
protected float getBezierCoordinateY(float time) {
|
||||
c.y = 3 * start.y;
|
||||
b.y = 3 * (end.y - start.y) - c.y;
|
||||
a.y = 1 - c.y - b.y;
|
||||
return time * (c.y + time * (b.y + time * a.y));
|
||||
}
|
||||
|
||||
protected float getXForTime(float time) {
|
||||
float x = time;
|
||||
float z;
|
||||
for (int i = 1; i < 14; i++) {
|
||||
z = getBezierCoordinateX(x) - time;
|
||||
if (Math.abs(z) < 1e-3) {
|
||||
break;
|
||||
}
|
||||
x -= z / getXDerivate(x);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
private float getXDerivate(float t) {
|
||||
return c.x + t * (2 * b.x + 3 * a.x * t);
|
||||
}
|
||||
|
||||
private float getBezierCoordinateX(float time) {
|
||||
c.x = 3 * start.x;
|
||||
b.x = 3 * (end.x - start.x) - c.x;
|
||||
a.x = 1 - c.x - b.x;
|
||||
return time * (c.x + time * (b.x + time * a.x));
|
||||
}
|
||||
}
|
||||
|
||||
private final int mInputID;
|
||||
private final CubicBezierInterpolator mInterpolator;
|
||||
|
||||
public BezierNode(int nodeID, ReadableMap config, NodesManager nodesManager) {
|
||||
super(nodeID, config, nodesManager);
|
||||
|
||||
mInputID = MapUtils.getInt(config, "input", "Reanimated: Argument passed to bezier node is either of wrong type or is missing.");
|
||||
|
||||
float startX = (float) config.getDouble("mX1");
|
||||
float startY = (float) config.getDouble("mY1");
|
||||
float endX = (float) config.getDouble("mX2");
|
||||
float endY = (float) config.getDouble("mY2");
|
||||
mInterpolator = new CubicBezierInterpolator(startX, startY, endX, endY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Double evaluate() {
|
||||
Double in = (Double) mNodesManager.getNodeValue(mInputID);
|
||||
return Double.valueOf(mInterpolator.getInterpolation(in.floatValue()));
|
||||
}
|
||||
}
|
24
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/BlockNode.java
generated
vendored
Normal file
24
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/BlockNode.java
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
package com.swmansion.reanimated.nodes;
|
||||
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.swmansion.reanimated.NodesManager;
|
||||
import com.swmansion.reanimated.Utils;
|
||||
|
||||
public class BlockNode extends Node {
|
||||
|
||||
private final int[] mBlock;
|
||||
|
||||
public BlockNode(int nodeID, ReadableMap config, NodesManager nodesManager) {
|
||||
super(nodeID, config, nodesManager);
|
||||
mBlock = Utils.processIntArray(config.getArray("block"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object evaluate() {
|
||||
Object res = null;
|
||||
for (int i = 0; i < mBlock.length; i++) {
|
||||
res = mNodesManager.findNodeById(mBlock[i], Node.class).value();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
48
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/CallFuncNode.java
generated
vendored
Normal file
48
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/CallFuncNode.java
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
package com.swmansion.reanimated.nodes;
|
||||
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.swmansion.reanimated.NodesManager;
|
||||
import com.swmansion.reanimated.Utils;
|
||||
|
||||
public class CallFuncNode extends Node {
|
||||
|
||||
private String mPreviousCallID;
|
||||
private final int mWhatNodeID;
|
||||
private final int[] mArgs;
|
||||
private final int[] mParams;
|
||||
|
||||
public CallFuncNode(int nodeID, ReadableMap config, NodesManager nodesManager) {
|
||||
super(nodeID, config, nodesManager);
|
||||
mWhatNodeID = config.getInt("what");
|
||||
mParams = Utils.processIntArray(config.getArray("params"));
|
||||
mArgs = Utils.processIntArray(config.getArray("args"));
|
||||
}
|
||||
|
||||
private void beginContext() {
|
||||
mPreviousCallID = mNodesManager.updateContext.callID;
|
||||
mNodesManager.updateContext.callID = mNodesManager.updateContext.callID + '/' + String.valueOf(mNodeID);
|
||||
for (int i = 0; i < mParams.length; i++) {
|
||||
int paramId = mParams[i];
|
||||
ParamNode paramNode = mNodesManager.findNodeById(paramId, ParamNode.class);
|
||||
paramNode.beginContext(mArgs[i], mPreviousCallID);
|
||||
}
|
||||
}
|
||||
|
||||
private void endContext() {
|
||||
for (int i = 0; i < mParams.length; i++) {
|
||||
int paramId = mParams[i];
|
||||
ParamNode paramNode = mNodesManager.findNodeById(paramId, ParamNode.class);
|
||||
paramNode.endContext();
|
||||
}
|
||||
mNodesManager.updateContext.callID = mPreviousCallID;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object evaluate() {
|
||||
beginContext();
|
||||
Node whatNode = mNodesManager.findNodeById(mWhatNodeID, Node.class);
|
||||
Object retVal = whatNode.value();
|
||||
endContext();
|
||||
return retVal;
|
||||
}
|
||||
}
|
38
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/ClockNode.java
generated
vendored
Normal file
38
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/ClockNode.java
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
package com.swmansion.reanimated.nodes;
|
||||
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.swmansion.reanimated.NodesManager;
|
||||
|
||||
public class ClockNode extends Node implements NodesManager.OnAnimationFrame {
|
||||
|
||||
public boolean isRunning;
|
||||
|
||||
public ClockNode(int nodeID, ReadableMap config, NodesManager nodesManager) {
|
||||
super(nodeID, config, nodesManager);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
if (isRunning) {
|
||||
return;
|
||||
}
|
||||
isRunning = true;
|
||||
mNodesManager.postOnAnimation(this);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
isRunning = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Double evaluate() {
|
||||
return mNodesManager.currentFrameTimeMs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationFrame() {
|
||||
if (isRunning) {
|
||||
markUpdated();
|
||||
mNodesManager.postOnAnimation(this);
|
||||
}
|
||||
}
|
||||
}
|
69
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/ClockOpNode.java
generated
vendored
Normal file
69
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/ClockOpNode.java
generated
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
package com.swmansion.reanimated.nodes;
|
||||
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.swmansion.reanimated.MapUtils;
|
||||
import com.swmansion.reanimated.NodesManager;
|
||||
|
||||
public abstract class ClockOpNode extends Node {
|
||||
|
||||
public static class ClockStartNode extends ClockOpNode {
|
||||
public ClockStartNode(int nodeID, ReadableMap config, NodesManager nodesManager) {
|
||||
super(nodeID, config, nodesManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Double eval(Node clock) {
|
||||
if (clock instanceof ParamNode) {
|
||||
((ParamNode) clock).start();
|
||||
} else {
|
||||
((ClockNode) clock).start();
|
||||
}
|
||||
return ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ClockStopNode extends ClockOpNode {
|
||||
public ClockStopNode(int nodeID, ReadableMap config, NodesManager nodesManager) {
|
||||
super(nodeID, config, nodesManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Double eval(Node clock) {
|
||||
if (clock instanceof ParamNode) {
|
||||
((ParamNode) clock).stop();
|
||||
} else {
|
||||
((ClockNode) clock).stop();
|
||||
}
|
||||
return ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ClockTestNode extends ClockOpNode {
|
||||
public ClockTestNode(int nodeID, ReadableMap config, NodesManager nodesManager) {
|
||||
super(nodeID, config, nodesManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Double eval(Node clock) {
|
||||
if (clock instanceof ParamNode) {
|
||||
return ((ParamNode) clock).isRunning() ? 1. : 0.;
|
||||
}
|
||||
return ((ClockNode) clock).isRunning ? 1. : 0.;
|
||||
}
|
||||
}
|
||||
|
||||
private int clockID;
|
||||
|
||||
public ClockOpNode(int nodeID, ReadableMap config, NodesManager nodesManager) {
|
||||
super(nodeID, config, nodesManager);
|
||||
clockID = MapUtils.getInt(config, "clock", "Reanimated: Argument passed to clock node is either of wrong type or is missing.");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Double evaluate() {
|
||||
Node clock = mNodesManager.findNodeById(clockID, Node.class);
|
||||
return eval(clock);
|
||||
}
|
||||
|
||||
protected abstract Double eval(Node clock);
|
||||
}
|
36
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/ConcatNode.java
generated
vendored
Normal file
36
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/ConcatNode.java
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
package com.swmansion.reanimated.nodes;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Locale;
|
||||
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.swmansion.reanimated.NodesManager;
|
||||
import com.swmansion.reanimated.Utils;
|
||||
|
||||
public class ConcatNode extends Node {
|
||||
private final int[] mInputIDs;
|
||||
private final static NumberFormat sFormatter = NumberFormat.getInstance(Locale.ENGLISH);
|
||||
static {
|
||||
sFormatter.setMinimumFractionDigits(0);
|
||||
sFormatter.setGroupingUsed(false);
|
||||
}
|
||||
|
||||
public ConcatNode(int nodeID, ReadableMap config, NodesManager nodesManager) {
|
||||
super(nodeID, config, nodesManager);
|
||||
mInputIDs = Utils.processIntArray(config.getArray("input"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String evaluate() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < mInputIDs.length; i++) {
|
||||
Node inputNodes = mNodesManager.findNodeById(mInputIDs[i], Node.class);
|
||||
Object value = inputNodes.value();
|
||||
if (value instanceof Double) {
|
||||
value = sFormatter.format((Double) value);
|
||||
}
|
||||
builder.append(value);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
29
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/CondNode.java
generated
vendored
Normal file
29
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/CondNode.java
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
package com.swmansion.reanimated.nodes;
|
||||
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.swmansion.reanimated.MapUtils;
|
||||
import com.swmansion.reanimated.NodesManager;
|
||||
|
||||
public class CondNode extends Node {
|
||||
|
||||
private final int mCondID, mIfBlockID, mElseBlockID;
|
||||
|
||||
public CondNode(int nodeID, ReadableMap config, NodesManager nodesManager) {
|
||||
super(nodeID, config, nodesManager);
|
||||
mCondID = MapUtils.getInt(config, "cond", "Reanimated: First argument passed to cond node is either of wrong type or is missing.");
|
||||
mIfBlockID = MapUtils.getInt(config, "ifBlock", "Reanimated: Second argument passed to cond node is either of wrong type or is missing.");
|
||||
mElseBlockID = config.hasKey("elseBlock")
|
||||
? MapUtils.getInt(config, "elseBlock", "Reanimated: Second argument passed to cond node is either of wrong type or is missing.")
|
||||
: -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object evaluate() {
|
||||
Object cond = mNodesManager.getNodeValue(mCondID);
|
||||
if (cond instanceof Number && ((Number) cond).doubleValue() != 0.0) {
|
||||
// This is not a good way to compare doubles but in this case it is what we want
|
||||
return mIfBlockID != -1 ? mNodesManager.getNodeValue(mIfBlockID) : ZERO;
|
||||
}
|
||||
return mElseBlockID != -1 ? mNodesManager.getNodeValue(mElseBlockID) : ZERO;
|
||||
}
|
||||
}
|
26
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/DebugNode.java
generated
vendored
Normal file
26
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/DebugNode.java
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
package com.swmansion.reanimated.nodes;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.swmansion.reanimated.MapUtils;
|
||||
import com.swmansion.reanimated.NodesManager;
|
||||
|
||||
public class DebugNode extends Node {
|
||||
|
||||
private final String mMessage;
|
||||
private final int mValueID;
|
||||
|
||||
public DebugNode(int nodeID, ReadableMap config, NodesManager nodesManager) {
|
||||
super(nodeID, config, nodesManager);
|
||||
mMessage = MapUtils.getString(config, "message", "Reanimated: First argument passed to debug node is either of wrong type or is missing.");
|
||||
mValueID = MapUtils.getInt(config, "value", "Reanimated: Second argument passed to debug node is either of wrong type or is missing.");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object evaluate() {
|
||||
Object value = mNodesManager.findNodeById(mValueID, Node.class).value();
|
||||
Log.d("REANIMATED", String.format("%s %s", mMessage, value));
|
||||
return value;
|
||||
}
|
||||
}
|
84
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/EventNode.java
generated
vendored
Normal file
84
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/EventNode.java
generated
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
package com.swmansion.reanimated.nodes;
|
||||
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
||||
import com.swmansion.reanimated.NodesManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class EventNode extends Node implements RCTEventEmitter {
|
||||
|
||||
private static class EventMap {
|
||||
private final int nodeID;
|
||||
private final String[] path;
|
||||
|
||||
public EventMap(ReadableArray eventPath) {
|
||||
int size = eventPath.size();
|
||||
path = new String[size - 1];
|
||||
for (int i = 0; i < size - 1; i++) {
|
||||
path[i] = eventPath.getString(i);
|
||||
}
|
||||
nodeID = eventPath.getInt(size - 1);
|
||||
}
|
||||
|
||||
public Double lookupValue(ReadableMap event) {
|
||||
ReadableMap map = event;
|
||||
for (int i = 0; map != null && i < path.length - 1; i++) {
|
||||
String key = path[i];
|
||||
map = map.hasKey(key) ? map.getMap(key) : null;
|
||||
}
|
||||
if (map != null) {
|
||||
String key = path[path.length - 1];
|
||||
return map.hasKey(key) ? map.getDouble(key) : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static List<EventMap> processMapping(ReadableArray mapping) {
|
||||
int size = mapping.size();
|
||||
List<EventMap> res = new ArrayList<>(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
res.add(new EventMap(mapping.getArray(i)));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private final List<EventMap> mMapping;
|
||||
|
||||
public EventNode(int nodeID, ReadableMap config, NodesManager nodesManager) {
|
||||
super(nodeID, config, nodesManager);
|
||||
mMapping = processMapping(config.getArray("argMapping"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveEvent(int targetTag, String eventName, @Nullable WritableMap event) {
|
||||
if (event == null) {
|
||||
throw new IllegalArgumentException("Animated events must have event data.");
|
||||
}
|
||||
|
||||
for (int i = 0; i < mMapping.size(); i++) {
|
||||
EventMap eventMap = mMapping.get(i);
|
||||
Double value = eventMap.lookupValue(event);
|
||||
if (value != null) {
|
||||
mNodesManager.findNodeById(eventMap.nodeID, ValueNode.class).setValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveTouches(String eventName, WritableArray touches, WritableArray changedIndices) {
|
||||
throw new RuntimeException("receiveTouches is not support by animated events");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Double evaluate() {
|
||||
return ZERO;
|
||||
}
|
||||
}
|
5
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/FinalNode.java
generated
vendored
Normal file
5
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/FinalNode.java
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
package com.swmansion.reanimated.nodes;
|
||||
|
||||
public interface FinalNode {
|
||||
void update();
|
||||
}
|
20
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/FunctionNode.java
generated
vendored
Normal file
20
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/FunctionNode.java
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
package com.swmansion.reanimated.nodes;
|
||||
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.swmansion.reanimated.NodesManager;
|
||||
|
||||
public class FunctionNode extends Node {
|
||||
|
||||
private final int mWhatNodeID;
|
||||
|
||||
public FunctionNode(int nodeID, ReadableMap config, NodesManager nodesManager) {
|
||||
super(nodeID, config, nodesManager);
|
||||
mWhatNodeID = config.getInt("what");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object evaluate() {
|
||||
Node what = mNodesManager.findNodeById(mWhatNodeID, Node.class);
|
||||
return what.value();
|
||||
}
|
||||
}
|
41
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/JSCallNode.java
generated
vendored
Normal file
41
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/JSCallNode.java
generated
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
package com.swmansion.reanimated.nodes;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.swmansion.reanimated.NodesManager;
|
||||
import com.swmansion.reanimated.Utils;
|
||||
|
||||
public class JSCallNode extends Node {
|
||||
|
||||
private final int[] mInputIDs;
|
||||
|
||||
public JSCallNode(int nodeID, ReadableMap config, NodesManager nodesManager) {
|
||||
super(nodeID, config, nodesManager);
|
||||
mInputIDs = Utils.processIntArray(config.getArray("input"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Double evaluate() {
|
||||
WritableArray args = Arguments.createArray();
|
||||
for (int i = 0; i < mInputIDs.length; i++) {
|
||||
Node node = mNodesManager.findNodeById(mInputIDs[i], Node.class);
|
||||
if (node.value() == null) {
|
||||
args.pushNull();
|
||||
} else {
|
||||
Object value = node.value();
|
||||
if (value instanceof String) {
|
||||
args.pushString((String) value);
|
||||
} else {
|
||||
args.pushDouble(node.doubleValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
WritableMap eventData = Arguments.createMap();
|
||||
eventData.putInt("id", mNodeID);
|
||||
eventData.putArray("args", args);
|
||||
mNodesManager.sendEvent("onReanimatedCall", eventData);
|
||||
return ZERO;
|
||||
}
|
||||
}
|
137
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/Node.java
generated
vendored
Normal file
137
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/Node.java
generated
vendored
Normal file
@ -0,0 +1,137 @@
|
||||
package com.swmansion.reanimated.nodes;
|
||||
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.UiThreadUtil;
|
||||
import com.swmansion.reanimated.NodesManager;
|
||||
import com.swmansion.reanimated.UpdateContext;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class Node {
|
||||
|
||||
public static final Double ZERO = Double.valueOf(0);
|
||||
public static final Double ONE = Double.valueOf(1);
|
||||
|
||||
protected final int mNodeID;
|
||||
protected final NodesManager mNodesManager;
|
||||
|
||||
protected final UpdateContext mUpdateContext;
|
||||
|
||||
private final Map<String, Long> mLastLoopID = new HashMap<>();
|
||||
private final Map<String, Object> mMemoizedValue = new HashMap<>();
|
||||
private @Nullable List<Node> mChildren; /* lazy-initialized when a child is added */
|
||||
|
||||
public Node(int nodeID, @Nullable ReadableMap config, NodesManager nodesManager) {
|
||||
mLastLoopID.put("", -1L);
|
||||
mNodeID = nodeID;
|
||||
mNodesManager = nodesManager;
|
||||
mUpdateContext = nodesManager.updateContext;
|
||||
}
|
||||
|
||||
protected abstract @Nullable Object evaluate();
|
||||
|
||||
public final @Nullable Object value() {
|
||||
if (!mLastLoopID.containsKey(mUpdateContext.callID) || mLastLoopID.get(mUpdateContext.callID) < mUpdateContext.updateLoopID) {
|
||||
mLastLoopID.put(mUpdateContext.callID, mUpdateContext.updateLoopID);
|
||||
Object result = evaluate();
|
||||
mMemoizedValue.put(mUpdateContext.callID, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
return mMemoizedValue.get(mUpdateContext.callID);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will never return null. If value is null or of a different type we try to cast and
|
||||
* return 0 if we fail to properly cast the value. This is to match iOS behavior where the node
|
||||
* would not throw even if the value was not set.
|
||||
*/
|
||||
public final Double doubleValue() {
|
||||
Object value = value();
|
||||
if (value == null) {
|
||||
return ZERO;
|
||||
} else if (value instanceof Double) {
|
||||
return (Double) value;
|
||||
} else if (value instanceof Number) {
|
||||
return Double.valueOf(((Number) value).doubleValue());
|
||||
} else if (value instanceof Boolean) {
|
||||
return ((Boolean) value).booleanValue() ? ONE : ZERO;
|
||||
}
|
||||
throw new IllegalStateException("Value of node " + this + " cannot be cast to a number");
|
||||
}
|
||||
|
||||
public void addChild(Node child) {
|
||||
if (mChildren == null) {
|
||||
mChildren = new ArrayList<>();
|
||||
}
|
||||
mChildren.add(child);
|
||||
child.dangerouslyRescheduleEvaluate();
|
||||
}
|
||||
|
||||
public void removeChild(Node child) {
|
||||
if (mChildren != null) {
|
||||
mChildren.remove(child);
|
||||
}
|
||||
}
|
||||
|
||||
protected void markUpdated() {
|
||||
UiThreadUtil.assertOnUiThread();
|
||||
mUpdateContext.updatedNodes.add(this);
|
||||
mNodesManager.postRunUpdatesAfterAnimation();
|
||||
}
|
||||
|
||||
protected final void dangerouslyRescheduleEvaluate() {
|
||||
mLastLoopID.put(mUpdateContext.callID, -1L);
|
||||
markUpdated();
|
||||
}
|
||||
|
||||
protected final void forceUpdateMemoizedValue(Object value) {
|
||||
mMemoizedValue.put(mUpdateContext.callID, value);
|
||||
markUpdated();
|
||||
}
|
||||
|
||||
private static void findAndUpdateNodes(Node node, Set<Node> visitedNodes, Stack<FinalNode> finalNodes) {
|
||||
if (visitedNodes.contains(node)) {
|
||||
return;
|
||||
} else {
|
||||
visitedNodes.add(node);
|
||||
}
|
||||
|
||||
List<Node> children = node.mChildren;
|
||||
if (children != null) {
|
||||
for (Node child : children) {
|
||||
findAndUpdateNodes(child, visitedNodes, finalNodes);
|
||||
}
|
||||
}
|
||||
if (node instanceof FinalNode) {
|
||||
finalNodes.push((FinalNode) node);
|
||||
}
|
||||
}
|
||||
|
||||
public static void runUpdates(UpdateContext updateContext) {
|
||||
UiThreadUtil.assertOnUiThread();
|
||||
ArrayList<Node> updatedNodes = updateContext.updatedNodes;
|
||||
Set<Node> visitedNodes = new HashSet<>();
|
||||
Stack<FinalNode> finalNodes = new Stack<>();
|
||||
for (int i = 0; i < updatedNodes.size(); i++) {
|
||||
findAndUpdateNodes(updatedNodes.get(i), visitedNodes, finalNodes);
|
||||
if (i == updatedNodes.size() - 1) {
|
||||
while (!finalNodes.isEmpty()) {
|
||||
finalNodes.pop().update();
|
||||
}
|
||||
}
|
||||
}
|
||||
updatedNodes.clear();
|
||||
updateContext.updateLoopID++;
|
||||
}
|
||||
}
|
37
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/NoopNode.java
generated
vendored
Normal file
37
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/NoopNode.java
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
package com.swmansion.reanimated.nodes;
|
||||
|
||||
import com.swmansion.reanimated.NodesManager;
|
||||
|
||||
/**
|
||||
* This node is used by {@link NodesManager} to return in place of a missing node that might have
|
||||
* been requested. This way we avoid a top of null-checks and we make nodes manager compatible with
|
||||
* the iOS code which does not crash for missing nodes. In most of the cases it is desirable to
|
||||
* handle missing nodes gracefully as it usually means the node hasn't been hooked under animated
|
||||
* view prop but is referenced in the graph (e.g. to support some edge case).
|
||||
*/
|
||||
public class NoopNode extends ValueNode {
|
||||
|
||||
public NoopNode(NodesManager nodesManager) {
|
||||
super(-2, null, nodesManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(Object value) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addChild(Node child) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeChild(Node child) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void markUpdated() {
|
||||
// no-op
|
||||
}
|
||||
}
|
346
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/OperatorNode.java
generated
vendored
Normal file
346
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/OperatorNode.java
generated
vendored
Normal file
@ -0,0 +1,346 @@
|
||||
package com.swmansion.reanimated.nodes;
|
||||
|
||||
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.swmansion.reanimated.NodesManager;
|
||||
import com.swmansion.reanimated.Utils;
|
||||
|
||||
public class OperatorNode extends Node {
|
||||
|
||||
private static boolean truthy(Object value) {
|
||||
return value != null && !value.equals(0.);
|
||||
}
|
||||
|
||||
private interface Operator {
|
||||
double evaluate(Node[] input);
|
||||
}
|
||||
|
||||
private static abstract class ReduceOperator implements Operator {
|
||||
@Override
|
||||
public double evaluate(Node[] input) {
|
||||
double acc = input[0].doubleValue();
|
||||
for (int i = 1; i < input.length; i++) {
|
||||
acc = reduce(acc, input[i].doubleValue());
|
||||
}
|
||||
return acc;
|
||||
}
|
||||
|
||||
public abstract double reduce(Double x, Double y);
|
||||
}
|
||||
|
||||
private static abstract class SingleOperator implements Operator {
|
||||
@Override
|
||||
public double evaluate(Node[] input) {
|
||||
return eval((Double) input[0].value());
|
||||
}
|
||||
|
||||
public abstract double eval(Double x);
|
||||
}
|
||||
|
||||
private static abstract class CompOperator implements Operator {
|
||||
@Override
|
||||
public double evaluate(Node[] input) {
|
||||
return eval((Double) input[0].value(), (Double) input[1].value()) ? 1. : 0.;
|
||||
}
|
||||
|
||||
public abstract boolean eval(Double x, Double y);
|
||||
}
|
||||
|
||||
// arithmetic
|
||||
private static final Operator ADD = new ReduceOperator() {
|
||||
@Override
|
||||
public double reduce(Double x, Double y) {
|
||||
return x + y;
|
||||
}
|
||||
};
|
||||
private static final Operator SUB = new ReduceOperator() {
|
||||
@Override
|
||||
public double reduce(Double x, Double y) {
|
||||
return x - y;
|
||||
}
|
||||
};
|
||||
private static final Operator MULTIPLY= new ReduceOperator() {
|
||||
@Override
|
||||
public double reduce(Double x, Double y) {
|
||||
return x * y;
|
||||
}
|
||||
};
|
||||
private static final Operator DIVIDE = new ReduceOperator() {
|
||||
@Override
|
||||
public double reduce(Double x, Double y) {
|
||||
return x / y;
|
||||
}
|
||||
};
|
||||
private static final Operator POW = new ReduceOperator() {
|
||||
@Override
|
||||
public double reduce(Double x, Double y) {
|
||||
return Math.pow(x, y);
|
||||
}
|
||||
};
|
||||
private static final Operator MODULO = new ReduceOperator() {
|
||||
@Override
|
||||
public double reduce(Double x, Double y) {
|
||||
return ((x % y) + y) % y;
|
||||
}
|
||||
};
|
||||
private static final Operator SQRT = new SingleOperator() {
|
||||
@Override
|
||||
public double eval(Double x) {
|
||||
return Math.sqrt(x);
|
||||
}
|
||||
};
|
||||
private static final Operator LOG = new SingleOperator() {
|
||||
@Override
|
||||
public double eval(Double x) {
|
||||
return Math.log(x);
|
||||
}
|
||||
};
|
||||
private static final Operator SIN = new SingleOperator() {
|
||||
@Override
|
||||
public double eval(Double x) {
|
||||
return Math.sin(x);
|
||||
}
|
||||
};
|
||||
private static final Operator COS = new SingleOperator() {
|
||||
@Override
|
||||
public double eval(Double x) {
|
||||
return Math.cos(x);
|
||||
}
|
||||
};
|
||||
private static final Operator TAN = new SingleOperator() {
|
||||
@Override
|
||||
public double eval(Double x) {
|
||||
return Math.tan(x);
|
||||
}
|
||||
};
|
||||
private static final Operator ACOS = new SingleOperator() {
|
||||
@Override
|
||||
public double eval(Double x) {
|
||||
return Math.acos(x);
|
||||
}
|
||||
};
|
||||
private static final Operator ASIN = new SingleOperator() {
|
||||
@Override
|
||||
public double eval(Double x) {
|
||||
return Math.asin(x);
|
||||
}
|
||||
};
|
||||
private static final Operator ATAN = new SingleOperator() {
|
||||
@Override
|
||||
public double eval(Double x) {
|
||||
return Math.atan(x);
|
||||
}
|
||||
};
|
||||
private static final Operator EXP = new SingleOperator() {
|
||||
@Override
|
||||
public double eval(Double x) {
|
||||
return Math.exp(x);
|
||||
}
|
||||
};
|
||||
private static final Operator ROUND = new SingleOperator() {
|
||||
@Override
|
||||
public double eval(Double x) {
|
||||
return Math.round(x);
|
||||
}
|
||||
};
|
||||
private static final Operator ABS = new SingleOperator() {
|
||||
@Override
|
||||
public double eval(Double x) {
|
||||
return Math.abs(x);
|
||||
}
|
||||
};
|
||||
private static final Operator FLOOR = new SingleOperator() {
|
||||
@Override
|
||||
public double eval(Double x) {
|
||||
return Math.floor(x);
|
||||
}
|
||||
};
|
||||
private static final Operator CEIL = new SingleOperator() {
|
||||
@Override
|
||||
public double eval(Double x) {
|
||||
return Math.ceil(x);
|
||||
}
|
||||
};
|
||||
private static final Operator MIN = new ReduceOperator() {
|
||||
@Override
|
||||
public double reduce(Double x, Double y) {
|
||||
return Math.min(x, y);
|
||||
}
|
||||
};
|
||||
private static final Operator MAX = new ReduceOperator() {
|
||||
@Override
|
||||
public double reduce(Double x, Double y) {
|
||||
return Math.max(x, y);
|
||||
}
|
||||
};
|
||||
|
||||
// logical
|
||||
private static final Operator AND = new Operator() {
|
||||
@Override
|
||||
public double evaluate(Node[] input) {
|
||||
boolean res = truthy(input[0].value());
|
||||
for (int i = 1; i < input.length && res; i++) {
|
||||
res = res && truthy(input[i].value());
|
||||
}
|
||||
return res ? 1. : 0.;
|
||||
}
|
||||
};
|
||||
private static final Operator OR = new Operator() {
|
||||
@Override
|
||||
public double evaluate(Node[] input) {
|
||||
boolean res = truthy(input[0].value());
|
||||
for (int i = 1; i < input.length && !res; i++) {
|
||||
res = res || truthy(input[i].value());
|
||||
}
|
||||
return res ? 1. : 0.;
|
||||
}
|
||||
};
|
||||
private static final Operator NOT = new Operator() {
|
||||
@Override
|
||||
public double evaluate(Node[] input) {
|
||||
return truthy(input[0].value()) ? 0. : 1.;
|
||||
}
|
||||
};
|
||||
private static final Operator DEFINED = new Operator() {
|
||||
@Override
|
||||
public double evaluate(Node[] input) {
|
||||
Object res = input[0].value();
|
||||
return (res != null && !(res instanceof Double && ((Double) res).isNaN())) ? 1. : 0.;
|
||||
}
|
||||
};
|
||||
|
||||
// comparison
|
||||
private static final Operator LESS_THAN = new CompOperator() {
|
||||
@Override
|
||||
public boolean eval(Double x, Double y) {
|
||||
if (x == null || y == null) {
|
||||
return false;
|
||||
}
|
||||
return x < y;
|
||||
}
|
||||
};
|
||||
private static final Operator EQ = new CompOperator() {
|
||||
@Override
|
||||
public boolean eval(Double x, Double y) {
|
||||
if (x == null || y == null) {
|
||||
return x == y;
|
||||
}
|
||||
return x.doubleValue() == y.doubleValue();
|
||||
}
|
||||
};
|
||||
private static final Operator GREATER_THAN = new CompOperator() {
|
||||
@Override
|
||||
public boolean eval(Double x, Double y) {
|
||||
if (x == null || y == null) {
|
||||
return false;
|
||||
}
|
||||
return x > y;
|
||||
}
|
||||
};
|
||||
private static final Operator LESS_OR_EQ = new CompOperator() {
|
||||
@Override
|
||||
public boolean eval(Double x, Double y) {
|
||||
return x <= y;
|
||||
}
|
||||
};
|
||||
private static final Operator GREATER_OR_EQ = new CompOperator() {
|
||||
@Override
|
||||
public boolean eval(Double x, Double y) {
|
||||
return x >= y;
|
||||
}
|
||||
};
|
||||
private static final Operator NEQ = new CompOperator() {
|
||||
@Override
|
||||
public boolean eval(Double x, Double y) {
|
||||
if (x == null || y == null) {
|
||||
return x == y;
|
||||
}
|
||||
return x.doubleValue() != y.doubleValue();
|
||||
}
|
||||
};
|
||||
|
||||
private final int[] mInputIDs;
|
||||
private final Node[] mInputNodes;
|
||||
private final Operator mOperator;
|
||||
|
||||
public OperatorNode(int nodeID, ReadableMap config, NodesManager nodesManager) {
|
||||
super(nodeID, config, nodesManager);
|
||||
mInputIDs = Utils.processIntArray(config.getArray("input"));
|
||||
mInputNodes = new Node[mInputIDs.length];
|
||||
|
||||
String op = config.getString("op");
|
||||
if ("add".equals(op)) {
|
||||
mOperator = ADD;
|
||||
} else if ("sub".equals(op)) {
|
||||
mOperator = SUB;
|
||||
} else if ("multiply".equals(op)) {
|
||||
mOperator = MULTIPLY;
|
||||
} else if ("divide".equals(op)) {
|
||||
mOperator = DIVIDE;
|
||||
} else if ("pow".equals(op)) {
|
||||
mOperator = POW;
|
||||
} else if ("modulo".equals(op)) {
|
||||
mOperator = MODULO;
|
||||
} else if ("sqrt".equals(op)) {
|
||||
mOperator = SQRT;
|
||||
} else if ("log".equals(op)) {
|
||||
mOperator = LOG;
|
||||
} else if ("sin".equals(op)) {
|
||||
mOperator = SIN;
|
||||
} else if ("cos".equals(op)) {
|
||||
mOperator = COS;
|
||||
} else if ("tan".equals(op)) {
|
||||
mOperator = TAN;
|
||||
} else if ("acos".equals(op)) {
|
||||
mOperator = ACOS;
|
||||
} else if ("asin".equals(op)) {
|
||||
mOperator = ASIN;
|
||||
} else if ("atan".equals(op)) {
|
||||
mOperator = ATAN;
|
||||
} else if ("exp".equals(op)) {
|
||||
mOperator = EXP;
|
||||
} else if ("round".equals(op)) {
|
||||
mOperator = ROUND;
|
||||
} else if ("and".equals(op)) {
|
||||
mOperator = AND;
|
||||
} else if ("or".equals(op)) {
|
||||
mOperator = OR;
|
||||
} else if ("not".equals(op)) {
|
||||
mOperator = NOT;
|
||||
} else if ("defined".equals(op)) {
|
||||
mOperator = DEFINED;
|
||||
} else if ("lessThan".equals(op)) {
|
||||
mOperator = LESS_THAN;
|
||||
} else if ("eq".equals(op)) {
|
||||
mOperator = EQ;
|
||||
} else if ("greaterThan".equals(op)) {
|
||||
mOperator = GREATER_THAN;
|
||||
} else if ("lessOrEq".equals(op)) {
|
||||
mOperator = LESS_OR_EQ;
|
||||
} else if ("greaterOrEq".equals(op)) {
|
||||
mOperator = GREATER_OR_EQ;
|
||||
} else if ("neq".equals(op)) {
|
||||
mOperator = NEQ;
|
||||
} else if ("abs".equals(op)) {
|
||||
mOperator = ABS;
|
||||
}else if ("floor".equals(op)) {
|
||||
mOperator = FLOOR;
|
||||
}else if ("ceil".equals(op)) {
|
||||
mOperator = CEIL;
|
||||
}else if ("max".equals(op)) {
|
||||
mOperator = MAX;
|
||||
}else if ("min".equals(op)) {
|
||||
mOperator = MIN;
|
||||
} else {
|
||||
throw new JSApplicationIllegalArgumentException("Unrecognized operator " + op);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object evaluate() {
|
||||
for (int i = 0; i < mInputIDs.length; i++) {
|
||||
mInputNodes[i] = mNodesManager.findNodeById(mInputIDs[i], Node.class);
|
||||
}
|
||||
return mOperator.evaluate(mInputNodes);
|
||||
}
|
||||
}
|
76
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/ParamNode.java
generated
vendored
Normal file
76
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/ParamNode.java
generated
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
package com.swmansion.reanimated.nodes;
|
||||
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.swmansion.reanimated.NodesManager;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
public class ParamNode extends ValueNode {
|
||||
|
||||
private final Stack<Integer> mArgsStack;
|
||||
private String mPrevCallID;
|
||||
|
||||
public ParamNode(int nodeID, ReadableMap config, NodesManager nodesManager) {
|
||||
super(nodeID, config, nodesManager);
|
||||
mArgsStack = new Stack<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(Object value) {
|
||||
Node node = mNodesManager.findNodeById(mArgsStack.peek(), Node.class);
|
||||
String callID = mUpdateContext.callID;
|
||||
mUpdateContext.callID = mPrevCallID;
|
||||
((ValueNode) node).setValue(value);
|
||||
mUpdateContext.callID = callID;
|
||||
forceUpdateMemoizedValue(value);
|
||||
}
|
||||
|
||||
public void beginContext(Integer ref, String prevCallID) {
|
||||
mPrevCallID = prevCallID;
|
||||
mArgsStack.push(ref);
|
||||
}
|
||||
|
||||
|
||||
public void endContext() {
|
||||
mArgsStack.pop();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Object evaluate() {
|
||||
String callID = mUpdateContext.callID;
|
||||
mUpdateContext.callID = mPrevCallID;
|
||||
Node node = mNodesManager.findNodeById(mArgsStack.peek(), Node.class);
|
||||
Object val = node.value();
|
||||
mUpdateContext.callID = callID;
|
||||
return val;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
Node node = mNodesManager.findNodeById(mArgsStack.peek(), Node.class);
|
||||
if (node instanceof ParamNode) {
|
||||
((ParamNode) node).start();
|
||||
} else {
|
||||
((ClockNode) node).start();
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
Node node = mNodesManager.findNodeById(mArgsStack.peek(), Node.class);
|
||||
if (node instanceof ParamNode) {
|
||||
((ParamNode) node).stop();
|
||||
} else {
|
||||
((ClockNode) node).stop();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
Node node = mNodesManager.findNodeById(mArgsStack.peek(), Node.class);
|
||||
if (node instanceof ParamNode) {
|
||||
return ((ParamNode) node).isRunning();
|
||||
}
|
||||
return ((ClockNode) node).isRunning;
|
||||
}
|
||||
}
|
||||
|
||||
|
157
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/PropsNode.java
generated
vendored
Normal file
157
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/PropsNode.java
generated
vendored
Normal file
@ -0,0 +1,157 @@
|
||||
package com.swmansion.reanimated.nodes;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.JavaOnlyMap;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.ReadableMapKeySetIterator;
|
||||
import com.facebook.react.bridge.ReadableType;
|
||||
import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.uimanager.ReactStylesDiffMap;
|
||||
import com.facebook.react.uimanager.UIImplementation;
|
||||
import com.swmansion.reanimated.NodesManager;
|
||||
import com.swmansion.reanimated.Utils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class PropsNode extends Node implements FinalNode {
|
||||
|
||||
private final Map<String, Integer> mMapping;
|
||||
private final UIImplementation mUIImplementation;
|
||||
private int mConnectedViewTag = View.NO_ID;
|
||||
|
||||
private final JavaOnlyMap mPropMap;
|
||||
private final ReactStylesDiffMap mDiffMap;
|
||||
|
||||
private static void addProp(WritableMap propMap, String key, Object value) {
|
||||
if (value == null) {
|
||||
propMap.putNull(key);
|
||||
} else if (value instanceof Double) {
|
||||
propMap.putDouble(key, (Double) value);
|
||||
} else if (value instanceof Integer) {
|
||||
propMap.putInt(key, (Integer) value);
|
||||
} else if (value instanceof Number) {
|
||||
propMap.putDouble(key, ((Number) value).doubleValue());
|
||||
} else if (value instanceof Boolean) {
|
||||
propMap.putBoolean(key, (Boolean) value);
|
||||
} else if (value instanceof String) {
|
||||
propMap.putString(key, (String) value);
|
||||
} else if (value instanceof WritableArray) {
|
||||
propMap.putArray(key, (WritableArray)value);
|
||||
} else if (value instanceof WritableMap) {
|
||||
propMap.putMap(key, (WritableMap)value);
|
||||
} else {
|
||||
throw new IllegalStateException("Unknown type of animated value");
|
||||
}
|
||||
}
|
||||
|
||||
public PropsNode(
|
||||
int nodeID,
|
||||
ReadableMap config,
|
||||
NodesManager nodesManager,
|
||||
UIImplementation uiImplementation) {
|
||||
super(nodeID, config, nodesManager);
|
||||
mMapping = Utils.processMapping(config.getMap("props"));
|
||||
mUIImplementation = uiImplementation;
|
||||
mPropMap = new JavaOnlyMap();
|
||||
mDiffMap = new ReactStylesDiffMap(mPropMap);
|
||||
}
|
||||
|
||||
public void connectToView(int viewTag) {
|
||||
mConnectedViewTag = viewTag;
|
||||
dangerouslyRescheduleEvaluate();
|
||||
}
|
||||
|
||||
public void disconnectFromView(int viewTag) {
|
||||
mConnectedViewTag = View.NO_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Double evaluate() {
|
||||
boolean hasUIProps = false;
|
||||
boolean hasNativeProps = false;
|
||||
boolean hasJSProps = false;
|
||||
WritableMap jsProps = Arguments.createMap();
|
||||
final WritableMap nativeProps = Arguments.createMap();
|
||||
|
||||
for (Map.Entry<String, Integer> entry : mMapping.entrySet()) {
|
||||
Node node = mNodesManager.findNodeById(entry.getValue(), Node.class);
|
||||
if (node instanceof StyleNode) {
|
||||
WritableMap style = (WritableMap) node.value();
|
||||
ReadableMapKeySetIterator iter = style.keySetIterator();
|
||||
while (iter.hasNextKey()) {
|
||||
String key = iter.nextKey();
|
||||
WritableMap dest;
|
||||
if (mNodesManager.uiProps.contains(key)) {
|
||||
hasUIProps = true;
|
||||
dest = mPropMap;
|
||||
} else if (mNodesManager.nativeProps.contains(key)){
|
||||
hasNativeProps = true;
|
||||
dest = nativeProps;
|
||||
} else {
|
||||
hasJSProps = true;
|
||||
dest = jsProps;
|
||||
}
|
||||
ReadableType type = style.getType(key);
|
||||
switch (type) {
|
||||
case Number:
|
||||
dest.putDouble(key, style.getDouble(key));
|
||||
break;
|
||||
case String:
|
||||
dest.putString(key, style.getString(key));
|
||||
break;
|
||||
case Array:
|
||||
dest.putArray(key, (WritableArray) style.getArray(key));
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unexpected type " + type);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String key = entry.getKey();
|
||||
Object value = node.value();
|
||||
if (mNodesManager.uiProps.contains(key)) {
|
||||
hasUIProps = true;
|
||||
addProp(mPropMap, key, value);
|
||||
} else {
|
||||
hasNativeProps = true;
|
||||
addProp(nativeProps, key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mConnectedViewTag != View.NO_ID) {
|
||||
if (hasUIProps) {
|
||||
mUIImplementation.synchronouslyUpdateViewOnUIThread(
|
||||
mConnectedViewTag,
|
||||
mDiffMap);
|
||||
}
|
||||
if (hasNativeProps) {
|
||||
mNodesManager.enqueueUpdateViewOnNativeThread(mConnectedViewTag, nativeProps);
|
||||
}
|
||||
if (hasJSProps) {
|
||||
WritableMap evt = Arguments.createMap();
|
||||
evt.putInt("viewTag", mConnectedViewTag);
|
||||
evt.putMap("props", jsProps);
|
||||
mNodesManager.sendEvent("onReanimatedPropsChange", evt);
|
||||
}
|
||||
}
|
||||
|
||||
return ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
// Since we are updating nodes after detaching them from views there is a time where it's
|
||||
// possible that the view was disconnected and still receive an update, this is normal and
|
||||
// we can simply skip that update.
|
||||
if (mConnectedViewTag == View.NO_ID) {
|
||||
return;
|
||||
}
|
||||
|
||||
// call value for side effect (diff map update via changes made to prop map)
|
||||
value();
|
||||
}
|
||||
}
|
27
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/SetNode.java
generated
vendored
Normal file
27
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/SetNode.java
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
package com.swmansion.reanimated.nodes;
|
||||
|
||||
import com.facebook.react.bridge.JSApplicationCausedNativeException;
|
||||
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
|
||||
import com.facebook.react.bridge.NoSuchKeyException;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.swmansion.reanimated.MapUtils;
|
||||
import com.swmansion.reanimated.NodesManager;
|
||||
|
||||
public class SetNode extends Node {
|
||||
|
||||
private int mWhatNodeID, mValueNodeID;
|
||||
|
||||
public SetNode(int nodeID, ReadableMap config, NodesManager nodesManager) {
|
||||
super(nodeID, config, nodesManager);
|
||||
mWhatNodeID = MapUtils.getInt(config, "what", "Reanimated: First argument passed to set node is either of wrong type or is missing.");
|
||||
mValueNodeID = MapUtils.getInt(config, "value", "Reanimated: Second argument passed to set node is either of wrong type or is missing.");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object evaluate() {
|
||||
Object newValue = mNodesManager.getNodeValue(mValueNodeID);
|
||||
ValueNode what = mNodesManager.findNodeById(mWhatNodeID, ValueNode.class);
|
||||
what.setValue(newValue);
|
||||
return newValue;
|
||||
}
|
||||
}
|
43
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/StyleNode.java
generated
vendored
Normal file
43
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/StyleNode.java
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
package com.swmansion.reanimated.nodes;
|
||||
|
||||
import com.facebook.react.bridge.JavaOnlyMap;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.swmansion.reanimated.NodesManager;
|
||||
import com.swmansion.reanimated.Utils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class StyleNode extends Node {
|
||||
|
||||
private final Map<String, Integer> mMapping;
|
||||
|
||||
public StyleNode(int nodeID, ReadableMap config, NodesManager nodesManager) {
|
||||
super(nodeID, config, nodesManager);
|
||||
mMapping = Utils.processMapping(config.getMap("style"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected WritableMap evaluate() {
|
||||
JavaOnlyMap propMap = new JavaOnlyMap();
|
||||
for (Map.Entry<String, Integer> entry : mMapping.entrySet()) {
|
||||
Node node = mNodesManager.findNodeById(entry.getValue(), Node.class);
|
||||
if (node instanceof TransformNode) {
|
||||
propMap.putArray(entry.getKey(), (WritableArray) node.value());
|
||||
} else {
|
||||
Object val = node.value();
|
||||
if (val instanceof Double) {
|
||||
propMap.putDouble(entry.getKey(), (Double) val);
|
||||
} else if (val instanceof String) {
|
||||
propMap.putString(entry.getKey(), (String) val);
|
||||
} else {
|
||||
throw new IllegalStateException("Wrong style form");
|
||||
}
|
||||
}
|
||||
}
|
||||
return propMap;
|
||||
}
|
||||
}
|
85
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/TransformNode.java
generated
vendored
Normal file
85
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/TransformNode.java
generated
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
package com.swmansion.reanimated.nodes;
|
||||
|
||||
import com.facebook.react.bridge.JavaOnlyArray;
|
||||
import com.facebook.react.bridge.JavaOnlyMap;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.ReadableType;
|
||||
import com.facebook.react.bridge.WritableArray;
|
||||
import com.swmansion.reanimated.NodesManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TransformNode extends Node {
|
||||
|
||||
private static abstract class TransformConfig {
|
||||
public String propertyName;
|
||||
|
||||
public abstract Object getValue(NodesManager nodesManager);
|
||||
}
|
||||
|
||||
private static class AnimatedTransformConfig extends TransformConfig {
|
||||
public int nodeID;
|
||||
|
||||
@Override
|
||||
public Object getValue(NodesManager nodesManager) {
|
||||
return nodesManager.getNodeValue(nodeID);
|
||||
}
|
||||
}
|
||||
|
||||
private static class StaticTransformConfig extends TransformConfig {
|
||||
public Object value;
|
||||
|
||||
@Override
|
||||
public Object getValue(NodesManager nodesManager) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private static List<TransformConfig> processTransforms(ReadableArray transforms) {
|
||||
List<TransformConfig> configs = new ArrayList<>(transforms.size());
|
||||
for (int i = 0; i < transforms.size(); i++) {
|
||||
ReadableMap transformConfigMap = transforms.getMap(i);
|
||||
String property = transformConfigMap.getString("property");
|
||||
if (transformConfigMap.hasKey("nodeID")) {
|
||||
AnimatedTransformConfig transformConfig = new AnimatedTransformConfig();
|
||||
transformConfig.propertyName = property;
|
||||
transformConfig.nodeID = transformConfigMap.getInt("nodeID");
|
||||
configs.add(transformConfig);
|
||||
} else {
|
||||
StaticTransformConfig transformConfig = new StaticTransformConfig();
|
||||
transformConfig.propertyName = property;
|
||||
ReadableType type = transformConfigMap.getType("value");
|
||||
if(type == ReadableType.String) {
|
||||
transformConfig.value = transformConfigMap.getString("value");
|
||||
} else if(type == ReadableType.Array) {
|
||||
transformConfig.value = transformConfigMap.getArray("value");
|
||||
} else {
|
||||
transformConfig.value = transformConfigMap.getDouble("value");
|
||||
}
|
||||
configs.add(transformConfig);
|
||||
}
|
||||
}
|
||||
return configs;
|
||||
}
|
||||
|
||||
private List<TransformConfig> mTransforms;
|
||||
|
||||
public TransformNode(int nodeID, ReadableMap config, NodesManager nodesManager) {
|
||||
super(nodeID, config, nodesManager);
|
||||
mTransforms = processTransforms(config.getArray("transform"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected WritableArray evaluate() {
|
||||
List<JavaOnlyMap> transforms = new ArrayList<>(mTransforms.size());
|
||||
|
||||
for (TransformConfig transformConfig : mTransforms) {
|
||||
transforms.add(
|
||||
JavaOnlyMap.of(transformConfig.propertyName, transformConfig.getValue(mNodesManager)));
|
||||
}
|
||||
|
||||
return JavaOnlyArray.from(transforms);
|
||||
}
|
||||
}
|
40
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/ValueNode.java
generated
vendored
Normal file
40
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/nodes/ValueNode.java
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
package com.swmansion.reanimated.nodes;
|
||||
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.ReadableType;
|
||||
import com.swmansion.reanimated.NodesManager;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class ValueNode extends Node {
|
||||
|
||||
private Object mValue;
|
||||
|
||||
public ValueNode(int nodeID, @Nullable ReadableMap config, NodesManager nodesManager) {
|
||||
super(nodeID, config, nodesManager);
|
||||
if (config == null || !config.hasKey("value")) {
|
||||
mValue = null;
|
||||
return;
|
||||
}
|
||||
ReadableType type = config.getType("value");
|
||||
if (type == ReadableType.String) {
|
||||
mValue = config.getString("value");
|
||||
} else if (type == ReadableType.Number) {
|
||||
mValue = config.getDouble("value");
|
||||
} else if (type == ReadableType.Null) {
|
||||
mValue = null;
|
||||
} else {
|
||||
throw new IllegalStateException("Not supported value type. Must be boolean, number or string");
|
||||
}
|
||||
}
|
||||
|
||||
public void setValue(Object value) {
|
||||
mValue = value;
|
||||
forceUpdateMemoizedValue(mValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object evaluate() {
|
||||
return mValue;
|
||||
}
|
||||
}
|
82
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/transitions/ChangeTransition.java
generated
vendored
Normal file
82
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/transitions/ChangeTransition.java
generated
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
package com.swmansion.reanimated.transitions;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.TimeInterpolator;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.transition.ChangeBounds;
|
||||
import androidx.transition.ChangeTransform;
|
||||
import androidx.transition.Transition;
|
||||
import androidx.transition.TransitionPropagation;
|
||||
import androidx.transition.TransitionValues;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
final class ChangeTransition extends Transition {
|
||||
|
||||
private final ChangeTransform mChangeTransform;
|
||||
private final ChangeBounds mChangeBounds;
|
||||
|
||||
public ChangeTransition() {
|
||||
mChangeTransform = new ChangeTransform();
|
||||
mChangeBounds = new ChangeBounds();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void captureStartValues(TransitionValues transitionValues) {
|
||||
mChangeTransform.captureStartValues(transitionValues);
|
||||
mChangeBounds.captureStartValues(transitionValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void captureEndValues(TransitionValues transitionValues) {
|
||||
mChangeTransform.captureEndValues(transitionValues);
|
||||
mChangeBounds.captureEndValues(transitionValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transition setDuration(long duration) {
|
||||
mChangeTransform.setDuration(duration);
|
||||
mChangeBounds.setDuration(duration);
|
||||
return super.setDuration(duration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transition setStartDelay(long startDelay) {
|
||||
mChangeTransform.setStartDelay(startDelay);
|
||||
mChangeBounds.setStartDelay(startDelay);
|
||||
return super.setStartDelay(startDelay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transition setInterpolator(@Nullable TimeInterpolator interpolator) {
|
||||
mChangeTransform.setInterpolator(interpolator);
|
||||
mChangeBounds.setInterpolator(interpolator);
|
||||
return super.setInterpolator(interpolator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPropagation(@Nullable TransitionPropagation transitionPropagation) {
|
||||
mChangeTransform.setPropagation(transitionPropagation);
|
||||
mChangeBounds.setPropagation(transitionPropagation);
|
||||
super.setPropagation(transitionPropagation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, TransitionValues endValues) {
|
||||
mChangeTransform.setReparent(false);
|
||||
Animator changeTransformAnimator = mChangeTransform.createAnimator(sceneRoot, startValues, endValues);
|
||||
Animator changeBoundsAnimator = mChangeBounds.createAnimator(sceneRoot, startValues, endValues);
|
||||
|
||||
if (changeTransformAnimator == null) {
|
||||
return changeBoundsAnimator;
|
||||
}
|
||||
|
||||
if (changeBoundsAnimator == null) {
|
||||
return changeTransformAnimator;
|
||||
}
|
||||
|
||||
AnimatorSet animatorSet = new AnimatorSet();
|
||||
animatorSet.playTogether(changeTransformAnimator, changeBoundsAnimator);
|
||||
return animatorSet;
|
||||
}
|
||||
}
|
22
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/transitions/SaneSidePropagation.java
generated
vendored
Normal file
22
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/transitions/SaneSidePropagation.java
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
package com.swmansion.reanimated.transitions;
|
||||
|
||||
import androidx.transition.SidePropagation;
|
||||
import androidx.transition.Transition;
|
||||
import androidx.transition.TransitionValues;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
public class SaneSidePropagation extends SidePropagation {
|
||||
|
||||
@Override
|
||||
public long getStartDelay(ViewGroup sceneRoot, Transition transition, TransitionValues startValues, TransitionValues endValues) {
|
||||
long delay = super.getStartDelay(sceneRoot, transition, startValues, endValues);
|
||||
if (delay != 0) {
|
||||
if (endValues == null || getViewVisibility(startValues) == View.VISIBLE) {
|
||||
return -delay;
|
||||
}
|
||||
}
|
||||
return delay;
|
||||
}
|
||||
|
||||
}
|
83
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/transitions/Scale.java
generated
vendored
Normal file
83
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/transitions/Scale.java
generated
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
package com.swmansion.reanimated.transitions;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import androidx.transition.Transition;
|
||||
import androidx.transition.TransitionListenerAdapter;
|
||||
import androidx.transition.TransitionValues;
|
||||
import androidx.transition.Visibility;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
public class Scale extends Visibility {
|
||||
|
||||
static final String PROPNAME_SCALE_X = "scale:scaleX";
|
||||
static final String PROPNAME_SCALE_Y = "scale:scaleY";
|
||||
|
||||
@Override
|
||||
public void captureStartValues(TransitionValues transitionValues) {
|
||||
super.captureStartValues(transitionValues);
|
||||
transitionValues.values.put(PROPNAME_SCALE_X, transitionValues.view.getScaleX());
|
||||
transitionValues.values.put(PROPNAME_SCALE_Y, transitionValues.view.getScaleY());
|
||||
}
|
||||
|
||||
public Scale setDisappearedScale(float disappearedScale) {
|
||||
if (disappearedScale < 0f) {
|
||||
throw new IllegalArgumentException("disappearedScale cannot be negative!");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
private Animator createAnimation(final View view, float startScale, float endScale, TransitionValues values) {
|
||||
final float initialScaleX = view.getScaleX();
|
||||
final float initialScaleY = view.getScaleY();
|
||||
float startScaleX = initialScaleX * startScale;
|
||||
float endScaleX = initialScaleX * endScale;
|
||||
float startScaleY = initialScaleY * startScale;
|
||||
float endScaleY = initialScaleY * endScale;
|
||||
|
||||
if (values != null) {
|
||||
Float savedScaleX = (Float) values.values.get(PROPNAME_SCALE_X);
|
||||
Float savedScaleY = (Float) values.values.get(PROPNAME_SCALE_Y);
|
||||
// if saved value is not equal initial value it means that previous
|
||||
// transition was interrupted and in the onTransitionEnd
|
||||
// we've applied endScale. we should apply proper value to
|
||||
// continue animation from the interrupted state
|
||||
if (savedScaleX != null && savedScaleX != initialScaleX) {
|
||||
startScaleX = savedScaleX;
|
||||
}
|
||||
if (savedScaleY != null && savedScaleY != initialScaleY) {
|
||||
startScaleY = savedScaleY;
|
||||
}
|
||||
}
|
||||
|
||||
view.setScaleX(startScaleX);
|
||||
view.setScaleY(startScaleY);
|
||||
|
||||
AnimatorSet animator = new AnimatorSet();
|
||||
animator.playTogether(
|
||||
ObjectAnimator.ofFloat(view, View.SCALE_X, startScaleX, endScaleX),
|
||||
ObjectAnimator.ofFloat(view, View.SCALE_Y, startScaleY, endScaleY));
|
||||
addListener(new TransitionListenerAdapter() {
|
||||
@Override
|
||||
public void onTransitionEnd(Transition transition) {
|
||||
view.setScaleX(initialScaleX);
|
||||
view.setScaleY(initialScaleY);
|
||||
transition.removeListener(this);
|
||||
}
|
||||
});
|
||||
return animator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues, TransitionValues endValues) {
|
||||
return createAnimation(view, 0f, 1f, startValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues, TransitionValues endValues) {
|
||||
return createAnimation(view, 1f, 0f, startValues);
|
||||
}
|
||||
}
|
45
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/transitions/TransitionModule.java
generated
vendored
Normal file
45
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/transitions/TransitionModule.java
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
package com.swmansion.reanimated.transitions;
|
||||
|
||||
import androidx.transition.TransitionManager;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.uimanager.IllegalViewOperationException;
|
||||
import com.facebook.react.uimanager.NativeViewHierarchyManager;
|
||||
import com.facebook.react.uimanager.UIBlock;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
|
||||
public class TransitionModule {
|
||||
|
||||
private final UIManagerModule mUIManager;
|
||||
|
||||
public TransitionModule(UIManagerModule uiManager) {
|
||||
mUIManager = uiManager;
|
||||
}
|
||||
|
||||
public void animateNextTransition(final int rootTag, final ReadableMap config) {
|
||||
mUIManager.prependUIBlock(new UIBlock() {
|
||||
@Override
|
||||
public void execute(NativeViewHierarchyManager nativeViewHierarchyManager) {
|
||||
try {
|
||||
View rootView = nativeViewHierarchyManager.resolveView(rootTag);
|
||||
if (rootView instanceof ViewGroup) {
|
||||
ReadableArray transitions = config.getArray("transitions");
|
||||
for (int i = 0, size = transitions.size(); i < size; i++) {
|
||||
TransitionManager.beginDelayedTransition(
|
||||
(ViewGroup) rootView,
|
||||
TransitionUtils.inflate(transitions.getMap(i)));
|
||||
}
|
||||
}
|
||||
} catch (IllegalViewOperationException ex) {
|
||||
// ignore, view might have not been registered yet
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
162
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/transitions/TransitionUtils.java
generated
vendored
Normal file
162
node_modules/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/transitions/TransitionUtils.java
generated
vendored
Normal file
@ -0,0 +1,162 @@
|
||||
package com.swmansion.reanimated.transitions;
|
||||
|
||||
import androidx.transition.ChangeBounds;
|
||||
import androidx.transition.ChangeTransform;
|
||||
import androidx.transition.Fade;
|
||||
import androidx.transition.SidePropagation;
|
||||
import androidx.transition.Slide;
|
||||
import androidx.transition.Transition;
|
||||
import androidx.transition.TransitionSet;
|
||||
import androidx.transition.Visibility;
|
||||
import android.view.Gravity;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.view.animation.AccelerateInterpolator;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
|
||||
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
class TransitionUtils {
|
||||
|
||||
static @Nullable Transition inflate(ReadableMap config) {
|
||||
String type = config.getString("type");
|
||||
if ("group".equals(type)) {
|
||||
return inflateGroup(config);
|
||||
} else if ("in".equals(type)) {
|
||||
return inflateIn(config);
|
||||
} else if ("out".equals(type)) {
|
||||
return inflateOut(config);
|
||||
} else if ("change".equals(type)) {
|
||||
return inflateChange(config);
|
||||
}
|
||||
throw new JSApplicationIllegalArgumentException("Unrecognized transition type " + type);
|
||||
}
|
||||
|
||||
private static @Nullable Transition inflateGroup(ReadableMap config) {
|
||||
TransitionSet set = new TransitionSet();
|
||||
if (config.hasKey("sequence") && config.getBoolean("sequence")) {
|
||||
set.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
|
||||
} else {
|
||||
set.setOrdering(TransitionSet.ORDERING_TOGETHER);
|
||||
}
|
||||
ReadableArray transitions = config.getArray("transitions");
|
||||
for (int i = 0, size = transitions.size(); i < size; i++) {
|
||||
Transition next = inflate(transitions.getMap(i));
|
||||
if (next != null) {
|
||||
set.addTransition(next);
|
||||
}
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
static Visibility createVisibilityTransition(String type) {
|
||||
if (type == null || "none".equals(type)) {
|
||||
return null;
|
||||
} else if ("fade".equals(type)) {
|
||||
return new Fade(Fade.IN | Fade.OUT);
|
||||
} else if ("scale".equals(type)) {
|
||||
return new Scale();
|
||||
} else if ("slide-top".equals(type)) {
|
||||
return new Slide(Gravity.TOP);
|
||||
} else if ("slide-bottom".equals(type)) {
|
||||
return new Slide(Gravity.BOTTOM);
|
||||
} else if ("slide-right".equals(type)) {
|
||||
return new Slide(Gravity.RIGHT);
|
||||
} else if ("slide-left".equals(type)) {
|
||||
return new Slide(Gravity.LEFT);
|
||||
}
|
||||
throw new JSApplicationIllegalArgumentException("Invalid transition type " + type);
|
||||
}
|
||||
|
||||
private static Transition inflateIn(ReadableMap config) {
|
||||
Visibility transition = createTransition(config.getString("animation"));
|
||||
if (transition == null) {
|
||||
return null;
|
||||
}
|
||||
transition.setMode(Visibility.MODE_IN);
|
||||
configureTransition(transition, config);
|
||||
return transition;
|
||||
}
|
||||
|
||||
private static Transition inflateOut(ReadableMap config) {
|
||||
Visibility transition = createTransition(config.getString("animation"));
|
||||
if (transition == null) {
|
||||
return null;
|
||||
}
|
||||
transition.setMode(Visibility.MODE_OUT);
|
||||
configureTransition(transition, config);
|
||||
return transition;
|
||||
}
|
||||
|
||||
private static Transition inflateChange(ReadableMap config) {
|
||||
ChangeBounds changeBounds = new ChangeBounds();
|
||||
ChangeTransform changeTransform = new ChangeTransform();
|
||||
configureTransition(changeBounds, config);
|
||||
configureTransition(changeTransform, config);
|
||||
return new TransitionSet().addTransition(changeBounds).addTransition(changeTransform);
|
||||
}
|
||||
|
||||
private static Visibility createTransition(String type) {
|
||||
if (type == null || "none".equals(type)) {
|
||||
return null;
|
||||
} else if ("fade".equals(type)) {
|
||||
return new Fade(Fade.IN | Fade.OUT);
|
||||
} else if ("scale".equals(type)) {
|
||||
return new Scale();
|
||||
} else if ("slide-top".equals(type)) {
|
||||
return new Slide(Gravity.TOP);
|
||||
} else if ("slide-bottom".equals(type)) {
|
||||
return new Slide(Gravity.BOTTOM);
|
||||
} else if ("slide-right".equals(type)) {
|
||||
return new Slide(Gravity.RIGHT);
|
||||
} else if ("slide-left".equals(type)) {
|
||||
return new Slide(Gravity.LEFT);
|
||||
}
|
||||
throw new JSApplicationIllegalArgumentException("Invalid transition type " + type);
|
||||
}
|
||||
|
||||
private static void configureTransition(Transition transition, ReadableMap params) {
|
||||
if (params.hasKey("durationMs")) {
|
||||
int durationMs = params.getInt("durationMs");
|
||||
transition.setDuration(durationMs);
|
||||
}
|
||||
if (params.hasKey("interpolation")) {
|
||||
String interpolation = params.getString("interpolation");
|
||||
if (interpolation.equals("easeIn")) {
|
||||
transition.setInterpolator(new AccelerateInterpolator());
|
||||
} else if (interpolation.equals("easeOut")) {
|
||||
transition.setInterpolator(new DecelerateInterpolator());
|
||||
} else if (interpolation.equals("easeInOut")) {
|
||||
transition.setInterpolator(new AccelerateDecelerateInterpolator());
|
||||
} else if (interpolation.equals("linear")) {
|
||||
transition.setInterpolator(new LinearInterpolator());
|
||||
} else {
|
||||
throw new JSApplicationIllegalArgumentException("Invalid interpolation type " + interpolation);
|
||||
}
|
||||
}
|
||||
if (params.hasKey("propagation")) {
|
||||
String propagation = params.getString("propagation");
|
||||
SidePropagation sidePropagation = new SaneSidePropagation();
|
||||
if ("top".equals(propagation)) {
|
||||
sidePropagation.setSide(Gravity.BOTTOM);
|
||||
} else if ("bottom".equals(propagation)) {
|
||||
sidePropagation.setSide(Gravity.TOP);
|
||||
} else if ("left".equals(propagation)) {
|
||||
sidePropagation.setSide(Gravity.RIGHT);
|
||||
} else if ("right".equals(propagation)) {
|
||||
sidePropagation.setSide(Gravity.LEFT);
|
||||
}
|
||||
transition.setPropagation(sidePropagation);
|
||||
} else {
|
||||
transition.setPropagation(null);
|
||||
}
|
||||
if (params.hasKey("delayMs")) {
|
||||
int delayMs = params.getInt("delayMs");
|
||||
transition.setStartDelay(delayMs);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user