Coroutines (and pooling) for v4, with improved tests

This PR supersedes #755 as it is based on the most recent v4 master source and implements all reviews and user request of the previous pull request.
In addition, pool-specific tests have been introduced and Scene.cs has a couple of missing "this" added to comply with the overall coding style.

Some more points:

A coroutine sample project would also be nice I believe, not just for the enduser but also for us to see how the API will look like and be used. Might inflate the current scope of the PR quite a bit though..
I see that CoroutineManager uses static state (private static QueuedPool<Coroutine> pool = new QueuedPool<Coroutine>();). Might be safer to switch to a instance based approach as that makes it more clear what the lifetime exactly is. This also makes it easier to test since you are not sharing data between tests anymore (especially when using a parallel test runner this is super annoying).

Condition / yield instruction classes have a rather unspecific name (to improve usability?),

Ideas?

A coroutine sample project would also be nice I believe, not just for the enduser but also for us to see how the API will look like and be used

Can be, I can provide one externally from the PR just to give you an idea and, in a second moment, extend it to a full Sample

Condition / yield instruction classes have a rather unspecific name (to improve usability?),

Ideas?

Not really, but we could move the entire coroutines feature to the Duality.Coroutines namespace, lifting a bit of naming pressure. It would still be just WaitFrames, but only when people plan to use a coroutine in that file - would make sense to me.
Alternatively, we could choose a really specific name like WaitFramesCoroutineCondition and provide a static(?) construction class to create them, like:
yield return CoroutineWait.ForFrames(15);
yield return CoroutineWait.ForSeconds(100.0f);
yield return CoroutineWait.Until(() => foo.Bar() == 17);

instead of
yield return new WaitFrames(15);
yield return new WaitTime(100.0f);
yield return new WaitCondition(() => foo.Bar() == 17);

Would not permit to add new conditions as first-class citizens though, since users cannot extend the static class.
We could also just do the namespace thing, just throwing ideas at the wall here.

Pooling data structures should be reviewed and considered separately and very thoroughly, since this is potentially common infrastructure.

Just looked into the pooling classes here, and it seems the only thing that is pooled is Coroutine itself, with IPoolable being completely unused. I'm honestly not sure that the internal pooling of Coroutine is enough to introduce this whole pooling utility class stuff, which also increases the scope of this PR a lot due to the added design work.
Can we just remove the pooling classes entirely and use a simple List<Coroutine> as an internal pool instead?

A coroutine sample project would also be nice I believe, not just for the enduser but also for us to see how the API will look like and be used

Can be, I can provide one externally from the PR just to give you an idea and, in a second moment, extend it to a full Sample

I'd keep a sample project in a separate PR to not inflate scope too much here, and also since it's not an integral part of the feature. The existing unit tests can also provide a basic example on how a coroutine is used.

Not really, but we could move the entire coroutines feature to the Duality.Coroutines namespace, lifting a bit of naming pressure. It would still be just WaitFrames, but only when people plan to use a coroutine in that file - would make sense to me.

well, they are already in a Duality.Utility.Coroutines namespace.. I don't see what would be different but if you prefer so, it's a quick fix 😄
Maybe instead of IWaitCondition it could be something like ICoroutineTask? would have an affinity with .net's Task system (Task.Delay => CoroutineTask.WaitFor, and so on?)

Alternatively, we could choose a really specific name like WaitFramesCoroutineCondition and provide a static(?) construction class to create them, like:
yield return CoroutineWait.ForFrames(15);
yield return CoroutineWait.ForSeconds(100.0f);
yield return CoroutineWait.Until(() => foo.Bar() == 17);

instead of
yield return new WaitFrames(15);
yield return new WaitTime(100.0f);
yield return new WaitCondition(() => foo.Bar() == 17);

Would not permit to add new conditions as first-class citizens though, since users cannot extend the static class.

And with the WaitCondition<T>.Reset method, you don't even need to instantiate a new condition each time you use the Coroutine.

Edit: Yeah, not sure I like this idea a lot the more I think about it. It's always nice when users can add their own stuff exactly like whatever was builtin, and a lot of design decisions in Duality point that way already. Nevermind then!

Just looked into the pooling classes here, and it seems the only thing that is pooled is Coroutine itself, with IPoolable being completely unused. I'm honestly not sure that the internal pooling of Coroutine is enough to introduce this whole pooling utility class stuff, which also increases the scope of this PR a lot due to the added design work.
Can we just remove the pooling classes entirely and use a simple List<Coroutine> as an internal pool instead?

I'd like to keep them together if possible; I know it goes a bit out of scope for this PR, but I think a pooling system could be useful as a general feature of the engine, and I would implement an internal one anyway, so why not just make it once properly, and available for general use? I don't see a rush to have all of this available for v4's first release, in case. It could very well be a 4.1.

I'd keep a sample project in a separate PR to not inflate scope too much here, and also since it's not an integral part of the feature. The existing unit tests can also provide a basic example on how a coroutine is used.

Hence the "external" part 😄 my idea is to provide a small demo project as a zip file, to try and test the usage of the various parts of the solution, separate from this PR. Only once everything is set, a proper Sample project would me made, eventually starting from the demo project.

I'd keep a sample project in a separate PR to not inflate scope too much here, and also since it's not an integral part of the feature. The existing unit tests can also provide a basic example on how a coroutine is used.

Hence the "external" part 😄 my idea is to provide a small demo project as a zip file, to try and test the usage of the various parts of the solution, separate from this PR. Only once everything is set, a proper Sample project would me made, eventually starting from the demo project.

Understood, and I actually meant to just agree with the separated approach here 👍

well, they are already in a Duality.Utility.Coroutines namespace.. I don't see what would be different but if you prefer so, it's a quick fix 😄

It says namespace Duality in all the coroutine files?

I'd like to keep them together if possible; I know it goes a bit out of scope for this PR, but I think a pooling system could be useful as a general feature of the engine, and I would implement an internal one anyway, so why not just make it once properly, and available for general use? I don't see a rush to have all of this available for v4's first release, in case. It could very well be a 4.1.

We can keep them together if you prefer, it's just that the margin for me approving general-purpose pooling utility is a lot thinner.
I'm a bit wary of pooling as a generalized technique (e.g. "just pool all the stuff, never worry about GC / memory again") that we might accidentally promote with generalized utility classes here, and it's also a very fundamental framework thing where I think we should be extra strict in design, implementation and review. Coroutines alone would probably a lot faster in a state where I'd give a thumbs up.

And with the WaitCondition.Reset method, you don't even need to instantiate a new condition each time you use the Coroutine.

Yeah, I was thinking something similar, that part would be neat. Then again, locking out or discouraging third-party conditions because they can't extend static API is a big downside and it would also mean introducing overhead for managing pooled instances.
There might be another way to avoid allocating new condition instances all the time: Make them (discriminated union style?) structs, e.g.
[StructLayout(LayoutKind.Explicit, Size=16)]
public struct WaitCondition
{
    [FieldOffset(0)] private WaitConditionType type;
    [FieldOffset(4)] private int intParam;
    [FieldOffset(4)] private float floatParam;
    [FieldOffset(4)] private Func<bool> conditionParam;

    // proper public API, constructors, etc.
}

// Coroutines would then return an IEnumerable<WaitCondition>

That way, we would still cover all cases, keep it allocation-free for "wait for time / frames" conditions and also remain extensible by letting users specify an arbitrary func to evaluate.

It says namespace Duality in all the coroutine files? 😄

DOH! Yeah, I followed the style of other Utility files, totally forgot about the actual namespace

I'm a bit wary of pooling as a generalized technique (e.g. "just pool all the stuff, never worry about GC / memory again") that we might accidentally promote with generalized utility classes here, and it's also a very fundamental framework thing where I think we should be extra strict in design, implementation and review. Coroutines alone would probably a lot faster in a state where I'd give a thumbs up.

IMHO it doesn't promote anything more than, let's say, ThreadPool does for managing your own Threads. It's a feature that is there, if you want to use it, go ahead (being mindful of what it means and what it does), if not, no one is pushing it; if you think it's overkill though, I can just remove it or change it as an internal class instead of a public one. OFC it must be tested, thought out if it's not already, etc.

Yeah, I was thinking something similar, that part would be neat. Then again, locking out or discouraging third-party conditions because they can't extend static API is a big downside and it would also mean introducing overhead for managing pooled instances.
There might be another way to avoid allocating new condition instances all the time: Make them (discriminated union style?) structs, e.g.
[StructLayout(LayoutKind.Explicit, Size=16)]
public struct WaitCondition
{
    [FieldOffset(0)] private WaitConditionType type;
    [FieldOffset(4)] private int intParam;
    [FieldOffset(4)] private float floatParam;
    [FieldOffset(4)] private Func<bool> conditionParam;

    // proper public API, constructors, etc.
}

// Coroutines would then return an IEnumerable<WaitCondition>

That way, we would still cover all cases, keep it allocation-free for "wait for time / frames" conditions and also remain extensible by letting users specify an arbitrary func to evaluate.

Ok, I got lost here 🤔 as things are now, everything is already extensible, either directly from IWaitCondition, WaitCondition, or WaitCondition<T>;
Plus, define "all cases".. this only covers ints and floats parameters, while now you could have any kind of object as T, and don't forget that yield return null is a valid construct, which would not work anymore with structs, unless we have a static ONE_FRAME value available.

Ok, I got lost here 🤔 as things are now, everything is already extensible, either directly from IWaitCondition, WaitCondition, or WaitCondition;

Yep, they are - I just meant that they would still be with the struct-based design. The goal here wouldn't be to make it extensible, but to avoid allocating a new object on every yield.

Plus, define "all cases".. this only covers ints and floats parameters, while now you could have any kind of object as T, and don't forget that yield return null is a valid construct, which would not work anymore with structs, unless we have a static ONE_FRAME value available.

We currently have waiting for a number frames, waiting for a time, and waiting for a condition, all three of which would work with this. And the condition case (in both designs) is generic enough for users to specify arbitrary waiting conditions.
They don't need to use any of the builtin parameter types either (they're probably not exposed anyway), since the Func<bool> allows capturing whichever parameters they want. The builtin parameter types are just there so the probably most used buitin conditions (waiting for a time or for number of frames) don't allocate anything on their own.
Returning null wouldn't work anymore, but that might not be that bad - because instead, we're now forced to return explicitly what we want, e.g. wait for one frame. Likely via static readonly field like you said, unless the user prefers new WaitCondition() or default(WaitCondition).
If you compare the following two:
yield return null; // ???

yield return WaitCondition.OneFrame; // Aha!

It's more verbose, but also less "arbitrary". The first one only makes sense if you know what it does already, but it's fine because people know Unity and Unity does it like that. The second one essentially tells you what it does by reading.
But again, I'm currently only throwing ideas around. This is not a finished design or proven concept, it's just something we can look into to avoid allocations where possible.

