Ищем синхронную альтернативу методу .toImage () Флаттера - PullRequest
0 голосов
/ 11 апреля 2019

Сейчас я экспериментирую с Flutter и игровым движком Flame. Для этого я расширяю класс Flame BaseGame и выполняю тяжелую обработку внутри его конструктора. Тяжелая обработка включает в себя составление изображения из других изображений и окончательное рисование его на временном холсте, и результат сохраняется в объекте Picture.

ui.PictureRecorder rec = new ui.PictureRecorder();
Canvas tempCanvas = new Canvas(rec, bgRect);
// left out picture operations
ui.Picture pic = rec.endRecording();

Чтобы наконец получить объект Image, мне нужно вызвать асинхронный метод .toData () , который возвращает Future. Я упаковываю вызов в асинхронный метод getImage ()

getImage(ui.Picture pic, Rect bgRect) async {
    background = await pic.toImage(bgRect.width.toInt(), bgRect.height.toInt());
    done = true;
}

( background - это переменная класса типа Image, которая используется внутри метода render () класса BaseGame)

Проблема в том, что все мои операторы внутри конструктора игры выполняются асинхронно и после его завершения запускается метод render (), но фон может быть еще недоступен. Чтобы обойти это, я добавил переменную класса done типа bool, которая получает значение true внутри метода getImage (). Теперь я изменил render () так, чтобы ждать, пока будет выполнено true.

void render(Canvas canvas) {
    if (done) {
        canvas.drawImage(background, new Offset(0.0, 0.0), new Paint());
    }
}

Конечно, это не элегантно. Есть ли способ дождаться завершения метода .toImage () внутри функции конструктора расширенного класса BaseGame? Я попытался сделать конструктор асинхронным, как:

class TheGame extends BaseGame {
    Image background;
    bool done = false;

    TheGame(DeviceOrientation orientation) async {  
    }
}

но это дает мне ошибку:

Модификатор 'async' нельзя применить к телу конструктора

Что еще я могу попытаться сделать "синхронным"?

1 Ответ

0 голосов
/ 11 апреля 2019

Если вам действительно нужно изображение перед рендерингом первого кадра, вы можете просто создать статический метод, который отвечает за создание TheGame

class TheGame extends BaseGame {
    final Image background;

    TheGame._(DeviceOrientation orientation, this.background);

    static Future<TheGame> create(DeviceOrientation orientation) async {
      return TheGame._(orientation, await generateImage());
    }
}

но я предполагаю, что это не помешает, если вы визуализируете несколько кадров без фонового изображения, тогда я бы посоветовал вам просто установить background != null вместо свойства done, которое кажется немного избыточным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...