Создать динамический график GSource в JavaScript
Основной цикл GLib поддерживает планирование функций обратного вызова для периодических интервалов, используя g_timemout_source_new и связанные функции. Обратный вызов будет повторно вызываться после запланированного интервала, пока он не вернется false
,
Теперь я хочу изменить этот процесс с динамическим интервалом. Вместо просто true
или же false
обратный вызов должен иметь возможность возвращать значение времени, которое должно пройти до его следующего вызова.
Делать это в C довольно просто: можно создать новый тип GSource, который отличается от источника времени ожидания только своей функцией отправки, которая затем учитывает возвращаемое значение при установке следующего срока действия.
К сожалению, я программирую расширение для оболочки GNOME, поэтому я застрял в JavaScript. Основной критический момент для переноса вышеуказанной стратегии в JavaScript, похоже, эквивалентен g_source_new function
, new GLib.Source
, Во-первых, для инициализации требуется длина типа структуры, который вычисляется sizeof
Оператор в C. Я не знаю, как получить это значение в JavaScript. Кроме того, ошибкой является попытка создания структуры GSourceFuncs, второго аргумента этого конструктора, который необходим для хранения функции диспетчеризации.
gjs> new imports.gi.GLib.SourceFuncs()
Error: Unable to construct struct type SourceFuncs since it has no default constructor and cannot be allocated directly
Как я могу создать новый GSource в JavaScript?
1 ответ
g_source_new()
на самом деле не был предназначен для языковых привязок и, вероятно, должен быть помечен для пропуска при создании привязок для JS или Python.
Включение вашей собственной частной библиотеки C, доступ к которой осуществляется через самоанализ GObject, как вы предлагаете в своем другом вопросе, - это то, что я обычно делал бы в приложении. Тем не менее, я понятия не имею, если вы можете сделать это для расширения оболочки.
Однако вы должны легко реализовать то, что хотите, в JS. Вот простой пример, который я написал по памяти, и кажется, что он может делать то, что вы хотите:
const Scheduler = new Lang.Class({
Name: 'Scheduler',
schedule: function (timeMs, callback, priority=GLib.PRIORITY_DEFAULT) {
this._callback = callback;
this._priority = priority;
GLib.timeout_add(priority, timeMs, this._onTimeout.bind(this));
},
_onTimeout: function (
let nextTimeoutMs = this._callback();
this.schedule(nextTimeoutMs, this._callback, this._priority);
return GLib.SOURCE_REMOVE;
},
});