You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
2.7 KiB
119 lines
2.7 KiB
/**
|
|
* Timer module
|
|
*
|
|
* @author Deminder <tremminder@gmail.com>
|
|
* @copyright 2021
|
|
* @license GNU General Public License v3.0
|
|
*/
|
|
/* exported Timer */
|
|
const Me = imports.misc.extensionUtils.getCurrentExtension();
|
|
const { RootMode, ScheduleInfo } = Me.imports.lib;
|
|
const logDebug = Me.imports.lib.Convenience.logDebug;
|
|
|
|
const { Gio } = imports.gi;
|
|
|
|
/* TIMER */
|
|
var Timer = class {
|
|
constructor(callbackAction, initialMode = 'shutdown') {
|
|
this._timerMaxSeconds = 0;
|
|
this._timerCancel = null;
|
|
this._callbackAction = callbackAction;
|
|
this._tick = null;
|
|
this._timerId = null;
|
|
this.info = new ScheduleInfo.ScheduleInfo({ mode: initialMode });
|
|
}
|
|
|
|
setTickCallback(tick) {
|
|
this._tick = tick;
|
|
}
|
|
|
|
adjustTo(info) {
|
|
const newDeadline = info.deadline !== this.info.deadline;
|
|
this.info = info;
|
|
if (info.scheduled) {
|
|
if (newDeadline) {
|
|
// update proc process for new deadline
|
|
this.startProcTimer();
|
|
}
|
|
this.startForegroundTick();
|
|
logDebug(
|
|
`Started timer: ${this.info.minutes}min remaining (deadline: ${this.info.deadline})`
|
|
);
|
|
} else {
|
|
this.stopTimer();
|
|
logDebug(
|
|
`Stopped timer: ${this.info.minutes}min remaining (deadline: ${this.info.deadline})`
|
|
);
|
|
}
|
|
}
|
|
|
|
stopTimer() {
|
|
this.stopProcTimer();
|
|
this.stopForeground();
|
|
}
|
|
|
|
_maybeRunTimerAction() {
|
|
if (this._timerCancel !== null) {
|
|
// ensure timer action is only run once
|
|
logDebug(`Running '${this.info.mode}' timer action...`);
|
|
this._callbackAction(this.info.mode);
|
|
}
|
|
}
|
|
|
|
async startProcTimer() {
|
|
// secondary timer witch calls a sleep process as timer
|
|
this.stopProcTimer();
|
|
|
|
const secs = this.info.secondsLeft;
|
|
this._timerCancel = new Gio.Cancellable();
|
|
try {
|
|
if (secs > 0) {
|
|
await RootMode.execCheck(
|
|
['sleep', `${secs}`],
|
|
this._timerCancel,
|
|
false
|
|
);
|
|
}
|
|
this._maybeRunTimerAction();
|
|
} catch {
|
|
} finally {
|
|
this._timerCancel = null;
|
|
}
|
|
}
|
|
|
|
stopProcTimer() {
|
|
if (this._timerCancel !== null) {
|
|
this._timerCancel.cancel();
|
|
}
|
|
this._timerCancel = null;
|
|
}
|
|
|
|
_maybeTick() {
|
|
if (this._tick !== null) {
|
|
this._tick();
|
|
}
|
|
}
|
|
|
|
startForegroundTick() {
|
|
if (this._timerId === null) {
|
|
// primary timer which updates ticks every second
|
|
this._timerId = setInterval(() => {
|
|
this._maybeTick();
|
|
if (!this.info.scheduled || this.info.secondsLeft < 0) {
|
|
// timer completed
|
|
this._maybeRunTimerAction();
|
|
this.stopTimer();
|
|
}
|
|
}, 1000);
|
|
this._maybeTick();
|
|
}
|
|
}
|
|
|
|
stopForeground() {
|
|
if (this._timerId) {
|
|
clearInterval(this._timerId);
|
|
}
|
|
this._timerId = null;
|
|
}
|
|
};
|