Search Unity

Question async/await with jslib plugin?

Discussion in 'Web' started by Marks4, Apr 12, 2022.

  1. Marks4

    Marks4

    Joined:
    Feb 25, 2018
    Posts:
    542
    I have a free plugin that you can check https://assetstore.unity.com/packages/tools/camera/fullscreenwebgl-180047 . Check out the FullscreenWebGLExample.cs, the FullscreenWebGL.requestFullscreen method. It uses a callback. How would I be able to change the code to use async/await? I know it's possible because API for Firebase bindings for webgl does this, but the source code isn't open and the author won't reply on this matter. Does anybody know how I could do this? Thank you for your time.

    @brendanduncan_u3d @De-Panther @GroovyKoala
     
  2. gtk2k

    gtk2k

    Joined:
    Aug 13, 2014
    Posts:
    287
    Async / await in WebGL Yes it still doesn't work.
    If you still want to use async / await, you can now use async / await with an UniTask.
     
  3. Marks4

    Marks4

    Joined:
    Feb 25, 2018
    Posts:
    542
    I want to know how though. I can use dynCall to invoke a callback, but how do I couple this with async/await? Essentially, I'd like to await the dynCall instead of passing a callback as argument to a function. Or somehow get the function that is used by the user to use async/await, while the internal function still uses the callback method.
     
    Last edited: Apr 12, 2022
  4. gtk2k

    gtk2k

    Joined:
    Aug 13, 2014
    Posts:
    287
    sample code
    Code (CSharp):
    1. using Cysharp.Threading.Tasks;
    2.  
    3. [DllImport("__Internal")]
    4. private static extern void testFuncAsync(Action<int> cb);
    5.  
    6. private static UniTaskCompletionSource<int> utcs;
    7.  
    8. [MonoPInvokeCallback(typeof(Action<int>))]
    9. private static void testFuncCB(int val)
    10. {
    11.     utcs.TrySetResult(val);  
    12. }
    13.  
    14. public static UniTask<int> TestFuncCallAsync()
    15. {
    16.     utcs = new UniTaskCompletionSource<int>();
    17.     testFuncAsync(testFuncCB);
    18.     return utcs.Task;
    19. }
    20.  
    21. private async UniTask<int> Call_TestFuncCallAsync()
    22. {
    23.     var ret = await TestFuncCallAsync();
    24.     Debug.Log($"testFuncCallAsync() Result:{ret}");
    25.     return ret;
    26. }

    Code (JavaScript):
    1. mergeInto(LibraryManager.library, {
    2.     testFuncAsync: function(cb){
    3.         setTimeout(function() {
    4.             dynCall_vi(cb, 123);
    5.         }, 1000);
    6.     }
    7. });
    8.  
     
  5. Marks4

    Marks4

    Joined:
    Feb 25, 2018
    Posts:
    542
    Awesome thank you!
     
  6. Marks4

    Marks4

    Joined:
    Feb 25, 2018
    Posts:
    542
    hey @gtk2k do you know how to use exceptions with this? I am trying but I keep getting "Uncaught RuntimeError: unreachable".

    I have something like this, using your code

    Code (CSharp):
    1. [MonoPInvokeCallback(typeof(Action<int>))]
    2. private static void testFuncCB(int val)
    3. {
    4.     if (val == 0)
    5.          utcs.TrySetResult(val);
    6.     else
    7.         utcs.TrySetException(new Exception("not valid"));
    8. }
    9. private async UniTask<int> Call_TestFuncCallAsync()
    10. {
    11.     try {
    12.         var ret = await TestFuncCallAsync();
    13.         Debug.Log($"testFuncCallAsync() Result:{ret}");
    14.         return ret;
    15.     } catch(Exception e) {
    16.         Debug.Log("ERROR");//this never runs
    17.         Debug.Log(e.Message);
    18.     }
    19. }
    20.  
    The exception I set with TrySetException doesn't work, I get a runtimeerror:unreachable and the exception I set is never caught. I am trying and trying but can't get this to work. Must be something silly.

    it only works when it runs the TrySetResult code, but explodes if it runs the TrySetException branch.
     
  7. Marks4

    Marks4

    Joined:
    Feb 25, 2018
    Posts:
    542
    Oh I needed to enable Exceptions
    upload_2022-4-16_15-2-39.png

    that's all
     
  8. Marks4

    Marks4

    Joined:
    Feb 25, 2018
    Posts:
    542
    @gtk2k What's awesome is that all of this works with the regular System.Threading.Tasks library, no need to import UniTask. Apparently tasks work on webgl as long as everything is on the same thread(see stonstad's first comment on page 2). According to my tests using then/catch inside jslibs don't break this restriction. UniTask is unnecessary, using regular TaskCompletionSource works as well :D