Создать динамический график 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;
    },
});
Другие вопросы по тегам