21 / 16 / 7
Регистрация: 30.01.2018
Сообщений: 117
|
||||||||||||||||||||||||||
1 | ||||||||||||||||||||||||||
Что то не так с системой корутин16.03.2021, 15:43. Показов 2123. Ответов 6
Приветствую всех.
Написал микро менеджер последовательных действий, через корутины. Хотя это даже менеджером нельзя назвать, но суть не в этом. Ситуация такая - Нпс при старте заполняет лист ienumerator'ов действиями которые он хочет последовательно производить(это как бы его цикл действий по уровню) и вызывает StartCoroutine (Это обертка на обычный запуск корутин, но перед этим он делает кое-что)
Тут происходит заполнение этого листа. Из названий методов, которые добавляются в очередь (в реальности же, эта очередь реализована листом), видно что происходит. Тут присутствует цикл, из-за того, что точек к которым нпс идет - несколько. То есть, нпс подошел -> повернулся в определенную сторону -> подождал и поновой, но только с другой точкой уже. Все эти действия реализованы через запуски корутин. То есть, каждое действие при окончании себя, вызывает следующее из очереди.
То есть вызывается корутина, но при этом удаляется это действие из очереди, и в итоге при проходе одного цикла, то есть когда нпс пройдет все точки сделает все повороты и т.д, ему нужно вернуться в первую точку и начать все с начало, и для этого и нужен nativeQueueEnumerators, в очередь queueEnumerators, опять можно засунуть все те действия и опять начать цикл без нашего вмешательства. Надеюсь понятно объяснил, теперь к проблеме, а она заключается в следующем -> Проблема в том, что первый цикл работает нормально, нпс проходит все точки и т.д, и когда приходит время возвращаться в начало, то есть происходит добавление всех начальных действий в queueEnumerators из nativeQueueEnumerators .
Эта функция и запускает следующую корутину из очереди . Setter нужен, так как класс не наследует monobehavior, Условие cor == null, я вставил, что отследить, что происходит, и это условие активируется как после того, как queueEnumerators.Count станет равным нулю(условие выше), после чего произойдет SetStartsValues(), Код
Дальше корутина не вызовется, не понятно почему, то есть cor будет равен null, в консоль выдаст это сообщение и выйдет из функции и нпс просто остановится и все. Фуу, надеюсь вам понятно. Так вот в чем вопрос, почему корутина не вызывается, он просто проходит по ней и выдает null и все.
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
|
|
16.03.2021, 15:43 | |
Ответы с готовыми решениями:
6
Что-то с системой не так(( Что я делаю не так с файловой системой при установке? Судя по s.m.a.r.t диск исправен, но с файловой системой что-то не так Сделать так, чтобы программа работала с шестнадцатиричной системой |
21 / 16 / 7
Регистрация: 30.01.2018
Сообщений: 117
|
|
16.03.2021, 17:17 [ТС] | 3 |
Вы будете удивлены, но это условие срабатывает. И эта ситуация происходит: когда в очереди элементов становится 0, вызывается функция SetStartsValues(), где в очередь, опять добавляются элементы, после чего вызывается корутина , и этот вызов я присваиваю к cor, и когда это происходит, вызов корутины "доджится" и в cor записывается null. В этом и вопрос, - почему?
0
|
![]() ![]() |
|
16.03.2021, 18:43 | 4 |
Вот смотрите, вы создаете объекты типа IEnumerator и сохраняете в списке.
Объект IEnumerator имеет состояние. Он моожет находится в сосотянии начала итераций, в процессе итераций и в состоянии конца итераций. После прохода первого цикла, у вас последовательно вызваются все IEnumerator, и они все отрабатывают. То есть все IEnumerator переходят в состояние конца итераций. А затем, вы пытаетесь снова запустить все те же самые объекты IEnumerator сначала. Но они не могут запуститься сначала, потому что они в состоянии конца итераций. Оттого ваша корутина второй раз и не запускается. Решение - либо создавать на каждом цикле новый объект IEnumerator, либо же вызывать метод Reset() у каждого экземпляра IEnumerator на каждом новом цикле (если ваша реализация IEnumerator поддерживает метод Reset). Обратите внимание, если вы используете упрощенный синтаксис IEnumerator, то есть у вас просто метод типа IEnumerator, с yield внутри, то Reset не поддерживается для такого энумератора.
1
|
21 / 16 / 7
Регистрация: 30.01.2018
Сообщений: 117
|
|
16.03.2021, 19:10 [ТС] | 5 |
Спасибо за объяснения, это многое проясняет. Reset() и вправду не поддерживается, костыль с присваиванием - ничего не вышло, он видимо и само состояние копирует. Свойство current только для чтения, его тоже не изменить. Насколько мне известно интерфейс Ienumerator создан для перебирания коллекций. Каким образом я могу переопределить Reset()?
0
|
3002 / 1551 / 898
Регистрация: 26.10.2018
Сообщений: 4,437
|
|||||||||||
16.03.2021, 20:19 | 6 | ||||||||||
![]() Решение
Ты можешь пихать в очередь не енумы, а лямбды, которые их каждый раз возвращают новыми.
Здесь в лог попадет два сообщения:
1
|
21 / 16 / 7
Регистрация: 30.01.2018
Сообщений: 117
|
||||||||||||||||
17.03.2021, 11:21 [ТС] | 7 | |||||||||||||||
Благодарю за помощь. Это и вправду работает. Кому интересно, как я изменил скрипты, то вот код:
Сами коллекции:
0
|
17.03.2021, 11:21 | |
Помогаю со студенческими работами здесь
7
Почему даже в простое системой потребляется так много памяти?
Рекурсия корутин Рекурсивный вызов корутин Разница запуска корутин Цепочка корутин из xml Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |