91 lines
3.3 KiB
JavaScript
Executable File
91 lines
3.3 KiB
JavaScript
Executable File
import { get_supported_effects } from '../effects/effects.js';
|
|
|
|
/// An object to manage effects (by not destroying them all the time)
|
|
export const EffectsManager = class EffectsManager {
|
|
constructor(connections) {
|
|
this.connections = connections;
|
|
this.used = [];
|
|
this.SUPPORTED_EFFECTS = get_supported_effects();
|
|
|
|
Object.keys(this.SUPPORTED_EFFECTS).forEach(effect_name => {
|
|
// init the arrays containing each unused effect
|
|
this[effect_name + '_effects'] = [];
|
|
|
|
// init the functions for each effect
|
|
this['new_' + effect_name + '_effect'] = function (params) {
|
|
let effect;
|
|
if (this[effect_name + '_effects'].length > 0) {
|
|
effect = this[effect_name + '_effects'].splice(0, 1)[0];
|
|
effect.set({
|
|
...this.SUPPORTED_EFFECTS[effect_name].class.default_params, ...params
|
|
});
|
|
} else
|
|
effect = new this.SUPPORTED_EFFECTS[effect_name].class({
|
|
...this.SUPPORTED_EFFECTS[effect_name].class.default_params, ...params
|
|
});
|
|
|
|
this.used.push(effect);
|
|
this.connect_to_destroy(effect);
|
|
return effect;
|
|
};
|
|
});
|
|
}
|
|
|
|
connect_to_destroy(effect) {
|
|
effect.old_actor = effect.get_actor();
|
|
if (effect.old_actor)
|
|
effect.old_actor_id = effect.old_actor.connect('destroy', _ => {
|
|
this.remove(effect, true);
|
|
});
|
|
|
|
this.connections.connect(effect, 'notify::actor', _ => {
|
|
let actor = effect.get_actor();
|
|
|
|
if (effect.old_actor && actor != effect.old_actor)
|
|
effect.old_actor.disconnect(effect.old_actor_id);
|
|
|
|
if (actor && actor != effect.old_actor) {
|
|
effect.old_actor_id = actor.connect('destroy', _ => {
|
|
this.remove(effect, true);
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
// IMPORTANT: do never call this in a mutable `this.used.forEach`
|
|
remove(effect, actor_already_destroyed = false) {
|
|
if (!actor_already_destroyed)
|
|
try {
|
|
effect.get_actor()?.remove_effect(effect);
|
|
} catch (e) {
|
|
this._warn(`could not remove the effect, continuing: ${e}`);
|
|
}
|
|
if (effect.old_actor)
|
|
effect.old_actor.disconnect(effect.old_actor_id);
|
|
delete effect.old_actor;
|
|
delete effect.old_actor_id;
|
|
|
|
let index = this.used.indexOf(effect);
|
|
if (index >= 0) {
|
|
this.used.splice(index, 1);
|
|
|
|
Object.keys(this.SUPPORTED_EFFECTS).forEach(effect_name => {
|
|
if (effect instanceof this.SUPPORTED_EFFECTS[effect_name].class)
|
|
this[effect_name + '_effects'].push(effect);
|
|
});
|
|
}
|
|
}
|
|
|
|
destroy_all() {
|
|
const immutable_used_list = [...this.used];
|
|
immutable_used_list.forEach(effect => this.remove(effect));
|
|
Object.keys(this.SUPPORTED_EFFECTS).forEach(effect_name => {
|
|
this[effect_name + '_effects'].splice(0, this[effect_name + '_effects'].length);
|
|
});
|
|
}
|
|
|
|
_warn(str) {
|
|
console.warn(`[Blur my Shell > effects mng] ${str}`);
|
|
}
|
|
};
|