2016-12-01 13 views
1

GLib's main loop поддерживает планирование функций обратного вызова для периодических интервалов, используя g_timemout_source_new и связанные функции. Обратный вызов будет повторно вызываться после запланированного интервала, пока он не вернет false.Создайте динамический переносимый источник в JavaScript

Теперь я хочу изменить этот процесс с помощью динамического интервала. Вместо true или false обратный вызов должен иметь возможность вернуть значение времени, которое должно пройти до следующего вызова.

Выполнение этого на C довольно просто: можно создать новый тип источника GSource, который отличается от источника тайм-аута в его dispatch function, который затем учитывает возвращаемое значение when setting the next expiration.

К сожалению, я программирую расширение для оболочки GNOME, поэтому я придерживаюсь JavaScript. Основная критическая точка переноса этой стратегии на JavaScript, по-видимому, эквивалентна the g_source_new function, new GLib.Source. Во-первых, для инициализации требуется длина типа структуры, которая будет вычисляться оператором sizeof в C. Я не знаю, как получить это значение в JavaScript. Кроме того, возникает ошибка в попытке создания a GSourceFuncs Struct, второго аргумента этому конструктору, который необходим для хранения функции отправки.

gjs> new imports.gi.GLib.SourceFuncs() 
Error: Unable to construct struct type SourceFuncs since it has no default constructor and cannot be allocated directly 

Как создать новый источник в JavaScript?

+0

Я также открыт для других решений, включая адаптацию существующего типа источника или [включение бинарных компонентов] (HTTP : //stackoverflow.com/questions/40919457/including-binary-components-in-a-gnome-shell-extension). – XZS

ответ

0

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; 
    }, 
});