Adding upstream version 48.2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
This commit is contained in:
parent
0d8723e422
commit
1fcdbd5df9
1059 changed files with 623842 additions and 0 deletions
204
js/gdm/batch.js
Normal file
204
js/gdm/batch.js
Normal file
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
* Copyright 2011 Red Hat, Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* In order for transformation animations to look good, they need to be
|
||||
* incremental and have some order to them (e.g., fade out hidden items,
|
||||
* then shrink to close the void left over). Chaining animations in this way can
|
||||
* be error-prone and wordy using just ease() callbacks.
|
||||
*
|
||||
* The classes in this file help with this:
|
||||
*
|
||||
* - Task. encapsulates schedulable work to be run in a specific scope.
|
||||
*
|
||||
* - ConsecutiveBatch. runs a series of tasks in order and completes
|
||||
* when the last in the series finishes.
|
||||
*
|
||||
* - ConcurrentBatch. runs a set of tasks at the same time and completes
|
||||
* when the last to finish completes.
|
||||
*
|
||||
* - Hold. prevents a batch from completing the pending task until
|
||||
* the hold is released.
|
||||
*
|
||||
* The tasks associated with a batch are specified in a list at batch
|
||||
* construction time as either task objects or plain functions.
|
||||
* Batches are task objects, themselves, so they can be nested.
|
||||
*
|
||||
* These classes aren't specific to GDM, but were found to be unintuitive and so
|
||||
* are not used elsewhere. These APIs may ultimately get dropped entirely and
|
||||
* replaced by something else.
|
||||
*/
|
||||
|
||||
import GObject from 'gi://GObject';
|
||||
import * as Signals from '../misc/signals.js';
|
||||
|
||||
export class Task extends Signals.EventEmitter {
|
||||
constructor(scope, handler) {
|
||||
super();
|
||||
|
||||
if (scope)
|
||||
this.scope = scope;
|
||||
else
|
||||
this.scope = this;
|
||||
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
run() {
|
||||
if (this.handler)
|
||||
return this.handler.call(this.scope);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export class Hold extends Task {
|
||||
constructor() {
|
||||
super(null, () => this);
|
||||
|
||||
this._acquisitions = 1;
|
||||
}
|
||||
|
||||
acquire() {
|
||||
if (this._acquisitions <= 0)
|
||||
throw new Error("Cannot acquire hold after it's been released");
|
||||
this._acquisitions++;
|
||||
}
|
||||
|
||||
acquireUntilAfter(hold) {
|
||||
if (!hold.isAcquired())
|
||||
return;
|
||||
|
||||
this.acquire();
|
||||
let signalId = hold.connect('release', () => {
|
||||
hold.disconnect(signalId);
|
||||
this.release();
|
||||
});
|
||||
}
|
||||
|
||||
release() {
|
||||
this._acquisitions--;
|
||||
|
||||
if (this._acquisitions === 0)
|
||||
this.emit('release');
|
||||
}
|
||||
|
||||
isAcquired() {
|
||||
return this._acquisitions > 0;
|
||||
}
|
||||
}
|
||||
|
||||
export class Batch extends Task {
|
||||
constructor(scope, tasks) {
|
||||
super();
|
||||
|
||||
this.tasks = [];
|
||||
|
||||
for (let i = 0; i < tasks.length; i++) {
|
||||
let task;
|
||||
|
||||
if (tasks[i] instanceof Task)
|
||||
task = tasks[i];
|
||||
else if (typeof tasks[i] == 'function')
|
||||
task = new Task(scope, tasks[i]);
|
||||
else
|
||||
throw new Error('Batch tasks must be functions or Task, Hold or Batch objects');
|
||||
|
||||
this.tasks.push(task);
|
||||
}
|
||||
}
|
||||
|
||||
process() {
|
||||
throw new GObject.NotImplementedError(`process in ${this.constructor.name}`);
|
||||
}
|
||||
|
||||
runTask() {
|
||||
if (!(this._currentTaskIndex in this.tasks))
|
||||
return null;
|
||||
|
||||
return this.tasks[this._currentTaskIndex].run();
|
||||
}
|
||||
|
||||
_finish() {
|
||||
this.hold.release();
|
||||
}
|
||||
|
||||
nextTask() {
|
||||
this._currentTaskIndex++;
|
||||
|
||||
// if the entire batch of tasks is finished, release
|
||||
// the hold and notify anyone waiting on the batch
|
||||
if (this._currentTaskIndex >= this.tasks.length) {
|
||||
this._finish();
|
||||
return;
|
||||
}
|
||||
|
||||
this.process();
|
||||
}
|
||||
|
||||
_start() {
|
||||
// acquire a hold to get released when the entire
|
||||
// batch of tasks is finished
|
||||
this.hold = new Hold();
|
||||
this._currentTaskIndex = 0;
|
||||
this.process();
|
||||
}
|
||||
|
||||
run() {
|
||||
this._start();
|
||||
|
||||
// hold may be destroyed at this point
|
||||
// if we're already done running
|
||||
return this.hold;
|
||||
}
|
||||
|
||||
cancel() {
|
||||
this.tasks = this.tasks.splice(0, this._currentTaskIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
export class ConcurrentBatch extends Batch {
|
||||
process() {
|
||||
let hold = this.runTask();
|
||||
|
||||
if (hold)
|
||||
this.hold.acquireUntilAfter(hold);
|
||||
|
||||
// Regardless of the state of the just run task,
|
||||
// fire off the next one, so all the tasks can run
|
||||
// concurrently.
|
||||
this.nextTask();
|
||||
}
|
||||
}
|
||||
|
||||
export class ConsecutiveBatch extends Batch {
|
||||
process() {
|
||||
let hold = this.runTask();
|
||||
|
||||
if (hold && hold.isAcquired()) {
|
||||
// This task is inhibiting the batch. Wait on it
|
||||
// before processing the next one.
|
||||
let signalId = hold.connect('release', () => {
|
||||
hold.disconnect(signalId);
|
||||
this.nextTask();
|
||||
});
|
||||
} else {
|
||||
// This task finished, process the next one
|
||||
this.nextTask();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue