Create a dynamic rescheduling GSource in JavaScript

会有一股神秘感。 提交于 2019-12-11 04:24:37

问题


GLib's main loop supports scheduling callback functions for periodic intervals, using g_timemout_source_new and related functions. The callback will repeatedly be called after the scheduled interval, until it returns false.

I now want to modify this process with a dynamic interval. Instead of just true or false, the callback should be able to return a time value that should pass until its next invocation.

Doing this in C is quite straightforward: A new GSource Type can be created, that only differs from the timeout source in its dispatch function, which then takes into account the return value when setting the next expiration.

Unfortunately, I am programming an extension for the GNOME Shell, so I'm stuck to JavaScript. The main critical point to porting the above strategy to JavaScript seems to be the equivalent of the g_source_new function, new GLib.Source. First, it requires the length of the struct type to initialize, which would be computed by the sizeof operator in C. I do not know how to get this value in JavaScript. In addition, it is an error to attempt the creation of a GSourceFuncs Struct, the second argument to this constructor, which is needed to hold the dispatch function.

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

How can I create a new GSource in JavaScript?


回答1:


g_source_new() was not really designed for language bindings and should probably be marked to be skipped when generating bindings for JS or Python.

Including your own private C library, accessed via GObject introspection, as you suggest in your other question, is what I would usually do in an app. However, I have no idea if you can do it for a shell extension.

You should quite easily be able to implement what you want in JS, though. Here's a simple example I wrote from memory that seems like it might do what you want:

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


来源:https://stackoverflow.com/questions/40919435/create-a-dynamic-rescheduling-gsource-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!