Last active
April 15, 2024 10:47
-
-
Save aalmada/a1edba42d27df7524b9f13c5e9fdfd34 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
SharpLab tools in Run mode: | |
• value.Inspect() | |
• Inspect.Heap(object) | |
• Inspect.Stack(value) | |
• Inspect.MemoryGraph(value1, value2, …) | |
*/ | |
using System; | |
using System.Collections.Generic; | |
var root = ParallelAll([ | |
Invert(Repeat(WriteLineRange(0, 4), 2)), | |
WriteLineRange(10, 10), | |
]); | |
foreach(var _ in root) | |
{ | |
Console.WriteLine("-"); | |
} | |
static IEnumerable<BehaviorStatus> Succeed() | |
{ | |
yield return BehaviorStatus.Succeeded; | |
} | |
static IEnumerable<BehaviorStatus> Fail() | |
{ | |
yield return BehaviorStatus.Failed; | |
} | |
static IEnumerable<BehaviorStatus> Sequence(IEnumerable<BehaviorStatus>[] children) | |
{ | |
ArgumentNullException.ThrowIfNull(children); | |
return GetEnumerable(children); | |
static IEnumerable<BehaviorStatus> GetEnumerable(IEnumerable<BehaviorStatus>[] children) | |
{ | |
for(var index = 0; index < children.Length; index++) | |
{ | |
var child = children[index]; | |
foreach(var status in child) | |
{ | |
switch(status) | |
{ | |
case BehaviorStatus.Running: | |
yield return BehaviorStatus.Running; | |
break; | |
case BehaviorStatus.Succeeded: | |
goto childSucceeded; | |
case BehaviorStatus.Failed: | |
yield return BehaviorStatus.Failed; | |
yield break; | |
} | |
} | |
childSucceeded: | |
if(index < children.Length - 1) | |
yield return BehaviorStatus.Running; | |
} | |
yield return BehaviorStatus.Succeeded; | |
} | |
} | |
static IEnumerable<BehaviorStatus> Select(IEnumerable<BehaviorStatus>[] children) | |
{ | |
ArgumentNullException.ThrowIfNull(children); | |
return GetEnumerable(children); | |
static IEnumerable<BehaviorStatus> GetEnumerable(IEnumerable<BehaviorStatus>[] children) | |
{ | |
for(var index = 0; index < children.Length; index++) | |
{ | |
var child = children[index]; | |
foreach(var status in child) | |
{ | |
switch(status) | |
{ | |
case BehaviorStatus.Running: | |
yield return BehaviorStatus.Running; | |
break; | |
case BehaviorStatus.Succeeded: | |
yield return BehaviorStatus.Succeeded; | |
yield break; | |
case BehaviorStatus.Failed: | |
goto childFailed; | |
} | |
} | |
childFailed: | |
if(index < children.Length - 1) | |
yield return BehaviorStatus.Running; | |
} | |
yield return BehaviorStatus.Failed; | |
} | |
} | |
static IEnumerable<BehaviorStatus> ParallelAny(IEnumerable<BehaviorStatus>[] children) | |
{ | |
ArgumentNullException.ThrowIfNull(children); | |
return GetEnumerable(children); | |
static IEnumerable<BehaviorStatus> GetEnumerable(IEnumerable<BehaviorStatus>[] children) | |
{ | |
var enumerators = new IEnumerator<BehaviorStatus>[children.Length]; | |
for (var index = 0; index < enumerators.Length && index < children.Length; index++) | |
enumerators[index] = children[index].GetEnumerator(); | |
try | |
{ | |
while(true) | |
{ | |
foreach(var enumerator in enumerators) | |
{ | |
enumerator.MoveNext(); | |
switch(enumerator.Current) | |
{ | |
case BehaviorStatus.Succeeded: | |
yield return BehaviorStatus.Succeeded; | |
yield break; | |
case BehaviorStatus.Failed: | |
yield return BehaviorStatus.Failed; | |
yield break; | |
} | |
} | |
yield return BehaviorStatus.Running; | |
} | |
} | |
finally | |
{ | |
foreach(var enumerator in enumerators) | |
enumerator.Dispose(); | |
} | |
} | |
} | |
static IEnumerable<BehaviorStatus> ParallelAll(IEnumerable<BehaviorStatus>[] children) | |
{ | |
ArgumentNullException.ThrowIfNull(children); | |
return GetEnumerable(children); | |
static IEnumerable<BehaviorStatus> GetEnumerable(IEnumerable<BehaviorStatus>[] children) | |
{ | |
var enumerators = new BehaviorEnumerator[children.Length]; | |
for (var index = 0; index < enumerators.Length && index < children.Length; index++) | |
enumerators[index] = new BehaviorEnumerator { Instance = children[index].GetEnumerator() }; | |
try | |
{ | |
var succeededCounter = 0; | |
while(true) | |
{ | |
foreach(var enumerator in enumerators) | |
{ | |
if(!enumerator.Succeeded) | |
{ | |
enumerator.Instance.MoveNext(); | |
switch(enumerator.Instance.Current) | |
{ | |
case BehaviorStatus.Succeeded: | |
enumerator.Succeeded = true; | |
succeededCounter++; | |
if(succeededCounter == children.Length) | |
{ | |
yield return BehaviorStatus.Succeeded; | |
yield break; | |
} | |
break; | |
case BehaviorStatus.Failed: | |
yield return BehaviorStatus.Failed; | |
yield break; | |
} | |
} | |
} | |
yield return BehaviorStatus.Running; | |
} | |
} | |
finally | |
{ | |
foreach(var enumerator in enumerators) | |
enumerator.Instance.Dispose(); | |
} | |
} | |
} | |
static IEnumerable<BehaviorStatus> Invert(IEnumerable<BehaviorStatus> child) | |
{ | |
ArgumentNullException.ThrowIfNull(child); | |
return GetEnumerable(child); | |
static IEnumerable<BehaviorStatus> GetEnumerable(IEnumerable<BehaviorStatus> child) | |
{ | |
foreach(var status in child) | |
{ | |
switch(status) | |
{ | |
case BehaviorStatus.Running: | |
yield return BehaviorStatus.Running; | |
break; | |
case BehaviorStatus.Succeeded: | |
yield return BehaviorStatus.Failed; | |
yield break; | |
case BehaviorStatus.Failed: | |
yield return BehaviorStatus.Succeeded; | |
yield break; | |
} | |
} | |
} | |
} | |
static IEnumerable<BehaviorStatus> Repeat(IEnumerable<BehaviorStatus> child, int count) | |
{ | |
ArgumentNullException.ThrowIfNull(child); | |
ArgumentOutOfRangeException.ThrowIfNegative(count); | |
return GetEnumerable(child, count); | |
static IEnumerable<BehaviorStatus> GetEnumerable(IEnumerable<BehaviorStatus> child, int count) | |
{ | |
for(var counter = 0; counter < count; counter++) | |
{ | |
foreach(var status in child) | |
{ | |
switch(status) | |
{ | |
case BehaviorStatus.Running: | |
yield return BehaviorStatus.Running; | |
break; | |
case BehaviorStatus.Succeeded: | |
goto childSucceeded; | |
case BehaviorStatus.Failed: | |
yield return BehaviorStatus.Failed; | |
yield break; | |
} | |
} | |
childSucceeded: | |
if(counter < count - 1) | |
yield return BehaviorStatus.Running; | |
} | |
yield return BehaviorStatus.Succeeded; | |
} | |
} | |
static IEnumerable<BehaviorStatus> RepeatUntilFail(IEnumerable<BehaviorStatus> child) | |
{ | |
ArgumentNullException.ThrowIfNull(child); | |
return GetEnumerable(child); | |
static IEnumerable<BehaviorStatus> GetEnumerable(IEnumerable<BehaviorStatus> child) | |
{ | |
while(true) | |
{ | |
foreach(var status in child) | |
{ | |
switch(status) | |
{ | |
case BehaviorStatus.Running: | |
yield return BehaviorStatus.Running; | |
break; | |
case BehaviorStatus.Succeeded: | |
goto childSucceeded; | |
case BehaviorStatus.Failed: | |
yield return BehaviorStatus.Succeeded; | |
yield break; | |
} | |
} | |
childSucceeded: | |
yield return BehaviorStatus.Running; | |
} | |
} | |
} | |
static IEnumerable<BehaviorStatus> WriteLine(string? message) | |
{ | |
Console.WriteLine(message); | |
yield return BehaviorStatus.Succeeded; | |
} | |
static IEnumerable<BehaviorStatus> WriteLineRange(int start, int count) | |
{ | |
ArgumentOutOfRangeException.ThrowIfNegative(count); | |
return GetEnumerable(start, count); | |
static IEnumerable<BehaviorStatus> GetEnumerable(int start, int count) | |
{ | |
var end = start + count; | |
for(var value = start; value < end; value++) | |
{ | |
Console.WriteLine(value); | |
if(value < end - 1) | |
yield return BehaviorStatus.Running; | |
} | |
yield return BehaviorStatus.Succeeded; | |
} | |
} | |
enum BehaviorStatus { Running, Succeeded, Failed }; | |
class BehaviorEnumerator | |
{ | |
public required IEnumerator<BehaviorStatus> Instance { get; init; } | |
public bool Succeeded { get; set; } = false; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
0 | |
10 | |
- | |
1 | |
11 | |
- | |
2 | |
12 | |
- | |
3 | |
13 | |
- | |
0 | |
14 | |
- | |
1 | |
15 | |
- | |
2 | |
16 | |
- | |
3 | |
- |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"version": 1, | |
"target": "Run", | |
"mode": "Release", | |
"branch": "core-x64" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment