94 lines
3.9 KiB
JavaScript
94 lines
3.9 KiB
JavaScript
//////////////////////////////////////////////////////////////////////////////////////////
|
|
// ) ( //
|
|
// ( /( ( ( ) ( ( ( ( )\ ) ( ( //
|
|
// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( //
|
|
// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ //
|
|
// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) //
|
|
// | '_ \ || | '_| ' \)) | ' \()| || | \ V V / | ' \)) _` / _ \ V V (_-< //
|
|
// |_.__/\_,_|_| |_||_| |_|_|_| \_, | \_/\_/|_|_||_|\__,_\___/\_/\_//__/ //
|
|
// |__/ //
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// SPDX-FileCopyrightText: Simon Schneegans <code@simonschneegans.de>
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
'use strict';
|
|
|
|
import GObject from 'gi://GObject';
|
|
|
|
import {Shader} from './Shader.js';
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
// Each effect of Burn-My-Windows owns an instance of this class. It is used to create //
|
|
// shaders whenever a new one is required. It tries to re-use old shaders as much as //
|
|
// possible in order to avoid memory leaks. //
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
export default class ShaderFactory {
|
|
|
|
// Creates a new ShaderFactory. Requires the nick of the effect and a callback function
|
|
// which will be called whenever a new shader is created.
|
|
constructor(nick, setupFunc) {
|
|
// The _freeShaders array contains previously created shaders which are not currently
|
|
// in use.
|
|
this._freeShaders = [];
|
|
|
|
// The nick of the effect is required when creating new shaders as it's part of the
|
|
// GLSL source code file name.
|
|
this._nick = nick;
|
|
|
|
// Store the setup callback.
|
|
this._setupFunc = setupFunc;
|
|
}
|
|
|
|
// ---------------------------------------------------------------- API for extension.js
|
|
|
|
// This is called from extension.js whenever a window is opened or closed. It returns an
|
|
// instance of the shader class, trying to reuse previously created shaders. If a new
|
|
// shader instance is required, it calls creates a new one and calls the setupFunc
|
|
// thereafter.
|
|
getShader() {
|
|
let shader;
|
|
|
|
// If there are currently no free shaders, we have to create a new one.
|
|
if (this._freeShaders.length == 0) {
|
|
|
|
// Since Shell.GLSLEffect caches the shader source per class (not per instance), we
|
|
// have to derive a new shader type for each effect. The type name contains the nick
|
|
// of the effect to make it unique.
|
|
const typeName = `BurnMyWindowsShader_${this._nick}`;
|
|
|
|
// Only try to register the new type once.
|
|
if (GObject.type_from_name(typeName) == null) {
|
|
const outerThis = this;
|
|
GObject.registerClass({GTypeName: typeName}, class ShaderImp extends Shader {
|
|
// This will actually load the GLSL source code from the resources.
|
|
_init() {
|
|
super._init(outerThis._nick);
|
|
}
|
|
|
|
// This can be called to mark this instance to be re-usable.
|
|
returnToFactory() {
|
|
outerThis._freeShaders.push(this);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Now create a niew instance of the newly registered shader type.
|
|
// GObject.Object.new is only available with newer versions of GJS.
|
|
if (GObject.Object.new) {
|
|
shader = GObject.Object.new(GObject.type_from_name(typeName), {});
|
|
} else {
|
|
shader = GObject.Object.newv(GObject.type_from_name(typeName), []);
|
|
}
|
|
|
|
// Call the provided setup callback.
|
|
this._setupFunc(shader);
|
|
|
|
} else {
|
|
shader = this._freeShaders.pop();
|
|
}
|
|
|
|
return shader;
|
|
}
|
|
} |