IMHO it doesn't promote anything more than, let's say, ThreadPool does for managing your own Threads. It's a feature that is there, if you want to use it, go ahead (being mindful of what it means and what it does), if not, no one is pushing it; if you think it's overkill though, I can just remove it or change it as an internal class instead of a public one. OFC it must be tested, thought out if it's not already, etc.

For this PR, I think a List really would be enough, as nothing here implements or really needs to be explicitly IPoolable, and without that, the queued pool doesn't really do much more than that - so personally, I'd probably just do without. For simplicity's sake, and also because the pooling thing just has a lot of discussion potential, and I don't want to mix that up with the coroutines feature if it can be avoided.

I guess I'm dense 😅 , or I have been using this architecture for myself too long and can't see the bigger picture anymore, but I don't understand how a condition can evolve without the relative update method in the struct definition.
i.e. Let's say I end up with a
yield return WaitCondition.ForSeconds(2.5);

who is in charge of counting the time? the condition itself? the CoroutineManager? based on what data, if everything is private?
Just as an example, this is something I'm currently using:
this.flashCondition = new WaitCondition<float>(
	(f) =>
	{
		float elapsedTime = f + Time.DeltaTime;

		float delta = elapsedTime / FLASH_TIME;
		this.flashSprite.SpriteTint = this.flashColor.WithAlpha(1f - delta);
		this.flashSprite.Position = this.sprite.Position - FLASH_DELTA * delta;
		this.flashSprite.Size = this.sprite.Size + FLASH_DELTA * delta * 2;

		return elapsedTime;
	},
	(f) => f >= FLASH_TIME,
	0);

How would you see this in the struct? (I like the struct idea, just want to be sure it fits 😄 )

If you really want to avoid allocations then we also have to think about the closure in the delegate that captures any variables from the outer scope. I think you should pass in the object you want to use (the gameobject for instance) as a parameter instead of using this.
I think its possible to make the condition a struct and make it allocation free without losing extensibilty if we use generics. If its a generic method the clr will actually compile a completely separate method with the correct parameters if the type parameter is a struct, thus avoiding the boxing overhead you normally get. We would have to make everything that uses IWaitCondition generic though.

i.e. Let's say I end up with a
yield return WaitCondition.ForSeconds(2.5);

who is in charge of counting the time? the condition itself? the CoroutineManager? based on what data, if everything is private?

