mucksponge / unityasync Goto Github PK
View Code? Open in Web Editor NEWAn allocation-free, high performance coroutine framework for Unity built around the async API
License: Apache License 2.0
An allocation-free, high performance coroutine framework for Unity built around the async API
License: Apache License 2.0
If you run await Await.NextUpdate()
on Android, it will fail with Unable to create field getter for Object.m_CachedPtr; internal implementation may have changed.
. The stacktrace appears to be corrupted.
In ContinuationProcessor, you allocate two arrays of size 500,000. This uses about 30 MB of memory for each type of IAwaitInstruction used (WaitForFrames, WaitForSeconds, etc), regardless of how few Continuations you actually use.
You could instead start the queue size small (like 16) and dynamically resize the arrays. For example:
public void Add(T cont)
{
if (futureCount == futureQueue.Length)
{
int newLength = futureQueue.Length * 3 / 2;
Array.Resize(ref futureQueue, newLength);
Array.Resize(ref currentQueue, newLength);
}
// rest of method...
}
The code heavily expects static
s to be cleared between runs, which breaks when you use the faster Play Mode in newer versions of Unity. I have tried to fix this myself but none of my attempts worked (hence the issue instead of a PR, sorry).
I was testing with both Domain and Scene reload disabled.
Reference: https://docs.unity3d.com/Manual/ConfigurableEnterPlayMode.html
I tried to import, but I cannot because the editor only supports C#6 compatible features. UnityAsync uses features above....
Love your library!
Say you have some code like this:
async void Start()
{
await Await.Seconds(5).ConfigureAwait(this);
transform.position = new Vector3(1, 2, 3); // will crash if object was destroyed
}
Currently, if the GameObject or Component is destroyed, the continuation runs immediately, which would cause a crash. I think it would be more intuitive if the continuation were cancelled instead. This is probably what the user wants most of the time and is consistent with how coroutines work.
when running the following code
List<DisplayInfo> displays = new List<DisplayInfo>();
Screen.GetDisplayLayout(displays);
DisplayInfo display = displays[1];
await Screen.MoveMainWindowTo(display, new Vector2Int(display.width / 2, display.height / 2));
Debug.Log("Finished");
The operation completes however the await call never continues on to call the Debug.Log. I have no clue why it is getting stuck but this may be a problem with MoveMainWindow method itself, I just wanted to share a bug I encountered.
I didn't find any description on how to actually use this library within a Unity project. It's not in the Asset Store, right? Is the idea to just copy-paste the contents of this repository into the project?
I believe this is because of the commit here:
e01e2dc#diff-86c1eb8e1ae625825c97d335eaea9712
if(!Application.isEditor) // DontDestroyOnLoad can not be called in editor mode DontDestroyOnLoad(Instance);
When loading a new scene, the AsyncManager instance is destroyed preventing any Await calls to complete.
DontDestroyOnLoad does work in Editor. So not following the reasoning behind the change.
When calling await Await.FixedUpdates(1) inside a while loop. The iterator will not continue until the fixedCount reaches updateCount.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityAsync;
public class TestAsync : MonoBehaviour {
#region Private Methods
public void DoRoutineAtSomeTime() {
DoRoutine();
}
private async void DoRoutine() {
while (isActiveAndEnabled) {
Debug.Log("Before " + Time.inFixedTimeStep);
await Await.FixedUpdates(1).ConfigureAwait(this);
//This will not occur until a long time later, depending on when "DoRoutine" was called
Debug.Log("After " + Time.inFixedTimeStep);
}
Debug.Log("Finished");
}
#endregion
}
This is because in the constructor of "WaitForFrames" the finishFrame is set to CurrentFrameCount + count
#if UNITY_EDITOR
using UnityEngine;
#endif
namespace UnityAsync
{
public struct WaitForFrames : IAwaitInstruction
{
readonly int finishFrame;
bool IAwaitInstruction.IsCompleted() => finishFrame <= AsyncManager.CurrentFrameCount;
/// <summary>
/// Waits for the specified number of frames to pass before continuing.
/// </summary>
public WaitForFrames(int count)
{
#if UNITY_EDITOR
if(count <= 0)
{
count = 1;
Debug.LogError($"{nameof(count)} should be greater than 0. This check will only appear in edit mode.");
}
#endif
finishFrame = AsyncManager.CurrentFrameCount + count;
}
}
}
So if you call Await.FixedUpdates(1) when not inside a FixedUpdate callback, the finishFrame is set to the AsyncManager.updateCount instead of AsyncManager.fixedCount
UnityAsync.WaitForSeconds is unusable currently. It never waits for even a frame.
IsCompleted() is never called. The code leading to IsCompleted() also isn't called.
This asset is currently unsuable, since it's not the only bug. Seems like it's sadly abandoned.
It seems that if you edit your code Unity clears your static
s, but the "Async Manager" GameObject survives until you leave Play Mode, which causes it to run into these null
s.
NullReferenceException: Object reference not set to an instance of an object
UnityAsync.AsyncManager.Update () (at Assets/Plugins/UnityAsync/Manager/AsyncManager.cs:110)
(as well as lines 120 and 130 for LateUpdate and FixedUpdate)
Hi, will it also work with UniTask implementation of lightweight Task ?
Specifically after this refactoring: 5430f35
Extensions
class is internal, when the library is referenced using asmdefs, Extensions
class is hidden. Which results in this error:
'WaitForFrames' does not contain a definition for 'GetAwaiter' and no accessible extension method 'GetAwaiter' accepting a first argument of type 'WaitForFrames' could be found (are you missing a using directive or an assembly reference?)
Solution is to Make Extensions
class public. This also means that other classes need to be made public as well:
SynchronizationContextAwaiter
IEnumeratorAwaiter
YieldInstructionAwaiter
Hi, the readme references Await.UnitySyncContext
but nothing seems to resemble this API on master. Was there a rename?
I assume that System.Linq.Expressions cannot be used on Android. But this is the error I get:
Unable to create field getter for Object.m_CachedPtr; internal implementation may have changed.
Changing the implementation of IsAlive to:
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsAlive(this Object o) => o != null;
Does fix the issue. Not sure why you need to use m_CachedPtr
?
Could be related: https://forum.unity.com/threads/are-c-expression-trees-or-ilgenerator-allowed-on-ios.489498/
Thanks for open sourcing this project!
I am using the latest release (v0.1.1), and I use methods such as await Await.UnitySyncContext();
and await Await.BackgroundSyncContext();
in the production code.
However, when this code is under testing (NUnit tests run with the Unity test runner in Edit mode), these calls fail because AsyncManager.Initialize()
has not been called. This is because [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
does not do anything when running the tests.
It would be nice to have a fix for this. I suggest creating a mechanism to be able to do this initialization from code (so that it can be called in the tests setup method). I will create a pull request with my suggestion for a fix.
I'm trying to load an scene aynchronous with await instead of using yield statement of coroutines. Is there any way to do it with this library?
It looks like this project is more up to date and perhaps better maintained than this Unity3dAsyncAwaitUtil project and since I'm currently using Unity3dAsyncAwaitUtil I'd be interested to learn if there are some specific technical pros/cons for each one to help decide whether to use this project instead.
It would be good if the documentation could highlight if there are any key technical differences between this and any other alternatives.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.