/
TON618OFF
/
Unity-Project-RTU
Обзор
Документация
Войти
/
TON618OFF
/
Unity-Project-RTU
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Library/PackageCache/com.unity.visualscripting@1.9.4/Runtime/VisualScripting.Flow/Framework/Control/ForEach.cs
175 строк
5 KB
TON618OFF
release
03 окт 2024, 22:20
03 окт 2024, 22:20
7c70e9f
Код
Авторство
О чём код?
using System; using System.Collections; namespace Unity.VisualScripting { /// <summary> /// Loops over each element of a collection. /// </summary> [UnitTitle("For Each Loop")] [UnitCategory("Control")] [UnitOrder(10)] public class ForEach : LoopUnit { /// <summary> /// The collection over which to loop. /// </summary> [DoNotSerialize] [PortLabelHidden] public ValueInput collection { get; private set; } /// <summary> /// The current index of the loop. /// </summary> [DoNotSerialize] [PortLabel("Index")] public ValueOutput currentIndex { get; private set; } /// <summary> /// The key of the current item of the loop. /// </summary> [DoNotSerialize] [PortLabel("Key")] public ValueOutput currentKey { get; private set; } /// <summary> /// The current item of the loop. /// </summary> [DoNotSerialize] [PortLabel("Item")] public ValueOutput currentItem { get; private set; } [Serialize] [Inspectable, UnitHeaderInspectable("Dictionary")] [InspectorToggleLeft] public bool dictionary { get; set; } protected override void Definition() { base.Definition(); if (dictionary) { collection = ValueInput<IDictionary>(nameof(collection)); } else { collection = ValueInput<IEnumerable>(nameof(collection)); } currentIndex = ValueOutput<int>(nameof(currentIndex)); if (dictionary) { currentKey = ValueOutput<object>(nameof(currentKey)); } currentItem = ValueOutput<object>(nameof(currentItem)); Requirement(collection, enter); Assignment(enter, currentIndex); Assignment(enter, currentItem); if (dictionary) { Assignment(enter, currentKey); } } private int Start(Flow flow, out IEnumerator enumerator, out IDictionaryEnumerator dictionaryEnumerator, out int currentIndex) { if (dictionary) { dictionaryEnumerator = flow.GetValue<IDictionary>(collection).GetEnumerator(); enumerator = dictionaryEnumerator; } else { enumerator = flow.GetValue<IEnumerable>(collection).GetEnumerator(); dictionaryEnumerator = null; } currentIndex = -1; return flow.EnterLoop(); } private bool MoveNext(Flow flow, IEnumerator enumerator, IDictionaryEnumerator dictionaryEnumerator, ref int currentIndex) { var result = enumerator.MoveNext(); if (result) { if (dictionary) { flow.SetValue(currentKey, dictionaryEnumerator.Key); flow.SetValue(currentItem, dictionaryEnumerator.Value); } else { flow.SetValue(currentItem, enumerator.Current); } currentIndex++; flow.SetValue(this.currentIndex, currentIndex); } return result; } protected override ControlOutput Loop(Flow flow) { var loop = Start(flow, out var enumerator, out var dictionaryEnumerator, out var currentIndex); var stack = flow.PreserveStack(); try { while (flow.LoopIsNotBroken(loop) && MoveNext(flow, enumerator, dictionaryEnumerator, ref currentIndex)) { flow.Invoke(body); flow.RestoreStack(stack); } } finally { (enumerator as IDisposable)?.Dispose(); } flow.DisposePreservedStack(stack); flow.ExitLoop(loop); return exit; } protected override IEnumerator LoopCoroutine(Flow flow) { var loop = Start(flow, out var enumerator, out var dictionaryEnumerator, out var currentIndex); var stack = flow.PreserveStack(); try { while (flow.LoopIsNotBroken(loop) && MoveNext(flow, enumerator, dictionaryEnumerator, ref currentIndex)) { yield return body; flow.RestoreStack(stack); } } finally { (enumerator as IDisposable)?.Dispose(); } flow.DisposePreservedStack(stack); flow.ExitLoop(loop); yield return exit; } } }