/** * Workspaces (or sessions) are settings and canvas state storage structures that can be changed at will, saved, and restored. */ /** * Represents a workspace * * @template [S] Settings type */ class Workspace { /** * The name of the workspace * @type {string} */ name = "Workspace Name"; /** * Workspace default settings. * * @type {S} */ defaults = {}; /** * Storage for workspace settings. * * @type {S} */ settings = new Proxy( {}, { get(t, name) { if (t[name] === undefined) t[name] = JSON.parse(localStorage.getItem(`openoutpaint/${name}`)) ?? defaults[name]; return t[name]; }, set(t, name, value) { localStorage.setItem(`openoutpaint/${name}`, JSON.stringify(value)); t[name] = value; }, } ); /** * Storage for other data * * @type {Record} */ data = new Proxy({}, {}); /** * Saves the data to the workspace * * @param {string} key The key of the data to be saved (eg. history or layers) * @param {any} data The data to be saved on this key. MUST BE SERIALIZABLE. */ save(key, data) { this.data[key] = data; } /** * Gets saved data from the workspace * * @param {string} key The key of the data to be saved (eg. history or layers) * @param {any} data The data to be saved on this key. MUST BE SERIALIZABLE. */ load(key) { return this.data[key]; } /** * @param {string} name The name of the workspace * @param {Object} options * @param {S} options.defaults Default workspace settings */ constructor(name, options = {}) { defaultOpt(options, { defaults: {}, }); this.name = name; this.defaults = options.defaults; } } const workspaces = { /** * Loaded workspace * * @type {Workspace} */ _workspace: null, get current() { return this._workspace; }, /** * On Workspace Changed * * @type {Observer<{workspace: Workspace}>} */ onchange: new Observer(), /** * Loads a workspace * * @param {Workspace} workspace Workspace to load */ loadWorkspace(workspace) { console.info(`[workspaces] Loading workspace: ${workspace.name}`); // Set current workspace this._workspace = workspace; // Notify observers that the workspace has changed this.onchange.emit({workspace}); }, }; // Creates a new workspace instance workspaces.loadWorkspace( new Workspace("Default", { workspaceDefaults, }) );