Selaa lähdekoodia

[RN] Reduce maintenance

JitsiMeetViewListener currently has methods of one and the same pattern
so adding new methods i.e. events i.e. redux action types is a question
of repetition in the Java source code. Speed up the support of new
events by trying to deal with them in a generic way.

The same goes for JitsiMeetViewDelegate.
master
Lyubo Marinov 8 vuotta sitten
vanhempi
commit
1d8ee9d32f

+ 63
- 20
android/sdk/src/main/java/org/jitsi/meet/sdk/ExternalAPIModule.java Näytä tiedosto

@@ -25,7 +25,12 @@ import com.facebook.react.bridge.ReadableMapKeySetIterator;
25 25
 import org.jitsi.meet.sdk.JitsiMeetView;
26 26
 import org.jitsi.meet.sdk.JitsiMeetViewListener;
27 27
 
28
+import java.lang.reflect.Method;
29
+import java.lang.reflect.Modifier;
28 30
 import java.util.HashMap;
31
+import java.util.Locale;
32
+import java.util.Map;
33
+import java.util.regex.Pattern;
29 34
 
30 35
 /**
31 36
  * Module implementing a simple API to enable a proximity sensor-controlled
@@ -35,10 +40,60 @@ import java.util.HashMap;
35 40
  */
36 41
 class ExternalAPIModule extends ReactContextBaseJavaModule {
37 42
     /**
38
-     * React Native module name.
43
+     * The {@code Method}s of {@code JitsiMeetViewListener} by event name i.e.
44
+     * redux action types.
45
+     */
46
+    private static final Map<String, Method> JITSI_MEET_VIEW_LISTENER_METHODS
47
+        = new HashMap<>();
48
+
49
+    /**
50
+     * The name of this module to be used in the React Native bridge.
39 51
      */
40 52
     private static final String MODULE_NAME = "ExternalAPI";
41 53
 
54
+    static {
55
+        // Figure out the mapping between the JitsiMeetViewListener methods
56
+        // and the events i.e. redux action types.
57
+        Pattern onPattern = Pattern.compile("^on[A-Z]+");
58
+        Pattern camelcasePattern = Pattern.compile("([a-z0-9]+)([A-Z0-9]+)");
59
+
60
+        for (Method method : JitsiMeetViewListener.class.getDeclaredMethods()) {
61
+            // * The method must be public (because it is declared by an
62
+            //   interface).
63
+            // * The method must be/return void.
64
+            if (!Modifier.isPublic(method.getModifiers())
65
+                    || !Void.TYPE.equals(method.getReturnType())) {
66
+                continue;
67
+            }
68
+
69
+            // * The method name must start with "on" followed by a
70
+            //   capital/uppercase letter (in agreement with the camelcase
71
+            //   coding style customary to Java in general and the projects of
72
+            //   the Jitsi community in particular).
73
+            String name = method.getName();
74
+
75
+            if (!onPattern.matcher(name).find()) {
76
+                continue;
77
+            }
78
+
79
+            // * The method must accept/have exactly 1 parameter of a type
80
+            //   assignable from HashMap.
81
+            Class<?>[] parameterTypes = method.getParameterTypes();
82
+
83
+            if (parameterTypes.length != 1
84
+                    || !parameterTypes[0].isAssignableFrom(HashMap.class)) {
85
+                continue;
86
+            }
87
+
88
+            // Convert the method name to an event name.
89
+            name
90
+                = camelcasePattern.matcher(name.substring(2))
91
+                    .replaceAll("$1_$2")
92
+                    .toUpperCase(Locale.ROOT);
93
+            JITSI_MEET_VIEW_LISTENER_METHODS.put(name, method);
94
+        }
95
+    }
96
+
42 97
     /**
43 98
      * Initializes a new module instance. There shall be a single instance of
44 99
      * this module throughout the lifetime of the application.
@@ -85,26 +140,14 @@ class ExternalAPIModule extends ReactContextBaseJavaModule {
85 140
             return;
86 141
         }
87 142
 
88
-        switch (name) {
89
-        case "CONFERENCE_FAILED":
90
-            listener.onConferenceFailed(toHashMap(data));
91
-            break;
92
-
93
-        case "CONFERENCE_JOINED":
94
-            listener.onConferenceJoined(toHashMap(data));
95
-            break;
96
-
97
-        case "CONFERENCE_LEFT":
98
-            listener.onConferenceLeft(toHashMap(data));
99
-            break;
100
-
101
-        case "CONFERENCE_WILL_JOIN":
102
-            listener.onConferenceWillJoin(toHashMap(data));
103
-            break;
143
+        Method method = JITSI_MEET_VIEW_LISTENER_METHODS.get(name);
104 144
 
105
-        case "CONFERENCE_WILL_LEAVE":
106
-            listener.onConferenceWillLeave(toHashMap(data));
107
-            break;
145
+        if (method != null) {
146
+            try {
147
+                method.invoke(listener, toHashMap(data));
148
+            } catch (ReflectiveOperationException roe) {
149
+                throw new RuntimeException(roe);
150
+            }
108 151
         }
109 152
     }
110 153
 

+ 25
- 18
ios/sdk/src/ExternalAPI.m Näytä tiedosto

@@ -52,26 +52,33 @@ RCT_EXPORT_METHOD(sendEvent:(NSString *)name
52 52
         return;
53 53
     }
54 54
 
55
-    if ([name isEqualToString:@"CONFERENCE_FAILED"]
56
-            && [delegate respondsToSelector:@selector(conferenceFailed:)]) {
57
-        [delegate conferenceFailed:data];
55
+    SEL sel = NSSelectorFromString([self methodNameFromEventName:name]);
58 56
 
59
-    } else if ([name isEqualToString:@"CONFERENCE_JOINED"]
60
-            && [delegate respondsToSelector:@selector(conferenceJoined:)]) {
61
-        [delegate conferenceJoined:data];
62
-
63
-    } else if ([name isEqualToString:@"CONFERENCE_LEFT"]
64
-            && [delegate respondsToSelector:@selector(conferenceLeft:)]) {
65
-        [delegate conferenceLeft:data];
66
-
67
-    } else if ([name isEqualToString:@"CONFERENCE_WILL_JOIN"]
68
-            && [delegate respondsToSelector:@selector(conferenceWillJoin:)]) {
69
-        [delegate conferenceWillJoin:data];
70
-
71
-    } else if ([name isEqualToString:@"CONFERENCE_WILL_LEAVE"]
72
-            && [delegate respondsToSelector:@selector(conferenceWillLeave:)]) {
73
-        [delegate conferenceWillLeave:data];
57
+    if (sel && [delegate respondsToSelector:sel]) {
58
+        [delegate performSelector:sel withObject:data];
74 59
     }
75 60
 }
76 61
 
62
+/**
63
+ * Converts a specific event name i.e. redux action type description to a
64
+ * method name.
65
+ *
66
+ * @param eventName The event name to convert to a method name.
67
+ * @return A method name constructed from the specified {@code eventName}.
68
+ */
69
+- (NSString *)methodNameFromEventName:(NSString *)eventName {
70
+   NSMutableString *methodName
71
+       = [NSMutableString stringWithCapacity:eventName.length];
72
+
73
+   for (NSString *c in [eventName componentsSeparatedByString:@"_"]) {
74
+       if (c.length) {
75
+           [methodName appendString:
76
+               methodName.length ? c.capitalizedString : c.lowercaseString];
77
+       }
78
+   }
79
+   [methodName appendString:@":"];
80
+
81
+   return methodName;
82
+}
83
+
77 84
 @end

Loading…
Peruuta
Tallenna