1

GLib のメイン ループは、 g_timemout_source_newおよび関連する関数を使用して、定期的な間隔でコールバック関数のスケジューリングをサポートします。コールバックは、スケジュールされた間隔の後、返されるまで繰り返し呼び出されますfalse

このプロセスを動的な間隔で変更したいと思います。trueまたはの代わりにfalse、コールバックは、次の呼び出しまで経過する時間値を返すことができる必要があります。

C でこれを行うのは非常に簡単です。新しい GSource タイプを作成できます。これは、ディスパッチ関数のタイムアウト ソースとのみ異なり、次の有効期限を設定するときに戻り値を考慮に入れます。

残念ながら、私は GNOME シェルの拡張機能をプログラミングしているので、JavaScript に固執しています。上記の戦略を JavaScript に移植する際の主な重要なポイントg_source_new functionnew GLib.Source. まず、初期化する構造体型の長さが必要ですsizeof。これは、C の演算子によって計算されます。JavaScript でこの値を取得する方法がわかりません。さらに、ディスパッチ関数を保持するために必要な、このコンストラクターの 2 番目の引数である 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 のバインディングを生成するときにスキップするようにマークする必要があります。

他の質問で提案しているように、GObject イントロスペクションを介してアクセスする独自のプライベート C ライブラリを含めることは、私が通常アプリで行うことです。ただし、シェル拡張でそれができるかどうかはわかりません。

ただし、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 に答える