This repository has been archived by the owner on Aug 6, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 16
/
RNMEvaluator.java
178 lines (151 loc) · 6.42 KB
/
RNMEvaluator.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/**
* RNMEvaluator.java
* react-native-eval
*
* Created by Andy Prock on 9/28/15.
*/
package com.evaluator.react;
import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.annotation.Nullable;
/**
* The NativeModule.
*/
public final class RNMEvaluator extends ReactContextBaseJavaModule {
private static final String TAG = "RNMEvaluator";
public static final String EXTRA_STRING = "com.evaluator.extra.STRING";
public static final String EXTRA_ARRAY = "com.evaluator.extra.ARRAY";
public static final String EXTRA_MAP = "com.evaluator.extra.MAP";
public static final String EXTRA_INT = "com.evaluator.extra.INT";
public static final String EXTRA_DOUBLE = "com.evaluator.extra.DOUBLE";
public static final String EXTRA_BOOL = "com.evaluator.extra.BOOL";
private static final String VALUE_KEY = "_value";
private static Map callbacks = new HashMap();
private boolean mShuttingDown = false;
public RNMEvaluator(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return TAG;
}
@Override
public void initialize() {
mShuttingDown = false;
}
@Override
public void onCatalystInstanceDestroy() {
mShuttingDown = true;
callbacks.clear();
}
/**
* This broadcasts the given event via the LocalBroadcastManager
*
* @param event the name of the event to be broadcast.
* @param value a {@link ReadableMap} containing the actual data to be
* broadcast. The data is wrapped in the VALUE_KEY key of this map, and
* is converted to a standard Java object or primitive, and put into the
* Intent.
*/
@ReactMethod
public void emit(final String event, final ReadableMap value) {
Intent intent = new Intent(event);
if (value != null && value.hasKey(VALUE_KEY)); {
Object data = ConversionUtil.toObject(value, VALUE_KEY);
if (data instanceof HashMap) {
intent.putExtra(EXTRA_MAP, (HashMap) data);
} else if (data instanceof ArrayList) {
intent.putExtra(EXTRA_ARRAY, (ArrayList) data);
} else if (data instanceof String) {
intent.putExtra(EXTRA_STRING, (String) data);
} else if (data instanceof Integer) {
intent.putExtra(EXTRA_INT, (Integer) data);
} else if (data instanceof Double) {
intent.putExtra(EXTRA_DOUBLE, (Double) data);
} else if (data instanceof Boolean) {
intent.putExtra(EXTRA_BOOL, (Boolean) data);
} else {
throw new IllegalArgumentException("Could not convert object with type: " + data.getClass().getCanonicalName() + ".");
}
}
LocalBroadcastManager.getInstance(getReactApplicationContext()).sendBroadcast(intent);
}
/**
* This calls the completion callback for the function that was invoked.
*
* @param callId the String identifying the call.
* @param error a String representing the possible error.
* @param value a {@link ReadableMap} containing the actual data to be
* returned. The data is wrapped in the VALUE_KEY key of this map, and
* is converted to a standard Java object or primitive, and put into the
* Intent.
*/
@ReactMethod
public void functionCallCompleted(final String callId, final String error, final ReadableMap returnValue) {
if (!callbacks.containsKey(callId)) {
return;
}
EvaluatorCallback cb = (EvaluatorCallback) callbacks.get(callId);
cb.invoke(error, returnValue.hasKey(VALUE_KEY) ? ConversionUtil.toObject(returnValue, VALUE_KEY) : null);
callbacks.remove(callId);
}
/**
* Invokes a javascript function via RNMEvaluator.callSyncFunction (blocking)
*/
public static void callSyncFunction(ReactContext context, String name, Object[] args, EvaluatorCallback cb) {
RNMEvaluator.callFunction(context, name, args, cb, "RNMEvaluator.callSyncFunction");
}
/**
* Invokes a javascript function via RNMEvaluator.callAsyncFunction (non-blocking)
*/
public static void callAsyncFunction(ReactContext context, String name, Object[] args, EvaluatorCallback cb) {
RNMEvaluator.callFunction(context, name, args, cb, "RNMEvaluator.callAsyncFunction");
}
/**
* Marshalls a function call to the javascript layer, via our NativeModule.
*
* @param context The context needed to execute this in.
* @param name The function to execute. e.g. "Math.Pow"
* @param args The arguments to pass to the function, or null.
* @param cb The completion callback for the result, or null.
* @param event The name of the event that our NativeModule is listening for.
*/
private static void callFunction(ReactContext context, String name, @Nullable Object[] args, @Nullable EvaluatorCallback cb, String event) {
String callId = UUID.randomUUID().toString();
if (null != cb) {
callbacks.put(callId, cb);
}
WritableArray arguments = args != null ? Arguments.fromJavaArgs(args) : Arguments.createArray();
if (arguments.size() == 0) {
arguments.pushNull();
}
WritableMap eventParams = Arguments.createMap();
eventParams.putString("name", name);
eventParams.putArray("args", arguments);
eventParams.putString("callId", callId);
// TODO: move to AppEventEmitter once App events are supported on android.
context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(event, eventParams);
}
/**
* Callback interface.
*/
public interface EvaluatorCallback {
void invoke(String error, Object returnValue);
}
}