glib的主循环支持调整回调功能以定期间隔,使用g_timemout_source_new和相关功能。在计划间隔后将重复调用回调,直到返回false
。
我现在想通过动态间隔修改此过程。该回调不仅是true
或false
,还应能够返回应通过的时间值,直到下一次调用为止。
在C中执行此操作非常简单:可以创建一种新的GSOURCE类型,仅与其调度函数中的超时源不同,然后在设置下一个到期时考虑了返回值。
不幸的是,我正在编程gnome shell的扩展名,所以我坚持使用JavaScript。将上述策略移植到JavaScript的主要关键点似乎等效于g_source_new function
,new GLib.Source
。首先,它需要结构类型的长度来初始化,这将由sizeof
运算符在C中计算。我不知道如何在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?
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;
},
});