Skip to content
This repository was archived by the owner on Jun 19, 2024. It is now read-only.

Commit 25697c2

Browse files
authored
Merge pull request #21 from LabyMod/develop
Make Javascript context provider async
2 parents f182602 + 4a7f7f9 commit 25697c2

File tree

5 files changed

+33
-20
lines changed

5 files changed

+33
-20
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Moreover, the databind API is capable of translating Java objects directly to Ja
2727
calls directly from within your JavaScript code, making integration with the UI even easier.
2828

2929
# Licensing
30-
For Ultralight Java [GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html) is being used, however, Ultralight itself is
30+
For Ultralight Java [LGPLv3](https://www.gnu.org/licenses/lgpl-3.0.en.html) is being used, however, Ultralight itself is
3131
licensed under a custom proprietary license. See
3232
[Ultralight licensing](https://github.com/ultralight-ux/Ultralight/blob/master/README.md#licensing) for further
3333
information.

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.3.0
1+
0.3.1

ultralight-java-databind/src/main/java/com/labymedia/ultralight/context/ContextProvider.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,16 @@
2121

2222
import com.labymedia.ultralight.javascript.JavascriptContextLock;
2323

24+
import java.util.function.Consumer;
25+
2426
/**
2527
* Interface to be implemented by the user.
2628
*/
2729
public interface ContextProvider {
2830
/**
29-
* Retrieves the bound Javascript context with a lock. The lock will be unlocked by the consumer automatically
30-
* after it finished using it.
31+
* Executes the callback later on a thread which is synchronized with the Javascript engine.
3132
*
32-
* @return The bound Javascript context lock, or {@code null}, if the context is not available anymore
33+
* @param callback The callback to execute
3334
*/
34-
JavascriptContextLock getContext();
35+
void syncWithJavascript(Consumer<JavascriptContextLock> callback);
3536
}

ultralight-java-databind/src/main/java/com/labymedia/ultralight/utils/FunctionalInvocationHandler.java

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import java.lang.invoke.MethodHandles;
2929
import java.lang.reflect.InvocationHandler;
3030
import java.lang.reflect.Method;
31+
import java.util.concurrent.CountDownLatch;
32+
import java.util.concurrent.atomic.AtomicReference;
3133

3234
/**
3335
* Invocation handler for Javascript functions bound to functional interfaces.
@@ -90,16 +92,15 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
9092

9193
Class<?>[] methodParameterTypes = method.getParameterTypes();
9294

93-
synchronized (lock) {
94-
try (JavascriptContextLock lock = contextProvider.getContext()) {
95-
if (lock == null) {
96-
throw new IllegalStateException("Context required for callback does not exist anymore");
97-
}
95+
CountDownLatch awaiter = new CountDownLatch(1);
96+
AtomicReference<Object> out = new AtomicReference<>();
9897

99-
JavascriptContext context = lock.getContext();
98+
contextProvider.syncWithJavascript((contextLock) -> {
99+
synchronized (lock) {
100+
JavascriptContext context = contextLock.getContext();
100101

101102
// Revive the Javascript value, this will effectively invalidate the protected value
102-
JavascriptObject object = protectedValue.get().value.revive(lock).toObject();
103+
JavascriptObject object = protectedValue.get().value.revive(contextLock).toObject();
103104

104105
// Convert all Java arguments to Javascript values
105106
JavascriptValue[] arguments = new JavascriptValue[args.length];
@@ -112,9 +113,15 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
112113
protectedValue.get().value = object.protect();
113114

114115
JavascriptValue returnValue = object.callAsFunction(null, arguments);
115-
return databind.getConversionUtils().fromJavascript(returnValue, method.getReturnType());
116+
Object ret = databind.getConversionUtils().fromJavascript(returnValue, method.getReturnType());
117+
out.set(ret);
118+
awaiter.countDown();
116119
}
117-
}
120+
});
121+
122+
awaiter.await();
123+
124+
return out.get();
118125
}
119126

120127
/**
@@ -142,8 +149,8 @@ private ValueWrapper(ContextProvider contextProvider, JavascriptProtectedValue v
142149
* @param valueWrapper The wrapper to delete
143150
*/
144151
private static void delete(ValueWrapper valueWrapper) {
145-
try (JavascriptContextLock lock = valueWrapper.contextProvider.getContext()) {
146-
valueWrapper.value.revive(lock);
147-
}
152+
valueWrapper.contextProvider.syncWithJavascript((contextLock) -> {
153+
valueWrapper.value.revive(contextLock);
154+
});
148155
}
149156
}

ultralight-java-lwjgl3-opengl/src/test/java/com/labymedia/ultralight/lwjgl3/opengl/TestContextProvider.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@
2222
import com.labymedia.ultralight.UltralightView;
2323
import com.labymedia.ultralight.context.ContextProviderFactory;
2424
import com.labymedia.ultralight.context.ContextProvider;
25+
import com.labymedia.ultralight.javascript.JavascriptContext;
2526
import com.labymedia.ultralight.javascript.JavascriptContextLock;
2627
import com.labymedia.ultralight.javascript.JavascriptValue;
2728

29+
import java.util.function.Consumer;
30+
2831
public class TestContextProvider implements ContextProvider {
2932
private final UltralightView view;
3033

@@ -33,8 +36,10 @@ private TestContextProvider(UltralightView view) {
3336
}
3437

3538
@Override
36-
public JavascriptContextLock getContext() {
37-
return view.lockJavascriptContext();
39+
public void syncWithJavascript(Consumer<JavascriptContextLock> callback) {
40+
try(JavascriptContextLock lock = view.lockJavascriptContext()) {
41+
callback.accept(lock);
42+
}
3843
}
3944

4045
public static class Factory implements ContextProviderFactory {

0 commit comments

Comments
 (0)