Как передать нативные указатели void в Dart Isolate - без копирования? - PullRequest
0 голосов
/ 19 апреля 2020

Я работаю над раскрытием аудио библиотеки (C library) для Dart. Чтобы запустить аудио-движок, требуется несколько шагов инициализации (не блокирующих для пользовательского интерфейса), затем обработка аудио запускается с помощью функции выполнения, которая блокирует (обработка аудио - тяжелая задача). Вот почему я пришел читать о дартс изолятов.

Моя первая мысль была о том, что мне нужно было только вызвать метод performance в изоляте, но это кажется невозможным, поскольку функция execute принимает состояние механизма в качестве первого аргумента - это состояние механизма является непрозрачным указателем. (Указатель в дротике: ffi). При попытке передать состояние двигателя в новый изолятор с помощью функции вычислений, Dart VM возвращает ошибку - он не может передать указатели C в изолятор.

Я не смог найти способ передать эти данные в изолятор, полагаю, это связано с отдельной памятью основного изолята и той, которую я создаю.

Итак, мне, вероятно, следует управлять всем состоянием двигателя в изоляторе, что означает:

  • Создание состояния двигателя
  • Инициализация его с некоторыми параметрами (строками)
  • активировать функцию выполнения
  • управлять звуком во время выполнения

Я не смог найти ни одного примера того, как выполнить эти действия в изоляте, но сработал из основного потока / изолят. Ни о том, как управлять изолировать память (сохранить состояние двигателя и использовать его). Конечно, я мог бы сделать

Вот не изолированный пример того, что я хочу сделать:

Pointer<Void> engineState = createEngineState();
initEngine(engineState, parametersString);
startEngine(engineState);
perform(engineState);

И во время выполнения, вызванный действиями пользовательского интерфейса (например, изменено значение слайдера или кнопка щелкнул):

setEngineControl(engineState, valueToSet);
double controleValue = getEngineControl(engineState);

Состояние двигателя может быть заключено в класс, я не думаю, что это действительно имеет значение здесь. Является ли это классом или непрозрачным типом данных, я не могу найти, как управлять этим состоянием и сохранять его, а также выполнять триггеры из основного потока (обрабатываются изолированно). Есть идеи ?

Заранее спасибо.

PS: при написании замечаю, что мой вопрос / объяснение может быть неточным, я должен сказать, что я немного растерялся здесь, так как никогда использованные изоляты дротика. Пожалуйста, скажите мне, если какая-то информация отсутствует.

РЕДАКТИРОВАТЬ 24 апреля: Кажется, он работает с созданием и управлением состоянием объекта внутри Isolate. Но главная проблема не решена. Поскольку метод execute фактически блокирует, пока он не завершен, невозможно по-прежнему получать сообщения в изоляте. Сначала я подумал, что нужно использовать метод executeBlock, который выполняет только блок аудиосэмплов. Например:

while(performBlock(engineState)) {
// listen messages, and do something
}

Но, похоже, это не сработает, процесс по-прежнему блокируется, пока не закончится воспроизведение звука. Даже если этот l oop вызывается в asyn c методе в изоляте, он блокируется, и сообщения не читаются.

Теперь я думаю о возможности передать управляемый Pointer<Void> в главном изоляте другому, который затем будет рабочим (только для метода execute), и затем сможет вызывать некоторые методы управления из основного изолята ,

Пакет isolate Dart предоставляет суббиблиотеку реестра для управления некоторой общей памятью. Но все еще невозможно передать указатель void между изолятами.

[ОШИБКА: flutter / lib / ui / ui_dart_state. cc (157)] Необработанное исключение: недопустимый аргумент (ы): собственные объекты (из dart: ffi), такие как указатели и структуры, не могут проходить между изолятами.

Кто-нибудь уже встречался с такой ситуацией?

...