The ForSeconds method would instantiate a new WaitCondition (struct) of type (let's say) WaitConditionType.SecondsPassed and set the float parameter to the current timestamp. To check whether the condition is met, the timestamp is compared against the current time, which is done probably in an internal WaitCondition.Evaluate (or so) instance method, invoked by whichever code manages the coroutine progression.
That method would switch on the condition type and knows what to do and which parameters to read and interpret. User-defined conditions use the Func<bool> condition parameter, which is just invoked blindly.

based on what data, if everything is private?

The outline above was super incomplete, I just wanted to illustrate what kind of data it would store and how it could store it to give you an idea. There is probably a non-private Evaluate method or similar that checks the condition - or not! Would have to be designed / prototyped.

Just as an example, this is something I'm currently using:
this.flashCondition = new WaitCondition<float>(
  (f) =>
  {
    float elapsedTime = f + Time.DeltaTime;

    float delta = elapsedTime / FLASH_TIME;
    this.flashSprite.SpriteTint = this.flashColor.WithAlpha(1f - delta);
    this.flashSprite.Position = this.sprite.Position - FLASH_DELTA * delta;
    this.flashSprite.Size = this.sprite.Size + FLASH_DELTA * delta * 2;

    return elapsedTime;
  },
  (f) => f >= FLASH_TIME,
  0);

How would you see this in the struct? (I like the struct idea, just want to be sure it fits 😄 )

Wait, why does the condition do anything besides check if it's met or not? Shouldn't it be the Coroutine updating sprites, not the wait condition?

Wait, why does the condition do anything besides check if it's met or not? Shouldn't it be the Coroutine updating sprites, not the wait condition?

Yeah, I admit that this example is bending a bit the "wait" part of the construct, and I guess that's what made me focus on the more complex generic behaviors.
After this, I believe that the whole thing can be simplified to something like this:
public struct WaitFor
{
  public static readonly WaitFor NextFrame = new WaitFor ((_) => 0, (_) => true, 0);

  private float internalValue;
  private readonly Func<float, float> updateValue;
  private readonly Func<float, bool> exitCondition;

  public WaitFor(Func<float, float> updateValue, Func<float, bool> exitCondition, float startingValue)
  {
    this.internalValue = startingValue;
    this.updateValue= updateValue;
    this.exitCondition = exitCondition;
  }

  public bool Update()
  {
    this.internalValue = this.updateValue(this.internalValue);
    return this.exitCondition(this.internalValue);
  }

  public static WaitFor Frames(int frames)
  {
    return new WaitFor((i) => i + 1, (i) => i >= frames, 0);
  }

  public static WaitFor Seconds(float seconds)
  {
    return new WaitFor((f) => f + Time.DeltaTime, (f) => f >= seconds, 0);
  }

  public static WaitFor TimeSpan(TimeSpan timeSpan)
  {
    return WaitFor.Seconds((float)timeSpan.TotalSeconds);
  }
}

which brings the previous example to
private IEnumerable<WaitFor> MyCoroutine(...)
{
  ...

  float elapsedTime = 0;
  while(true)
  {
    elapsedTime += Time.DeltaTime;
    float delta = MathF.Clamp01(elapsedTime / FLASH_TIME);

    // do things for this frame until done, for an amount of time in this case,
    // but it could be any other condition (moved far away enough,
    // wait for another variable to change, etc...)
    ...
    if(elapsedTime >= FLASH_TIME)
      break;

    yield return WaitFor.NextFrame;
  }
  ...
}

how do you think?

Thinking about the coroutines it would be nice if it automatically (or optionally) spreads out the updates over multiple frames.
For instance you have alot of instances that have to update something every x frames. For frametime reasons you don't want those updates to all end up in the same frame, causing the frametime to spike. What you want is that it updates 1/x instances every frame:
10k instances
1 update every 10 frames
Old:
frame 1: updates 0 instances
frame 2: updates 0 instances
....
frame 10: updates 10000 instances (stutter!)
New:
frame 1: updates 1000 instances
frame 2: updates 1000 instances
frame 3: updates 1000 instances
etc...

I think this is a key feature for performance. Ofcourse the above is a simple scenario with a constant wait time so we have to think how handle cases with a variable wait time as well and what guarantees we will give to the enduser.

I was thinking, about this point, that maybe there could be another job system in place, in addition to the coroutines one, in charge of dealing with time-consuming or long-running processes, such as the 10k instances update above.
Just throwing out ideas now, but maybe it could be possible to see this system as a separate thread, so that it won't bother the main engine even with thousands of entities to process, potentially leveraging parallel libraries to use the CPU more efficiently (of course this means that this system would be strictly reserved for computation), and give back the results when they are ready
Something like
MAIN ENGINE THREAD                      JOBS THREAD
 Standard loop                           nothing
 ...                                     ...
 Job j = Jobs.StartNew(10kProcess)       Start, keep track of returned reference
 if(j.GetResult() != null)...            Processing
 if(j.GetResult() != null)...            Processing
 if(j.GetResult() != null)...            End, thisJob.Result = ...
 if(j.GetResult() != null)...            ...
 ...                                     ...

where GetResult would return the data and clear it from the job's instance, so that another call in the next frame won't return the same results
Ideally the StartNew or equivalent method would allow a parameter that says if this job has to be done only once, or repeated indefinitelly, there should be a way to cancel it, maybe a way to feed it new parameters?
Just my first 0.02€ on this topic

Hmm but with a actual separate thread you escalate the complexity alot due to synchronization. You cannot really call into any duality API from that job.
It has it use cases surely but its completely different from a coroutine on the same thread thats efficiently scheduled to spread out the load.

Yeah, the idea for the separate thread is to have something that can deal with tasks that do not require a strict frame-by-frame synchronization (pathfinding, AI) and can report back "asynchronously", potentially providing a kind of a framework that masks the low level workings (i.e. keep the jobs thread always active instead of spooling a new one every time).
On the other hand, to stay within the Coroutines system, I put together a kind of a prototype, which could look like this
public static Coroutine ForEach<T>(Scene scene, IEnumerable<T> collection, Action<T> action, int cycleFrames, string name = null)
{
  return Start(scene, OffsetExecution(collection, action, cycleFrames), name);
}

private static IEnumerable<WaitCondition> OffsetExecution<T>(IEnumerable<T> collection, Action<T> action, int cycleFrames)
{
  int sliceSize = (collection.Count() / cycleFrames) + 1;

  // split in equal chunks
  T[][] chunks = Enumerable
    .Range(0, cycleFrames)
    .Select(i => collection.Skip(i * sliceSize).Take(sliceSize).ToArray())
    .ToArray();

  int cycle = -1;
  while(true)
  {
    cycle = (cycle + 1) % cycleFrames;

    for (int i = 0; i < chunks[cycle].Length; i++)
      action(chunks[cycle][i]);

    // Would stuff like this be possible?
    // Parallel.ForEach(blocks[cycle], action);

    yield return null;
  }
}

Maybe with an extra parameter to say if the cycle should repeat indefinitely or not

Yeah, the idea for the separate thread is to have something that can deal with tasks that do not require a strict frame-by-frame synchronization (pathfinding, AI) and can report back "asynchronously", potentially providing a kind of a framework that masks the low level workings (i.e. keep the jobs thread always active instead of spooling a new one every time).

Yeah I think you want something like this as well. Its separate from the coroutine system though. .NET already has the task library which we should leverage for this. There already is a issue for this #603

On the other hand, to stay within the Coroutines system, I put together a kind of a prototype, which could look like this

I think Ill have to checkout the code myself and play a bit with it. Have to check these points:

What happens when coroutines end? Lets say all coroutines in the same cycle end you would end up with a smaller cycle compared to the others. Not sure if this could be solved as 'rebalancing' this is impossible without moving other updates. Maybe we have to make a distinction here between coroutines which are allowed to be moved backwards or forwards for optimization purposes and coroutines which are not allowed to because it breaks correctness.
The code has to be fast and avoid allocations, as beautiful as LINQ is its not suited in this regard.

Sounds like we are gonna have to make a coroutine scheduler that handles this for us which could be quite complex, maybe better to do that in a separate PR but I still think its good to think of it now as it might have a impact on the public API.

// Would stuff like this be possible?

// Parallel.ForEach(blocks[cycle], action);

No this would execute the action on a different thread. It has to happen on the main thread.

Wait, why does the condition do anything besides check if it's met or not? Shouldn't it be the Coroutine updating sprites, not the wait condition?

Yeah, I admit that this example is bending a bit the "wait" part of the construct, and I guess that's what made me focus on the more complex generic behaviors.
After this, I believe that the whole thing can be simplified to something like this:
public struct WaitFor
{
  [...]
}

which brings the previous example to
private IEnumerable<WaitFor> MyCoroutine(...)
{
  [...]
}

how do you think?

I like the new WaitFor design and the example is exactly what I had in mind as the typical use case - internally, we can simplify this even further by unifying the update and exit condition funcs into just a generic "evaluation" function that returns whether it's done and can do whatever otherwise.
We're still getting allocations due to lambdas whenever creating a new wait-for-seconds or wait-for-frames in the current design though, which we could get rid of with the discrimated union special case above for these kinds of often used builtin conditions.

Thinking about the coroutines it would be nice if it automatically (or optionally) spreads out the updates over multiple frames.

We might be mixing concerns and use cases here, which I would try to avoid. As I understand Coroutines, all they do is provide a way to execute game updates over time, like in a scripted sequence of events, an animation, or maybe even a complex, instantiated behavior.
Spreading updates over frames for large numbers of objects is a completely different thing, and also one that a user could easily implement themselves with just the "basic" coroutines. Offloading lots of work somewhere or dealing with large workloads in general is something that I'd see in a different system, like SirePi suggested.

Which brings me to a point from SirePi that I'd like to get back to, which is whether wait conditions should actually be allowed to wrap execution and updates themselves, by design, rather than just waiting. I'm currently leaning towards "no", but maybe "yes" also makes sense when thinking about some Coroutine use cases:

Wait for a few seconds or frames
Wait until a condition is met
Perform an operation and wait until execution is done
Wait until another coroutine has finished
Wait until a number of coroutines all have finished, or until any of a group of coroutines has finished
Wait until processing of X is complete, maybe get results
Continue with some part of the work on a different thread, then go back to main for handling results

The above use cases form a gradient where Coroutines are at the top and C# Tasks are at the bottom. We should either avoid mixing the two very clearly, or embrace the similarity and go all-in with 100% async game code support where stuff like waiting for frames is just a special ValueTask.
Right now, I'm pretty sure we should not go all-in here, since async / await addresses a lot more cases that anything typically used in game code, and the required infrastructure for that is way more complicated than what we actually need for Coroutines. In that case, however, we should try to draw a clear line in the use case gradient. What I'd suggest where to put that line is here:

Wait for a few seconds or frames
Wait until a condition is met

Perform an operation and wait until execution is done
Wait until another coroutine has finished
Wait until a number of coroutines all have finished, or until any of a group of coroutines has finished
Wait until processing of X is complete, maybe get results
Continue with some part of the work on a different thread, then go back to main for handling results

Anything else on top of that is up to the user by defining custom conditions, allowing them to move the line as much down as they want for their project.
We could also put that line here:

Wait for a few seconds or frames
Wait until a condition is met
Perform an operation and wait until execution is done

Wait until another coroutine has finished
Wait until a number of coroutines all have finished, or until any of a group of coroutines has finished
Wait until processing of X is complete, maybe get results
Continue with some part of the work on a different thread, then go back to main for handling results

It might reduce clarity what coroutines and wait conditions are intended for, but if we rebrand exit conditions as "evaluation functions" that happen to return whether they're done, then we already provide the required extension points for users to decide if they want to use Coroutines that way or not, without explicitly suggesting it.
This turned out to be a bit longer than intended - I hope you can still gather something coherent from it 😄

I think the main discriminant here would be to decide if a wait condition should support arbitray code execution inside of its update method, or if it should be limited to keeping track of frames/time.
In the first case, there needs to be a way for the user to access a condition's internal state, either directly or through a referenced area, and the condition would effectively assume the meaning of "do this until that happens".
In the second case, the whole thing can be simplified to the WaitFor example, even going as far as to remove the Funcs and staying with an bool + float struct, and the "do things until" part is left to the user to implement as he sees fit.
I think this would be the bare minimum
public struct WaitFor
{
  public static readonly WaitFor NextFrame = new WaitFor(1, true);

  private readonly bool countFrames;
  private float internalValue;

  public WaitFor(float startingValue, bool countFrames)
  {
    this.internalValue = startingValue;
    this.countFrames = countFrames;
  }

  public bool Update()
  {
    this.internalValue -= (this.countFrames ? 1 : Time.DeltaTime);
    return this.internalValue <= 0;
  }

  public static WaitFor Frames(int frames)
  {
    return new WaitFor(frames, true);
  }

  public static WaitFor Seconds(float seconds)
  {
    return new WaitFor(seconds, false);
  }

  public static WaitFor TimeSpan(TimeSpan timeSpan)
  {
    return WaitFor.Seconds((float)timeSpan.TotalSeconds);
  }
}

It is not extensible anymore, but you can do everything in the Coroutine's enumerator method

After thinking about evenly spreading the load over multiple frames I agree with Adam that this probably should be a separate system.
I think the flexibility that coroutines give you in defining wait conditions makes it really complex/impossible to implement this properly so its not really suited. Might be better suited to a RecurringJob (with a option to run it on the main thread?) or something like that

In the first case, there needs to be a way for the user to access a condition's internal state, either directly or through a referenced area, and the condition would effectively assume the meaning of "do this until that happens".

Do we actually need that? Consider the following with only an evaluate method:
// Various stuff happening in the coroutine before
GameObject someObj = ...;
int someCounter = ....;
float startTime = (float)Time.GameTimer.TotalSeconds;

// Now we wait, but we use coroutine state in the condition via captured scope
yield return new WaitFor.Condition(() =>
{
    // Access any captured state
    float elapsedTime = (float)Time.GameTimer.TotalSeconds - startTime;

    // Access and modify any captured state
    someCounter--;

    return someObj.Disposed || elapsedTime  > 20.0f || someCounter == 0;
});

No storage or access to the actual WaitFor object needed, since the lambdas captured scope doubles as a state object.
One thing that we should still work on is API naming - WaitFor.Condition actually makes it look like the rate at which the function is called, and thus state is mutated, is undefined, because one would expect a function without side effects here. If that's not the case, then a different name might be better, like WaitFor.ExecutionDone or so.
If we keep those conditions strictly waiting conditions like in your super minimal sample, the equivalent to the above would be:
// Various stuff happening in the coroutine before
GameObject someObj = ...;
int someCounter = ....;
float startTime = (float)Time.GameTimer.TotalSeconds;

while (true)
{
    float elapsedTime = (float)Time.GameTimer.TotalSeconds - startTime;
    someCounter--;

    if (someObj.Disposed || elapsedTime  > 20.0f || someCounter == 0)
        break;

    yield return WaitFor.NextFrame;
}

Not too bad either, and arbitrary conditions and logic is still possible. Could be the simplest approach overall, and we could still extend WaitFor capabilities later on, if needed.

No storage or access to the actual WaitFor object needed, since the lambdas captured scope doubles as a state object.

Ah, I was under the assumption that lambdas were bad for the solution.. either is fine for me

If we keep those conditions strictly waiting conditions like in your super minimal sample, the equivalent to the above would be:
while (true)
{
    ...
    if (someObj.Disposed || elapsedTime  > 20.0f || someCounter == 0)
        break;

    yield return WaitFor.NextFrame;
}

or just
while (!(someObj.Disposed || elapsedTime  > 20.0f || someCounter == 0))
{
    ...
    yield return WaitFor.NextFrame;
}

For the naming, if we go with the first solution, I'd change WaitFor to WaitUntil, so you'd have
WaitUntil.NextFrame
WaitUntil.Frames(...)
WaitUntil.Seconds(...)
WaitUntil.TimeSpan(...)
WaitUntil.IsComplete(() => ...)

Maybe we could use the term "passed" instead of "elapsed"? I know "elapsed" is used in established API, but "passed" sounds a bit more natural in this context and works better with "frames".
On the execution / condition thing, we could rephrase this as a continuously updated state that the coroutine will be in until X.
How about the following API?
public struct WaitUntil
{
    public delegate bool StateUpdater();

    // ...

    public static readonly WaitUntil NextFrame;

    // ...

    public static WaitUntil FramesPassed(int frameCount);
    public static WaitUntil SecondsPassed(float seconds, bool gameTime = true); // Real time, if false
    public static WaitUntil TimePassed(TimeSpan duration, bool gameTime = true); // Real time, if false
    public static WaitUntil StateCompleted(StateUpdater func);
}

That way, it would look like this in practice:
yield return WaitUntil.NextFrame;
yield return WaitUntil.FramesPassed(5);
yield return WaitUntil.SecondsPassed(0.5f);
yield return WaitUntil.TimePassed(TimeSpan.FromMinutes(2.0f));
yield return WaitUntil.StateCompleted(() =>
{
    someObj.Health -= 1.7f;
    return someObj.Health < 0.0f;
});

No storage or access to the actual WaitFor object needed, since the lambdas captured scope doubles as a state object.

Ah, I was under the assumption that lambdas were bad for the solution.. either is fine for me

Not necessarily, but you're right that relying on captured scope would prevent users from using a more optimized approach for their frequently used states / waiting conditions. We could allow providing an optional parameter to the method, modifying the API like so:
public delegate bool StateUpdater();
public delegate bool StateUpdater<T>(T arg) where T : class;

public static WaitUntil StateCompleted(StateUpdater func) where T : class;
public static WaitUntil StateCompleted<T>(T arg, StateUpdater<T> func) where T : class;

// The WaitUntil struct just stores this as an object field and casts before invoking the func, allowing WaitUntil to not be generic.

So people could write their own wait condition libs, like this:
public static class FooConditions
{
    public static readonly StateUpdater Poisoned = (obj) =>
    {
        someObj.Health -= 1.7f;
        return someObj.Health < 0.0f;
    };
}

yield return WaitUntil.StateCompleted(someObj, FooConditions.Poisoned);

I don't really have a strong opinion either way here, maybe just see what sticks?

I would prefer the API with the stateobject being passed as a parameter as that should prevent allocating a closure object thus improving performance. Also like you pointed out it makes it easier to make a 'wait condition' lib.

Also if we go this route I think we should not provide 2 flavors here and just choose one of them.

There are still conditions without any state or anything to update - for them, the parameter would be useless, and it would be nice if it could be omitted entirely in that case. Internally, it would just be a null parameter, but the API wouldn't force the user to specify it (and an unused T parameter).

There are still conditions without any state or anything to update - for them, the parameter would be useless, and it would be nice if it could be omitted entirely in that case. Internally, it would just be a null parameter, but the API wouldn't force the user to specify it (and an unused T parameter).

Hmm ye now I think of it the main thing is we want to prevent users from causing a closure to be captured implicitly on every invocation. If C# would have something like a 'static delegate' that does not allow capturing scope this would be solved already. I think this is one of the language proposals for a future C# release.
yield return WaitUntil.StateCompleted(() =>
{
    someObj.Health -= 1.7f;
    return someObj.Health < 0.0f;
});

I still do not understand the need for a stateupdater delegate though. Why not do this in the enumerator method itself and let the yields just care about how long to wait? Any conditions could be defined in the enumerator method itself as well:
while(someObj.Health < 0.0f)
{
    someObj.Health -= 1.7f;
    yield return WaitUntil.NextFrame
}

I admit that extreme optimization is not my strong suite, but is it really such a loss of performance calling a delegate instead of a method?
I mean, besides the inherent cost of using one or the other, once they are defined there's no difference I believe 🤔 no? I mean, they don't have to be re-instantiated every cycle

I admit that extreme optimization is not my strong suite, but is it really such a loss of performance calling a delegate instead of a method?

Well the difference between invoking a method and a delegate is not that big. The compiler does lose the ability to inline the body of the delegate which can make a bigger difference in some cases. For the rest invoking a delegate is pretty comparable to a calling a interface method or a virtual method.
However if said delegate has to allocate a closure (a object which holds the captured context) on every call then the delegate will be much slower. This basically happens when you use a variable that was defined outside of the scope of the delegate body so its pretty implicit.
One easier way to spot these 'hidden' allocations is to use a extension like the heap allocation analyzer https://marketplace.visualstudio.com/items?itemName=MukulSabharwal.ClrHeapAllocationAnalyzer
We should try to make a API that makes it easy for developers to write high performance code so I think we should try to avoid having them to worry about closures and delegates.

We should try to make a API that makes it easy for developers to write high performance code so I think we should try to avoid having them to worry about closures and delegates.

Agree 100%. However, as long as we have any way to specify a delegate, we can't prevent users to use a dynamically allocated one, or a closure.
We could remove this use case entirely and not have state updater conditions at all, which I would be fine with as well. The state lib use case still sounds intriguing though.
As far as the non-parameter variant goes, consider this:
public static class FooConditions
{
    public static readonly StateUpdater<Character> Poisoned = (Character obj) =>
    {
        obj.Health -= 1.7f;
        return obj.Health < 0.0f;
    };
    public static readonly StateUpdater ItsTimeForLunch = () =>
    {
        // No idea if that code is correct, but you know what I mean:
        return DateTime.Now.Hours >= 12 && DateTime.Now.Hours <= 14;
    };
}

yield return WaitUntil.StateCompleted(someObj, FooConditions.Poisoned);
yield return WaitUntil.StateCompleted(FooConditions.ItsTimeForLunch);

No parameters needed for that one, despite not using any closure - that would be the main reason why I'd provide the parameterless variant as well. Otherwise you'd have to make it a StateUpdater<object> with an awkward unused parameter for those cases.

We could remove this use case entirely and not have state updater conditions at all, which I would be fine with as well. The state lib use case still sounds intriguing, but I guess it could easily be expressed differently, allowing us to remove the lambda / condition based WaitUntil entirely (at the cost of being more verbose in those cases?)

Well atleast with the example it seems to be more verbose with the lambda condition:
yield return WaitUntil.StateCompleted(() =>
{
    someObj.Health -= 1.7f;
    return someObj.Health < 0.0f;
});

vs
while(someObj.Health > 0.0f)
{
    someObj.Health -= 1.7f;
    yield return WaitUntil.NextFrame
}

Then again, with the custom condition variant, it would also enable users to specify an implicit cast from some type X to a WaitUntil struct, allowing them to yield return whatever for their convenience. Like waiting for an animation to finish, or a character to finish speaking, and so on.

Hmm I don't think you want to use implicit casts for this. Its too implicit I guess.
You could move the condition to a separate method that returns a IEnumerable<WaitUntil> You cannot directly yield return that though but you can use concat to chain things together or just iterate it yourself.
On the other hand with unit testing that would make it easy to check 'will this complete after x frames/seconds etc' since its just a piece of data and doesn't make any assumptions on how it will be used.

I put together a first draft based on the story so far. WaitUntil.zip
I believe the only thing left to finalize is in regard to the StateCompleted methods.. leave them or take them away? From the discussion I think we can summarize the main points for each way as follows:

With StateCompleted
Without StateCompleted

The coroutine's body looks more like a list of steps that are to be carried out until the relevant exit condition is met, probably without loops
The coroutine's body will most definitely contain loops that might make it harder to read

More verbose to write
Shorter, cleaner code on a line-by-line basis

Basically just syntactic sugar, doesn't add anything that could already be done without it
Requires the user to think about the frame-by-frame evolution of the coroutine

Could introduce performance issues if not used properly, but it can mitigated by a proper API
The same errors can be done by the user anyway

...
...

Of course feel free to add new ones or refute some of them if I misinterpreted them

Could introduce performance issues if not used properly, but it can mitigated by a proper API

As long as its not possible to define a delegate that cannot capture context we cannot prevent closures from happening actually.
Now I think of it one limitation of StateCompleted is that you cannot do things like 'check this condition again in 10 seconds instead of next frame'
You can however easily do this with the loop construct
while(someObj.Health > 0.0f)
{
    someObj.Health -= 1.7f;
    yield return WaitUntil.SecondsPassed(10f);
}

You can however easily do this with the loop construct
while(someObj.Health > 0.0f)
{
    someObj.Health -= 1.7f;
    yield return WaitUntil.SecondsPassed(10f);
}

Its also easy to move the condition after the yield if so desired:
do
{
    someObj.Health -= 1.7f;
    yield return WaitUntil.SecondsPassed(10f);
}
while(someObj.Health > 0.0f);

Makes a lot of sense.. I believe we can agree to start with a timing-only related management for now. Will fix the code accordingly

Sounds pretty solid overall. Let us know when you're ready for the next review!

I am, review away!

Did a small benchmark with benchmarkdotnet and these are the results:
// * Summary *

BenchmarkDotNet=v0.12.1, OS=Windows 10.0.18363.778 (1909/November2018Update/19H2)
AMD Ryzen 9 3900X, 1 CPU, 24 logical and 12 physical cores
  [Host]     : .NET Framework 4.8 (4.8.4150.0), X64 RyuJIT
  DefaultJob : .NET Framework 4.8 (4.8.4150.0), X64 RyuJIT

| Method |      N |            Mean |         Error |        StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|------- |------- |----------------:|--------------:|--------------:|------:|------:|------:|----------:|
|    Foo |      1 |        26.96 ns |      0.386 ns |      0.361 ns |     - |     - |     - |         - |
|    Foo |      3 |        70.55 ns |      0.341 ns |      0.319 ns |     - |     - |     - |         - |
|    Foo |     10 |       226.96 ns |      0.438 ns |      0.342 ns |     - |     - |     - |         - |
|    Foo |    100 |     2,301.60 ns |      9.649 ns |      8.553 ns |     - |     - |     - |         - |
|    Foo |   1000 |    22,102.72 ns |     71.463 ns |     66.847 ns |     - |     - |     - |         - |
|    Foo |  10000 |   218,520.84 ns |    949.447 ns |    888.113 ns |     - |     - |     - |         - |
|    Foo | 100000 | 2,475,735.87 ns | 41,625.357 ns | 32,498.341 ns |     - |     - |     - |         - |

So no allocations in the update loop which is very nice. Seems the coroutine itself has about ~20ns runtime overhead and it scales linearly with the amount of coroutines that are running.
The code:
    class Program
    {
        static void Main(string[] args)
        {
            BenchmarkRunner.Run<CoroutineBenchmark>();
        }
    }

    class CoroutineObject
    {
        public int Value { get; set; }
    }

    [MemoryDiagnoser]
    public class CoroutineBenchmark
    {
        [Params(1, 3, 10, 100, 1000, 10000, 100000)]
        public int N { get; set; }

        public Scene scene;

        [GlobalSetup]
        public void Setup()
        {
            scene = new Scene();
            scene.Activate();

            CoroutineObject obj = new CoroutineObject();
            for (int i = 0; i < N; i++)
            {
                Coroutine coroutine = Coroutine.Start(scene, BasicRoutine(obj), $"basic {i}");
            }
        }

        [Benchmark]
        public void Foo()
        {
            scene.CoroutineManager.Update();
        }

        private static IEnumerable<WaitUntil> BasicRoutine(CoroutineObject obj)
        {
            while (true)
            {
                yield return WaitUntil.NextFrame;
            }
        }
    }

Sounds like you guys got this and I think the general direction of this is pretty good. I'll remove my change requests and leave the rest of the review and merge process to you 👍 Ping me if you need me on anything down the line.

@ilexp, @Barsonax
Do you think it's sensible to change this
public static Coroutine Start(Scene scene, IEnumerable<WaitUntil> method, string name = null)

to
public static Coroutine Start(IEnumerable<WaitUntil> method, string name = null, Scene scene = null)

where if scene is null, it will use Scene.Current ?

Was just giving those methods a look.
Not really a fan of the static utility methods in the Coroutine class as they use static state. It also makes unit testing harder as you now also need a scene instance etc. I think we should just use the CoroutineManager instance on the scene itself. Maybe add a utility method to the scene to easily do this for you so you can write scene.StartCoroutine(....).
We should also make it possible for the CoroutineManager class to accept a IEnumerable as well.
With these changes the coroutine logic no longer has dependencies on a scene which makes it easier to test as well as you will see in my benchmark below. Also expanded my benchmark a bit to also take into account the starting of coroutines:
    class Program
    {
        static void Main(string[] args)
        {
            BenchmarkRunner.Run<CoroutineBenchmark>();
        }
    }

    [MemoryDiagnoser]
    public class CoroutineBenchmark
    {
        [Params(1, 3, 10, 100, 1000, 10000, 100000)]
        public int N { get; set; }

        private CoroutineManager _manager = new CoroutineManager();

        [GlobalSetup]
        public void Setup()
        {
            for (int i = 0; i < N; i++)
            {
                _manager.StartNew(EndlessCoroutine().GetEnumerator(), ""); //If it accepted a IEnumerable directly I wouldnt have to call .GetEnumerator
            }
        }

        [Benchmark]
        public void Endless()
        {
            _manager.Update();
        }

        [Benchmark]
        public void Start_N_Coroutines()
        {
            var manager = new CoroutineManager();
            for (int i = 0; i < N; i++)
            {
                manager.StartNew(EndlessCoroutine().GetEnumerator(), "");
            }
        }

        private static IEnumerable<WaitUntil> EndlessCoroutine()
        {
            while (true)
            {
                yield return WaitUntil.NextFrame;
            }
        }
    }

And the results
// * Summary *

BenchmarkDotNet=v0.12.1, OS=Windows 10.0.18363.778 (1909/November2018Update/19H2)
AMD Ryzen 9 3900X, 1 CPU, 24 logical and 12 physical cores
  [Host]     : .NET Framework 4.8 (4.8.4150.0), X64 RyuJIT
  DefaultJob : .NET Framework 4.8 (4.8.4150.0), X64 RyuJIT

|             Method |      N |             Mean |          Error |         StdDev |     Gen 0 |     Gen 1 |    Gen 2 |  Allocated |
|------------------- |------- |-----------------:|---------------:|---------------:|----------:|----------:|---------:|-----------:|
|            Endless |      1 |         28.85 ns |       0.259 ns |       0.243 ns |         - |         - |        - |          - |
| Start_N_Coroutines |      1 |        367.39 ns |       6.970 ns |       7.458 ns |    3.1543 |         - |        - |     5241 B |
|            Endless |      3 |         76.11 ns |       0.757 ns |       0.708 ns |         - |         - |        - |          - |
| Start_N_Coroutines |      3 |        450.20 ns |       8.804 ns |      10.138 ns |    3.2678 |         - |        - |     5432 B |
|            Endless |     10 |        235.50 ns |       1.433 ns |       1.270 ns |         - |         - |        - |          - |
| Start_N_Coroutines |     10 |        803.69 ns |       9.051 ns |       8.466 ns |    3.8185 |         - |        - |     6348 B |
|            Endless |    100 |      2,315.79 ns |      45.506 ns |      54.172 ns |         - |         - |        - |          - |
| Start_N_Coroutines |    100 |      4,224.03 ns |      32.811 ns |      30.691 ns |   10.1624 |         - |        - |    16883 B |
|            Endless |   1000 |     22,640.59 ns |     196.131 ns |     183.461 ns |         - |         - |        - |          - |
| Start_N_Coroutines |   1000 |     41,746.56 ns |     578.692 ns |     541.309 ns |   61.5845 |    9.5215 |        - |   117989 B |
|            Endless |  10000 |    228,322.10 ns |   1,851.573 ns |   1,641.371 ns |         - |         - |        - |          - |
| Start_N_Coroutines |  10000 |  1,274,988.19 ns |  15,588.004 ns |  14,581.029 ns |  208.9844 |  107.4219 |  39.0625 |  1230680 B |
|            Endless | 100000 |  2,362,414.09 ns |  46,363.687 ns |  64,995.414 ns |         - |         - |        - |          - |
| Start_N_Coroutines | 100000 | 16,305,813.30 ns | 317,686.890 ns | 521,968.671 ns | 2000.0000 | 1281.2500 | 437.5000 | 11731826 B |

Originally I didn't want to change too much in the Scene, but since we are going for a major release, I don't see why not at this point

How about making this one an extension method?
public static Coroutine StartCoroutine(this Scene scene, IEnumerable<WaitUntil> method, string name = null)

// In some component:
this.Scene.StartCoroutine(this.FooRoutine);

Since most coroutine logic is nicely aggregated in the coroutine manager with little effect on scenes otherwise, this would keep the separation but provide the same convenience.

SceneExtensions it is then.. where? under Resources, or do you prefer a separate directory (Extensions?) with the Resources namespace?

SceneExtensions would be too general, maybe something like CoroutineSceneExtensions in the coroutines namespace, and right next to the coroutine files.

Review plz @ilexp @Barsonax 😄

New benchmark results are alot better. Will review the code itself later.
// * Summary *

BenchmarkDotNet=v0.12.1, OS=Windows 10.0.18363.778 (1909/November2018Update/19H2)
AMD Ryzen 9 3900X, 1 CPU, 24 logical and 12 physical cores
  [Host]     : .NET Framework 4.8 (4.8.4150.0), X64 RyuJIT
  DefaultJob : .NET Framework 4.8 (4.8.4150.0), X64 RyuJIT

|             Method |      N |             Mean |          Error |         StdDev |     Gen 0 |     Gen 1 |    Gen 2 |  Allocated |
|------------------- |------- |-----------------:|---------------:|---------------:|----------:|----------:|---------:|-----------:|
|            Endless |      1 |         22.10 ns |       0.137 ns |       0.129 ns |         - |         - |        - |          - |
| Start_N_Coroutines |      1 |        323.25 ns |       4.824 ns |       4.276 ns |    3.0441 |         - |        - |     5057 B |
|            Endless |      3 |         50.71 ns |       0.612 ns |       0.572 ns |         - |         - |        - |          - |
| Start_N_Coroutines |      3 |        391.56 ns |       6.619 ns |       6.192 ns |    3.1495 |         - |        - |     5236 B |
|            Endless |     10 |        152.81 ns |       2.014 ns |       1.884 ns |         - |         - |        - |          - |
| Start_N_Coroutines |     10 |        608.70 ns |       7.751 ns |       7.250 ns |    3.5210 |         - |        - |     5850 B |
|            Endless |    100 |      1,359.68 ns |      23.791 ns |      22.254 ns |         - |         - |        - |          - |
| Start_N_Coroutines |    100 |      3,414.93 ns |      41.126 ns |      38.469 ns |    8.3008 |         - |        - |    13794 B |
|            Endless |   1000 |     13,597.57 ns |     207.006 ns |     193.634 ns |         - |         - |        - |          - |
| Start_N_Coroutines |   1000 |     33,702.82 ns |     474.036 ns |     420.220 ns |   62.8052 |    0.4272 |        - |   105600 B |
|            Endless |  10000 |    137,642.43 ns |   1,713.818 ns |   1,603.107 ns |         - |         - |        - |          - |
| Start_N_Coroutines |  10000 |  1,128,187.21 ns |  19,851.838 ns |  18,569.421 ns |  191.4063 |   93.7500 |  41.0156 |  1145978 B |
|            Endless | 100000 |  1,388,138.39 ns |   9,962.400 ns |   9,318.835 ns |         - |         - |        - |          - |
| Start_N_Coroutines | 100000 | 14,298,808.54 ns | 177,963.971 ns | 166,467.609 ns | 1796.8750 | 1125.0000 | 437.5000 | 10925768 B |

Looking at the Update method I think we cannot really further optimize it without making something like a customized queue.

I think the code itself now looks pretty good and performs well. Next step is to review the unit tests. I think we can do better on the naming and readability:
For the general case we could do this (maybe a parameterized way?). The Assert will give a nice exception telling you the index of the mismatching element if something is wrong.:
        [Test]
        public void Coroutine_Evolution()
        {
            //ARRANGE
            var manager = new CoroutineManager();
            var obj = new CoroutineObject();
            var expected = new[]
            {
                (10, CoroutineStatus.Running),
                (20, CoroutineStatus.Running),
                (20, CoroutineStatus.Running),
                (20, CoroutineStatus.Running),
                (30, CoroutineStatus.Complete),
                (30, CoroutineStatus.Complete)
            };

            //ACT
            Coroutine coroutine = manager.StartNew(this.BasicRoutine(obj), "basic");
            var results = expected.Select(x =>
            {
                var result = (obj.Value, coroutine.Status);
                manager.Update();
                return result;
            }).ToArray();

            //ASSERT
            CollectionAssert.AreEqual(expected, results);
        }

Some more special cases should be done in a separate test so their intention is clear from the name of the method:
        [Test]
        public void StartCoroutine_StartsImmediately()
        {
            //ARRANGE
            var manager  = new CoroutineManager();
            var obj = new CoroutineObject();

            //ACT
            Coroutine coroutine = manager.StartNew(this.BasicRoutine(obj), "basic");

            //ASSERT
            Assert.AreEqual(10, obj.Value);
            Assert.AreEqual(CoroutineStatus.Running, coroutine.Status);
        }

The realtime based tests are a bit more difficult. I think we cannot really get around also testing the whole Time class here.
We also need a test that verifies that the scene update correctly calls the coroutine update method but we don't have to do this for every test which is the reason I written the examples above without a scene being present.
@ilexp maybe you have some more suggestions for the code or the tests?

I can do a review soon-ish, will put it on my ToDo.

Got nothing on the tests though - they look pretty clean to me and I don't have a strong opinion on any specific design here.

For the most part yeah, naming could be a bit better as Basic is just too vague. To solve this one might also have to split some tests so you can properly name special cases.
What I don't like however is that static dependency on the Time class in the WaitUntil struct which makes the realtime test more complex because we are now also testing the Time class. Not really a way around this though.

What happens if the gameobject that started the coroutine gets removed? I think the coroutine will keep running till it ends so it possibly uses a gameobject thats no longer in use.
You could say this is something thats the developers responsibility but the very least we should do is to make a notice of this in the documentation. If we want to go further than that (probably not in this PR) then we could provide a API that automatically cleans up the coroutine when the context where its in started ends.

You are absolutely correct that this is an eventuality; on the other hand, there is no way for the Manager to know beforehand what the Coroutine will affect (it could affect the spawning object, something else, no objects at all, ...).
Plus, the update method is already catching eventual exceptions so it won't fail catastrophically.

You are absolutely correct that this is an eventuality; on the other hand, there is no way for the Manager to know beforehand what the Coroutine will affect (it could affect the spawning object, something else, no objects at all, ...).

You could make a API on the gameobject to start a coroutine and that API also queues up a cleanup action that is run when the gameobject is deactivated. A bit like the UseEffect from React I guess.

Added #817 to continue discussions on open points


Improce docs & examples for interfaces, modules, classes, etc.

hi, I find it very hard to move into imports, exports, declares, modules, successfully with flow, I have failed so far. And reading other issues has made it appear to me that other (even smart) people have been tripped up by all this random example: https://github.com/facebook/flow/issues/769. Thus I would like to suggest that somebody who really groks this stuff does some pair documenting with somebody who doesn't, to work up some succinct but fully fleshed out examples.

Do you want to help with this?

Hi, I would like to take this issue if it's still open. I will most probably be needing help though. But would love to give it a try. Thanks


[Bug]: Panic from markdown-1.0.0-alpha.16 on build

Version
System:
  OS: Linux 6.1 Debian GNU/Linux 12 (bookworm) 12 (bookworm)
  CPU: (16) x64 AMD Ryzen 7 5800X 8-Core Processor
  Memory: 7.00 GB / 31.25 GB
  Container: Yes
  Shell: 5.2.15 - /usr/bin/bash
Browsers:
  Chrome: 127.0.6533.88
npmPackages:
  rspress: ^1.27.0 => 1.27.0

Details
When I try to run npm run build i.e. rspress build in my documentation directory I see:
(base) hayzam@hayzam-pc ~/Documents/bad_doc/panic $ RUST_BACKTRACE=full npm run build

><EMAIL_ADDRESS>build
> rspress build

🔥 Rspress v1.27.0

thread '<unnamed>' panicked at /usr/local/cargo/registry/src/index.crates.io-6f17d22bba15001f/markdown-1.0.0-alpha.16/src/construct/document.rs:567:77:
index out of bounds: the len is 2 but the index is 2
stack backtrace:
   0:     0x7f7c5abdbfdc - <unknown>
   1:     0x7f7c5ac02b9c - <unknown>
   2:     0x7f7c5abd994e - <unknown>
   3:     0x7f7c5abdbdc4 - <unknown>
   4:     0x7f7c5abdd043 - <unknown>
   5:     0x7f7c5abdcd64 - <unknown>
   6:     0x7f7c5abdd5c5 - <unknown>
   7:     0x7f7c5abdd4c1 - <unknown>
   8:     0x7f7c5abdc506 - <unknown>
   9:     0x7f7c5abdd212 - <unknown>
  10:     0x7f7c5a892255 - <unknown>
  11:     0x7f7c5a892412 - <unknown>
  12:     0x7f7c5abab0d2 - <unknown>
  13:     0x7f7c5abbed12 - <unknown>
  14:     0x7f7c5ab9bebd - <unknown>
  15:     0x7f7c5ab9b480 - <unknown>
  16:     0x7f7c5ab9a364 - <unknown>
  17:     0x7f7c5ab8cef9 - <unknown>
  18:     0x7f7c5a8b47a3 - <unknown>
  19:     0x7f7c5a893462 - <unknown>
  20:           0xc78a49 - _ZZN4node14ThreadPoolWork12ScheduleWorkEvENUlP9uv_work_sE_4_FUNES2_
  21:          0x18ab5b0 - worker
                               at /home/iojs/build/ws/out/../deps/uv/src/threadpool.c:122:5
  22:     0x7f7c89aa8134 - start_thread
                               at ./nptl/pthread_create.c:442:8
  23:     0x7f7c89b287dc - __GI___clone3
                               at ./misc/../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
  24:                0x0 - <unknown>
fatal runtime error: failed to initiate panic, error 5
Aborted
(base) hayzam@hayzam-pc ~/Documents/bad_doc/panic $

panic.zip -> This is the zip of my project (without node_modules)
We're working on a CMS and recently migrated from Docusaurus. All the files in the folder inside the zip is auto generated from a DB, it could be that I'm doing something wrong in the files but in any case a panic doesn't sound good?
Reproduce link
https://github.com/user-attachments/files/16529114/panic.zip
Reproduce Steps
Run npm install and npm run build and you ideally should see the error described in details.

I figured the issue out (it was that I was referencing stuff that wasn't available in the index.md file), once I took care of that the panic went away.

yeah, I also solved this by modifying docs/1.0.0/index.mdx
---
pageType: home
hero:
  name: Kalmia
  text: Fast, easy-to-use CMS for your documentations
  tagline: Tagline
  actions:
    - theme: brand
      text: Quick Start
      link: /guide/
    - theme: alt
      text: GitHub
      link: https://github.com/web-infra-dev/rspress
  image:
    src: /rspress-icon.png
    alt: Rspress Logo

features:
  - title: Blazing fast build speed
    details: The core compilation module is based on the Rust front-end toolchain, providing a more ultimate development experience.
    icon: 🏃🏻♀
  - title: Support for MDX content writing
    details: MDX is a powerful way to write content, allowing you to use React components in Markdown.
    icon: 📦
  - title: Built-in full-text search
    details: Automatically generates a full-text search index for you during construction, providing out-of-the-box full-text search capabilities.
    icon: 🎨
  - title: Simpler I18n solution
    details: With the built-in I18n solution, you can easily provide multi-language support for documents or components.
    icon: 🌍
  - title: Static site generation
    details: In production, it automatically builds into static HTML files, which can be easily deployed anywhere.
    icon: 🌈
  - title: Providing multiple custom capabilities
    details: Through its extension mechanism, you can easily extend theme UI and build process.
    icon: 🔥
---

this is an error from markdown-rs imported from mdx-rs, your markdown did not follow the grammar, resulting in parsing errors.
we'll track the error message handling in https://github.com/web-infra-dev/mdx-rs/issues/49


🐛 BUG: create-cloudflare with opennextjs-cloudflare deploy script error

Which Cloudflare product(s) does this pertain to?
C3 (npm create cloudflare)
What versions are you using?

C3 2.35.1

What operating system and version are you using?
Windows 11
Please provide a link to a minimal reproduction
No response
Describe the Bug
The next C3 install uses the wrong deploy command.

Run npm create cloudflare@latest my-next-app -- --framework=next --experimental
Try npm run deploy
Observe:

'cloudflare' is not recognized as an internal or external command,
operable program or batch file.

This was changed in https://github.com/opennextjs/opennextjs-cloudflare/pull/166
Please provide any relevant error logs
No response

The issue here is that the template has not been updated for @opennextjs/cloudflare 0.3.x.
So the fix is to ping the package to 0.2.x, done in this PR but pending release.
We can either close the issue or keep it open to track the upgrade of the templates


Updated dependencies to work on flutter 2.2.0

Hey!
I noticed the app was not working on the newest version of flutter. Here are the changes I made:

I updated most of the dependencies to the latest version, and did the necessary changes for depreciated usages.

I changed the mock package from Mockito to Mocktail (https://pub.dev/packages/mocktail)

I upgrade the gradle version

I set the IOS platform to 9 for sqflite to work

Please let me know if there's something you need me to change 💙

Hi @aumb. Really appreciate you making this PR. Can you please fix build workflow. I am assuming the issue is the flutter version used in build.yaml

Hi @aumb. Really appreciate you making this PR. Can you please fix build workflow. I am assuming the issue is the flutter version used in build.yaml

Yes sure on it!
I can migrate the application to null safety if you'd like as well.

Migrating to null safety would be great @aumb

A

Migrating to null safety would be great @aumb

Okay will migrate as soon as this is merged so i can worked based on this. I'll open another pull request for null safety if this is all ok with you.

Thanks for contributing @aumb 🎉


Android nav bar appear if i access the app from "recent" button

Steps to reproduce
https://github.com/LNReader/lnreader/assets/75091899/1f03f336-64b5-44ca-8b23-c4ea1eee9e6c

with the reader open click on recent button (android nav bar) then click on lnreader. The nav bar will appear (transparent).

Expected behavior
Fullscreen is maintained
Actual behavior

Android nav bar appears
LNReader version
1.1.5
Android version
Android 8
Device
Huawei p8 lite 2017
Other details
No response
Acknowledgements

[X] I have searched the existing issues and this is a new ticket, NOT a duplicate or related to another open or closed issue.
[X] I have written a short but informative title.
[X] If this is an issue with a source, I should be opening an issue in the sources repository.
[X] I have updated the app to version 1.1.15.
[X] I will fill out all of the requested information in this form.

Not able to reproduce this. Could be a device or Android version specific issue.

[llmogcat.txt](https://githu@rajarsheechatterjee om/LNReader/lnreader/files/11928909/llmogcat.txt)
@ra here u go

Hide navigation bar was introduced in Android 4.0 (API level 14).
link: https://developer.android.com/training/system-ui/navigation


Register

@JuliaRegistrator register()

Registration pull request created: JuliaRegistries/General/69904
After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.
This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:
git tag -a v0.1.0 -m "<description of version>" 08952f05f4431dfa2da4e62602a90d29a730fa4d
git push origin v0.1.0


[Feature Request] Save PSBT as HEX

Samourai Wallet has experimental PSBT support but requires transactions to be imported as hex.
It would be nice to be able to copy the psbt (in hex) to clipboard also, saving the step of opening the file to copy the text.

While I think it's lame that Samourai (apparently) doesn't accept PSBT in the standard base64 format, +1 for functionality to copy the psbt to clipboard. Specter-Desktop has this and it's really nice.
For Sparrow testing I've found it annoying to save the PSBT to a file, open the file, copy the contents, and then paste them into a Signer (multiwallet.py software CLI wallet in my case).

Added in 74b4f51.


SilentConfig Setting for ADFS environment

This Article mentions "If you federate your on-premises Active Directory with Azure AD, you must use AD FS to enable this feature." But doesn't provide more details on what needs to be done on ADFS Side. Also the article its pointing to about AAD Connect doesn't give clarity on what exactly needs to be done. It would be great if you can add more details here.
Thanks.

Document Details
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

ID: 3a21a400-6ad2-b371-0205-9a1b51b3fe29
Version Independent ID: 801d184f-046b-8d37-30f7-f82ebda3df3f
Content: Silently configure user accounts - OneDrive
Content Source: OneDrive/use-silent-account-configuration.md
Service: one-drive
GitHub Login: @kaarins
Microsoft Alias: kaarins

@3novsan Thank you for submitting feedback and contributing to the docs. We are currently investigating this.

Hello @3novsan how are you?
Have you seen the links in the Note?
For more info, see How to configure hybrid Azure Active Directory joined devices.
https://docs.microsoft.com/en-us/azure/active-directory/devices/hybrid-azuread-join-plan#federated-environment
Thanks

@3novsan Thank you for submitting feedback. We understand that this issue has been resolved.
Please feel free to re-open this issue if there is a specific area of the docs that we can improve or make better. Thank you.


Problems with CDN, other issues

So, one problem we discovered a bit too late with EQCSS is that when we have CSS files loaded to a CDN in production, the CDN doesn't permit EQCSS to load in the files via AJAX load. So the automatic loading of every CSS file linked in the document with a < link > tag is something we need to change. I like the fact that we have multiple ways we can put the EQCSS in the document, in a script tag, or in the actual CSS files themselves, but this last method isn't documented on your site and was a surprise to us until reading the code.
Also because of this, on a site where our CSS is not all concatenated (a wordpress site with custom theme installed) this means that 30+ css files are loading again, which is overkill.
I recommend that we either take out this undocumented "feature" or put some kind of rule on it that it only Ajax loads documents with an href ending in ".eqcss" or some other attribute match, instead of reloading all CSS. Does this make sense, or am I missing something vital?

#29 I created this PR for you to consider. Solves my current needs by limiting the amount of needless Ajax calls to CSS files.

Hey @jhnsntmthy, thanks for opening this issue. I've commented in the PR so I'll quote that here:

I don't think we should restrict EQCSS to only loading files with the string eqcss in the filename because that would break what's already out there, but also because you could have something like reqcss.css or some other name that would wrongly trigger this.
If you want to have EQCSS ignore fetching a stylesheet via  or


Camera light dark and objects  are zoomed closers

So I have noticed with the camera that the imaged of the camera is a little bit more zoomed in that normal cameras with its dimensions. So now you have fewer objects in the visual frame. At the same time, it seems the light coming into the camera is not as solid as it could be. Other cameras have more light coming into the camera.

@rFlex any luck or fix?

@renjithn any fix?

@briansugar any fix or suggestion on this topic? Seems like the camera comes by default with this issue.

@cerupcat

The fix for light/dark should of been fixed here: https://github.com/rFlex/SCRecorder/pull/302

@cerupcat sweet but what about the aspect ratio of the screen view? For example, when I look at snapchat's screen I capture more of the image view this camera is more zoomed in by default.  If that makes sense?


[ISSUE] UI Not Loading

What happened?

Steps to reproduce the issue

Install the component
Configure the component
Create the dashboard with the following:
views:

strategy:
type: custom:lock-code-manager
config_entry_id: 01J5DZP5C8SFVCNN4QSKD26R60
include_code_slot_sensors: false
icon: mdi:lock-smart
title: Lock Code Manager

See error message
...

Home Assistant Version
2024.8.1
What version of Lock Code Manager are you running?
0.5.1
Lock make and model
Schlage BE469
Relevant log output
No logs

Screenshots
No response
Anything else?
No response

@raman325 would you mind taking a look?

I have the same issue. The lock I have is Weiser SmartCode 5. I tried going back to version 5.0 and have the same problem. Was unable to go back to version 4.x so can't tell for that version. That said, I can manage the lock through service action and I also tried keymaster which is also able to manage the lock so it seems it's not because of an incompatibility with the lock that the UI is not showing.

Any resolution on this, I have the same issue....


Feature - Integrate test in ci flow for Validator POS Node

Set up tests execution during CI for Validator PoS node for PRs. Jira ticket (url).

Add test command execution in docker build step

Doing PR, close because of new PR are created with only result commit.


Update approvals in profile deletes approvals for other client ids

Via the /profile view, one gets a page with a form for each client where one can update the assigned approvals. On my installation, if a user has assigned approvals to multiple clients, pressing the update button correctly updates the approvals for the respective client, but also unexpectedly deletes the approvals for all other clients.
I think this is due to
https://github.com/cloudfoundry/uaa/blob/master/server/src/main/java/org/cloudfoundry/identity/uaa/account/ProfileController.java#L99-L106
This iterates over all approvals, instead of only over the approvals with the respective client id.

Being fixed with UAA 4.5.0


GPO text updates

This issue has been automatically labelled "stale" because it hasn't had recent activity.
A core team member will check in on the status of the PR to help with questions.
Thank you for your contribution!
/cc @jasonblais @hanzei

@deanwhillier / @esethna looks like build failed but otherwise good to merge?


Donation

Hey Jake, not really an issue but you're a hard man to reach - not even an e-mail address on your site ;)
This project saved me a lot of time and is really great & fun to use, so I'd love to do a one-time donation. However, the github sponsoring system is monthly-based. Maybe add a donation button on the readme page?
Regardless; thanks for all your hard work and making it opensource!

Ah, thank you! Yes, my larger project here has another donation link using Buy Me a Coffee, you can find my page here:
https://www.buymeacoffee.com/qJake
I will get this button added to this project as well, I didn't realize people were looking for it. 🙂
Thanks!


primer_efficiency not recovering sequences on file and output structure

Hello @gjeunen !
I am trying to use the primer_efficiency function but I'm running into an issue. I am using version 0.1.8 in a Linux cluster using gitBash on my PC.
I have downloaded a mitogenome database using NSDPY and imported it to CRABS. I followed with the in_silico and downstream steps, including the pga function with no problems. For the 12S-V5 primer I've used, I got 562 sequences of Rodentia. However, when I run the primer_efficiency funtion, I'm only able to recover 2 sequences. The command is as follows:
wd=/home/rachel.turba/promata
indir=$wd/crabs/results/mtgenome
outdir=$wd/crabs/results/mtgenome/visual
raw=$wd/crabs/mtgenomeDB/CRABS_mtgenomes_chordata.fasta

crabs visualization --method primer_efficiency \
	--input $indir/12S/12S-V5_tax_derep_clean.tsv \
	--fwd TAGAACAGGCTCCTCTAG \
	--rev TTAGATACCCCACTATGC \
	--fwd_name 12S-V5-F --rev_name 12S-V5-R \
	--raw_file $raw \
	--tax_group Rodentia \
	--output $outdir/12S/12S-V5_primerEff_rodentia.tsv

When I do this for another primer, CO1-mljgXT (with 846 sequences of rodents), I get 843 sequences back:
crabs visualization --method primer_efficiency \
	--input $indir/CO1/CO1-mljgXT_tax_derep_clean.tsv \
	--fwd GGWACWRGWTGRACWITITAYCCYCC \
	--rev TAIACYTCIGGRTGICCRAAR \
	--fwd_name CO1-mljgXT-F --rev_name CO1-mljgXT-R \
	--raw_file $raw \
	--tax_group Rodentia \
	--output $outdir/CO1/CO1-mljgXT_primerEff_rodentia.tsv

It cannot be something wrong with my command then. And I don't think the primer is the issue, because it was able to recover the sequences for my in_silico steps. Has anyone seen this issue before?
Also, in the output for the command, is it safe to assume that the last 3 columns are the fragment that the primer recovers, and the ends where they attach to (forward and reverse)?

Hello @rturba,
For the primer_efficiency method, the primer sequences need to be available for CRABS to include them into the analysis. Would it be possible that the sequences that are left out in this analysis were all included during the pga step? As this might mean that the primer sequences are not fully present in the raw reference sequence.
The code does look fine indeed.
Thanks,
Gert-Jan

I thought that could be the case, but:

I actually don't have an increase in sequence number when I do the pga step. I keep the same from the previous in_silico one.
And also, I'm working with a mitogenome database, so technically the primer region should be there.

I'm really confused by this :/

Thanks for the additional info. It does seem that there might be a bug in the code. I'll try and fix it, but this may take some time, as I'm currently out of office. I hope to get something to you by the end of August. Apologies for the delay.
Best wishes,
Gert-Jan

Hello @rturba,
My sincere apologies that it took me this long to respond!
crabs --version 1.0.0 is now available and can be downloaded by cloning the GitHub repo (we hope to update the Docker container and conda package shortly). This version should resolve your issue, but please reopen this thread if the issue persists.
Best wishes,
Gert-Jan


fix: custom components are not destroyed after being closed

Types

[x] 🐛 Bug Fixes

详情参见：https://github.com/opensumi/core/issues/3034#issue-1877454248
添加了component-editor-view.tsx文件用于复现。确认没有问题后。我来删除这个文件。
复现步骤：
1、新建文件“test.cmp”、"test.txt"
2、打开文件“test.cmp”，关闭“test.cmp”。控制台输出1（未修复前不会输出。）
3、打开文件“test.cmp”、"test.txt"，保持“test.cmp”为当前Tab，关闭“test.cmp”。控制台输出1（未修复前会正确输出。）
4、打开文件“test.cmp”、"test.txt"，保持“test.txt”为当前Tab，关闭“test.cmp”。控制台输出1（未修复前不会输出。）
Background or solution

🤖 Generated by Copilot at d66d41e

Add and register a custom editor component for .cmp files (link, link, link)
Update the editor group logic to clear and notify the active components when the body or tab changes (link, link)

Changelog

🤖 Generated by Copilot at d66d41e
This pull request enhances the editor service to support custom editor components and adds an example of such a component for .cmp files. It also fixes some issues with the editor component lifecycle when switching editor groups or tabs.

 Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.You have signed the CLA already but the status is still pending? Let us recheck it.

@MMhunter 看一下这个 PR，我看着没啥问题

@MMhunter 已调整

LGTM

/backport to v2.26


Docker deployment fails, apparently not reading ENV correctly

When launching within a docker container via docker-compose, the environment is (seemingly) not being handled correctly. The 'System Settings' modal displays each field in red with the text "Need setup in .env file." even though the proper environment was confirmed as follows:
@dev anything-llm]$ docker exec -it --workdir=/app/collector anything-llm /bin/sh
$ env
HOSTNAME=10db28434b74
VECTOR_DB=chroma
HOME=/app
OPEN_MODEL_PREF=gpt-3.5-turbo
TERM=xterm
PATH=/app/collector/v-env/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
GID=1000
OPEN_AI_KEY=sk-TrusMeMyKeyIsHere
UID=1000
CACHE_VECTORS=true
PWD=/app/collector
CHROMA_ENDPOINT=http://ip_of_chroma_host_here:8000
STORAGE_DIR=./server/storage
SERVER_PORT=3001
NODE_ENV=production

A review of the server code indicates no other expected ENV variables (other than GOOGLE_API_KEY) presumably for Youuge transcript ingestion.
There's one other symptom in that when we name a workspace to create it we get Error: Failed to fetch which I presume is related to the failure to process the environment, bu it may b indicative of a separate issue

You should first use this command: "cp .env.example .env" to create a .env file in the Docker folder, then open the .env file to configure the key of Open AI and the related data of Pinecone

"Need setup in .env file."

Me too. For grins I tried it in Debian bookworm, Rocky 9 and ubuntu 20.04 all with the same result. I got an env similar to my .env when I ran  docker exec -it --workdir=/app/collector anything-llm /bin/sh

@timothycarambat I don't  a solution to this issue, either as a comment explaining the workaround, or a referenced commit addressing the issue. Can you please clarify?

@timothycarambat I don't see a solution to this issue, either as a comment explaining the workaround, or a referenced commit addressing the issue. Can you please clarify?

In discourse Tim said it's a duplicate, and that he is working on it.

@timothycarambat I don't see a solution to this issue, either as a comment explaining the workaround, or a referenced commit addressing the issue. Can you please clarify?

In discord Tim said it's a duplicate, and that he is working on the problem. See; https://discord.com/channels/1114740394715004990/1114740395159597068/1122726007355473982

In that case we need to see i marked as a duplicate, with an indication of which is being treated as the controlling ticket on this issue. The point here is, under no circumstances should it be marked as completed unless it is in fact completed.


Chef Recipe?

I think I recall you mentioning that you use Chef for configuration/deployment.
It would be awesome if you added a generic single-server instance RTD recipe in the repo.

Need to keep the chef stuff up to date in the repo, but closing this.


Option to set titleTemplate once for whole app

For not complex use cases when plugin is used only for setting title of the rendered vue-router page, that would be nice to set titleTemplate once in the config phase as so:
Vue.use(Meta, {
  titleTemplate: (titleChunk) => `${titleChunk} - ${config.APP_VERSION}`,
  // other configs
})

and later on separate routes/pages just use metaInfo.title property to pass title
export default {
  name: 'LoginPage',
  metaInfo: {
    title: 'Login'
  },

and
export default {
  name: 'SearchResults',
  metaInfo: {
    title: 'Search results'
  },

Maybe you can set the template in App.vue? Just like this: https://github.com/declandewet/vue-meta#step-3-start-defining-metainfo

Yes, works like a charm
@issaTan Thanks!


Flink-Canary: Local App Working

Readme has instructions to test and demo the network connectivity checking. Please test and check if functionality is working as intended.

Reviewed.


backup_extension option in command line, made a better passphrase con…

…sole input, added import for dbbackup_settings

Hello sroussy, I made an another pull request with your commit corrected where you are the author (git commit -a): PR #77.
I think we can close your PR.

@sroussy looks like @ZuluPro fixed what I commented about. Thanks for the contribution!!


Allow defining description on call graph nodes; closes #900

Dont generate jsonschema.json; Define schema as single file; closes #615
Notes re jsonschema.json file consolidation: it seems like the jsonschema generated by json-schema-ref-parser is too complicated (or possibly invalid) for general jsonschema client consumption. Putting everything back into a single file and using standard JSON schema $ref's seems to solve the problem and arguably makes things more standard.

Dont generate jsonschema.json; Define schema as single file; closes #615

It looks like this won't be resolved with this PR (testing locally). I'm guessing that won't be fixed until https://github.com/SchemaStore/schemastore/blob/master/src/schemas/json/opspec-io-0.1.7.json is updated.

Dont generate jsonschema.json; Define schema as single file; closes #615

It looks like this won't be resolved with this PR (testing locally). I'm guessing that won't be fixed until https://github.com/SchemaStore/schemastore/blob/master/src/schemas/json/opspec-io-0.1.7.json is updated.

If you're relying on the schemastore for sure  we also need to submit a PR with this update (we need to submit a PR anyways because the one they have is old). If you're relying on the file like is mentioned in https://opctl.io/docs/setup/bare-metal#vscode then you'll need to update link. This did seem to resolve it for me though in my testing.

This PRs a little confusing, since there are two things going on here:

The title refers to one thing, #900, which is to add support for a description field on opsec calls and opspec inputs. This sense to me.
The opening comment refers to another, #615, which is to restructure the json schema to fix VSCode parsing. Also makes sense

Combining the two things in a single PR makes it very hard to tell what actually changed with the JSON schema for the first item, since the entire json schema file was updated. It would be nice to split the two into two PRs (one made to the other branch) so I can review each change independently (two commits would also work, given the rebase enforcement in the codebase).

The title got auto-generated by github from the PR message. I started out adding description property but I actually got blocked by re-generating the schema. It seemed I couldn't generate a valid one anymore. So that led to me needing to fix the schema generation to solve the original task. In this case it was a really minimal schema generation change because it was just adding a single string attribute to an existing object.


Export TimeArbitraries

It would be nice to use TimeArbitraries outside cats-time. Perhaps it could use the testkit style to make it importable
Thanks

I can extract time arbitraries into a separate cats-time-testkit module if this issue is still relevant. @cquiroz what do you think?

Yes, it would be useful. Maybe we should try to get #290 merged first

Solved by #293


add type annotations

Update the code base to use type annotations and run mypy as part of the linter job.
https://mypy-lang.org

I think we have all of this in place now, except for the tests. We can address those as we make further updates, so I'm going t mark this as closed.


MIS-C [NTR]

Preferred term label:
Multisystem Inflammatory Syndrome in Children  Associated with Coronavirus Disease 2019
Synonyms
MIS-C
Definition (free text, please give PubMed ID, if applicable, in format PMID:#######)
See https://emergency.cdc.gov/han/2020/han00432.asp
Parent term (use OLS, or your favorite ontology browser)
Your nano-attribution (ORCID)

for modeling diseases like this, should it be is-a or a causal relation to COVID-19? I think the latter.

I agree, but I don't claim any deep understanding of this particular case beyond popular news reports.

We already have the term MONDO_0100163 'SARS-CoV-2 Kawasaki-like syndrome', which I think is the same thing, I added synonyms.


Upgrade to use latest version of Node on Digital Platform

Requirement

[ ] Upgrade our Digital platform code base to use the latest version of Node. In particular firebase functions should run in a newer version of node (e.g. 18 or 20 or newer). See here for more info: https://firebase.google.com/docs/functions/manage-functions?gen=2nd#set_nodejs_version

Hey team! Please add your planning poker estimate with Zenhub @drieJAC @HalcyonJAC @tomlovesgithub @warrensearle


Flow as a service

Is it possible to, is there a sample of using flow as a service?
The use case I have in mind is creation of F# bindings for the react/react-native libs. Here's an example of the current react bindings. The process at the moment is cumbersome - we import d.ts to produce "import" types then convert generated interface methods into "helpers" DSL. There's quite a bit of manual work and it's not reproducible.
I'm wondering if there a way to ask flow to produce metadata that we could use to produce the DSL directly.

Maybe I'm completely off-track, but would flow --json help you out? It outputs the typechecker results in a parseable JSON format.

I don't want the typecheck results though, I want the types themselves that flow has detected/inferred.

Oh, I see. Sorry I was definitely off-track. The closest thing I can think of is flow type-at-pos <file> <line> <column>
Example, if you have a file foo.js like this:
const x = 42

flow type-at-pos foo.js 1 7 will output
flow type-at-pos foo.js 1 7
number
/Users/gabro/buildo/experiments/flow-cose/foo.js:1:7,1:7

See the following locations:
/Users/gabro/buildo/experiments/flow-cose/foo.js:1:11-12:
number

You can then use the --json options to have a parseable output, example
{"type":"number","reasons":[{"desc":"number","loc":{"source":"/Users/gabro/buildo/experiments/flow-cose/foo.js","type":"SourceFile","start":{"line":1,"column":11,"offset":10},"end":{"line":1,"column":12,"offset":12}},"path":"/Users/gabro/buildo/experiments/flow-cose/foo.js","line":1,"endline":1,"start":11,"end":12}],"loc":{"source":"/Users/gabro/buildo/experiments/flow-cose/foo.js","type":"SourceFile","start":{"line":1,"column":7,"offset":6},"end":{"line":1,"column":7,"offset":7}},"path":"/Users/gabro/buildo/experiments/flow-cose/foo.js","line":1,"endline":1,"start":7,"end":7}

I guess what I'm looking for is a way to ask flow to produce something like this:
https://github.com/facebook/react-native/blob/master/flow/Map.js
simply by pointing it at an entry point.

check out flow gen-flow-files --help. if that doesn't do what you're looking for, flow dump-types will output all of the inferred types, and flow ast will dump the AST. you can probably use those two things to do what you're looking for. a typed ast that combines those two things is being tracked in https://github.com/facebook/flow/issues/248

Ok, that's a bit tricker but I put something together that may be helpful:
flow suggest foo.js | patch foo.js -o foo.tmp.js && flow gen-flow-files foo.tmp.js && rm foo.tmp.js

I'll break it down:

flow suggest foo.js creates a patch that adds all the type annotations Flow was able to infer
patch foo.js -o foo.tmp.js applies the patch and saves the result to a temporary file
flow gen-flow-files foo.tmp.js uses the temporary file to generate the type definition
rm foo.tmp.js removes the temporary file.

Provided you have a foo.js like this in input:
// @flow

export default class Foo {
  bar(x: number) {
    return x;
  }
}

This is the output
// @flow

declare export default class {

  bar(x: number): number;
}

thanks, my brew-installed version wasn't showing any of these options, flow-bin for the win :)

That's strange, I use brew as well and I have the latest version!

I must be missing something, just tried running gen-flow-files against a react-native component (had to update .flowconfig to use 0.33), got the errors:

flow/Promise.js:30
30:   static all: Promise$All;
^^^^^^^^^^^ Library type error:
30:   static all: Promise$All;
^^^^^^^^^^^ identifier Promise$All. Could not resolve name

Am I approaching this correctly, processing one-by-one components using the original sources? Since there no (apparent) index.js to include all the components, will there be any issues reconciling all the resulting declarations?

@et1975 glad to know it worked for you! Do you think the issue can be closed?

Thanks, closing.


Security bug in deserialization of protected values

When deserializing there is no control if object in array I really belongs to this property.
In the 'Sample 6 - ViewModel property encryption and protection' first remove explicit proteced data validation (method ValidateSecretDataDecryptedSuccessfully). Then you can run this command in developer console to display SecretData property.
redwood.viewModels.root.ReadOnlyData$encrypted(redwood.viewModels.root.SecretData$encrypted())

Good catch. I have modified the converter to serialize and deserialize the properties always in the alphabetical order, so we don't need to store indexes in the object, because the order of properties is always the same.

Oh, nice idea


Add woodland compositor, diowpanel, diowwindowlist and diowmenu

DESCRIPTION
woodland
A minimal Wayland compositor based on wlroots and inspired by TinyWl.
diowpanel
A Wayland application that represents a little panel with widgets.
diowwindowlist
A Wayland application showing a list of opened toplevels (applicaiton windows).
diowmenu
A Wayland application menu to quicky access your favorite applications.
CHECKLIST
I have:

[x] 🤳 made sure that what I am adding is targeted for Wayland.
[x] 🔗 checked that the link I am using refers to the source repository.
[x] 📝 checked that the projects and/or the sections are alphabetically sorted.

Thank you!


Error when I run a script with many subdomains

Hello!
I don't know if it is appreciated, but it is constantly giving me an error.

: no such host)e.org[-] Unable to validate base domain: binance.org

This is the Syntax:

gobuster dns -d ${domain} -w ${gobusterDictionary} -t 70 -o GobusterResult.txt

All subdomains listed below if valid.
Could you confirm that it is my problem, or that I am doing something wrong?

Thank you :)

The solution was .trim() at the subdomain called.

Friend, I have the same problem as you but I still don't understand, can you share the complete code?


First git-pull-request pull request

Just wanted to make the first git-pull-request pull request 🤔

:rofl:

Ship it !


#161255244 Create articles CRUD

What does this PR do?

Allow users to create an article

Description of Task to be completed?

Write tests for article endpoints
Create list articles serializer
Retrieve single article by slug API endpoint
Update article API endpoint
Write article model unit tests
Add permission to allow owners only to edit an article

Having the following API endpoints working

Method
Endpoint
Functionality

GET
/api/article/:slug
Retrieve an article

GET
/api/article/
List articles

PUT
/api/article/:slug
Update an article

DELETE
/api/article/:slug
Delete an article

How should this be manually tested?
After cloning the repo, cd into it and RUN python manage.py test authors.apps.article.tests
What are the relevant pivotal tracker stories?
#161255244

Pull Request Test Coverage Report for Build 229

155 of 161 (96.27%)  changed or added relevant lines in 9 files are covered.
No unchanged relevant lines lost coverage.
Overall coverage increased (+2.0%) to 88.639%

Changes Missing Coverage
Covered Lines
Changed/Added Lines
%

authors/apps/article/api/serializers.py
32
35
91.43%

authors/apps/article/apps.py
0
3
0.0%

Totals

Change from base Build 227:
2.0%

Covered Lines:
749

Relevant Lines:
845

💛  - Coveralls


Downloads page of website shows old version numbers and dates

https://iitc.me/desktop/ shows incorrect dates and version numbers for both the main IITC script as well as all the plugins. It would be good to either update them or remove them to avoid confusion.

The version on the website is the same as the last release tag - but same problem with the test builds (website)


fix file naming when first path segment is 'api'

Coverage increased (+0.05%) to 93.585% when pulling 4b46271588c6f1e62b20e19058bc553cc11fe101 on first-path-element-api into 4f0a63cd9d562cf270bd0e5e01fb26a262f97ff5 on master.

closes https://github.com/ePages-de/restdocs-raml/issues/25