1

GLib 的主循环支持为周期性间隔调度回调函数,使用g_timemout_source_new和相关函数。回调将在预定的时间间隔后重复调用,直到它返回false

我现在想用动态间隔修改这个过程。回调应该能够返回一个时间值,而不仅仅是trueor ,该时间值应该传递到下一次调用。false

在 C 中这样做非常简单:可以创建一个新的 GSource 类型,它与调度函数中的超时源不同,然后在设置下一个过期时考虑返回值。

不幸的是,我正在为 GNOME Shell 编写扩展程序,所以我坚持使用 JavaScript。将上述策略移植到 JavaScript 的主要关键点似乎等同g_source_new function, new GLib.Source. 首先,它需要初始化结构类型的长度,这将由sizeofC 中的运算符计算。我不知道如何在 JavaScript 中获取该值。此外,尝试创建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 中创建新的 GSource?

4

1 回答 1

0

g_source_new()并不是真正为语言绑定而设计的,在为 JS 或 Python 生成绑定时应该将其标记为跳过。

正如您在另一个问题中所建议的那样,包括您自己的私有 C 库,通过 GObject 自省访问,这是我通常在应用程序中所做的。但是,我不知道你是否可以为 shell 扩展做这件事。

不过,您应该可以很容易地在 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;
    },
});
于 2016-12-04T04:15:40.527 回答