Skip to content

Commit

Permalink
Merge branch 'release/0.8.1' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
caewok committed Oct 3, 2024
2 parents adb6d8e + e6ae6a5 commit 5cb2198
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 23 deletions.
3 changes: 3 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 0.8.1
Fix for scene not loading due to errors with rendering cached walls when Elevation Ruler v0.10.12 is active.

## 0.8.0
Update to FoundryVTT v12 compatibility. Adds a tab dedicated to Light/Mask in the new v12 App v2 windows for lighting and sound configuration. Uses v12's new canvas edges feature to implement wall caching.

Expand Down
3 changes: 1 addition & 2 deletions module.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
"description": "Mask Foundry VTT lights and sounds",
"version": "#{VERSION}#",
"library": false,
"manifestPlusVersion": "1.0.0",
"compatibility": {
"minimum": "12",
"verified": "12.324"
"verified": "12.331"
},
"authors": [
{
Expand Down
54 changes: 40 additions & 14 deletions scripts/ModuleSettingsAbstract.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,26 @@ PATCHES.BASIC = {};
/**
* Wipe the settings cache on update
*/
function updateSetting(document, change, options, userId) { // eslint-disable-line no-unused-vars
const [module, ...arr] = document.key.split(".");
const key = arr.join("."); // If the key has periods, multiple will be returned by split.
if ( module === MODULE_ID && Settings.cache.has(key) ) Settings.cache.delete(key);
async function set(wrapper, namespace, key, value, options) {
if ( namespace === MODULE_ID ) ModuleSettingsAbstract.cache.delete(key);
return wrapper(namespace, key, value, options);
}

PATCHES.BASIC.WRAPS = { set };

/**
* Wipe setting cache on update hook.
* Needed so world settings get wiped from all users.
* @param {Document} document The existing Document which was updated
* @param {object} changed Differential data that was used to update the document
* @param {Partial<DatabaseUpdateOperation>} options Additional options which modified the update request
* @param {string} userId The ID of the User who triggered the update workflow
*/
function updateSetting(document, changed, options, userId) {
const [theNamespace, key] = document.key.split(".", 2);
if ( !(theNamespace || key) ) return;
if ( theNamespace !== MODULE_ID ) return;
ModuleSettingsAbstract.cache.delete(key);
}

PATCHES.BASIC.HOOKS = { updateSetting };
Expand All @@ -40,15 +56,15 @@ export class ModuleSettingsAbstract {
* @returns {*}
*/
static get(key) {
// TODO: Bring back a working cache.

const cached = this.cache.get(key);
if ( typeof cached !== "undefined" ) {
const origValue = game.settings.get(MODULE_ID, key);
if ( origValue !== cached ) {
console.debug(`Settings cache fail: ${origValue} !== ${cached} for key ${key}`);
return origValue;
}
// For debugging, can confirm against what the value should be.
// const origValue = game.settings.get(MODULE_ID, key);
// if ( origValue !== cached ) {
// console.debug(`Settings cache fail: ${origValue} !== ${cached} for key ${key}`);
// return origValue;
// }

return cached;

Expand All @@ -64,10 +80,7 @@ export class ModuleSettingsAbstract {
* @param {*} value
* @returns {Promise<boolean>}
*/
static async set(key, value) {
this.cache.delete(key);
return game.settings.set(MODULE_ID, key, value);
}
static async set(key, value) { return game.settings.set(MODULE_ID, key, value); }

static async toggle(key) {
const curr = this.get(key);
Expand Down Expand Up @@ -98,4 +111,17 @@ export class ModuleSettingsAbstract {
* Register all settings
*/
static registerAll() {}

/**
* Check the stored value for a setting.
* Typically used to retrieve stored setting values prior to registration. E.g., in data migration.
* @param {string} storageKey The key from Settings.KEYS
* @param {"world"|"client"} [storageType="world"] Whether this is a client or a world setting
* @returns {string|undefined} The stored setting as a string
*/
static _getStorageValue(storageKey, storageType = "world") {
if ( !game.settings?.storage ) return undefined;
if ( storageType === "client" ) return game.settings.storage.get(storageType).getItem(`${MODULE_ID}.${storageKey}`);
return game.settings.storage.get(storageType).getSetting(`${MODULE_ID}.${storageKey}`).value;
}
}
25 changes: 19 additions & 6 deletions scripts/Patcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ export class Patcher {
switch ( typeName ) {
case "HOOKS": patchCl = HookPatch; break;

case "STATIC_OVERRIDES": // eslint-disable-line no-fallthrough
case "STATIC_OVERRIDES":
case "OVERRIDES":
case "STATIC_MIXES":
case "MIXES":
Expand All @@ -144,13 +144,13 @@ export class Patcher {
? libWrapper.MIXED : libWrapper.WRAPPER;
break;

case "STATIC_GETTERS": // eslint-disable-line no-fallthrough
case "STATIC_GETTERS":
case "GETTERS":
cfg.isGetter = true;
patchCl = MethodPatch;
break;

case "STATIC_SETTERS": // eslint-disable-line no-fallthrough
case "STATIC_SETTERS":
case "SETTERS":
cfg.isSetter = true;
patchCl = MethodPatch;
Expand Down Expand Up @@ -197,7 +197,7 @@ export class Patcher {
Object.defineProperty(cl, name, descriptor);

const prototypeName = cl.constructor?.name;
const id = `${prototypeName ?? cl.name }.${prototypeName ? "prototype." : ""}${name}`; // eslint-disable-line template-curly-spacing
const id = `${prototypeName ?? cl.name}.${prototypeName ? "prototype." : ""}${name}`;
return { id, args: { cl, name } };
}

Expand All @@ -218,12 +218,21 @@ export class Patcher {
: className;

const configObj = CONFIG[baseClass];
if ( isConfig && configObj && configObj.sheetClasses?.base ) {
// Attempt to locate a base sheet class.
for ( const [key, obj] of Object.entries(configObj.sheetClasses.base) ) {
if ( !(obj.default && obj.cls) ) continue;
return returnPathString ? `CONFIG.${baseClass}.sheetClasses.base["${key}"].cls` : obj.cls;
}
}

if ( !configObj || isConfig ) return returnPathString ? className : eval?.(`"use strict";(${className})`);

// Do this the hard way to catch inconsistencies
switch ( className ) {
case "Actor":
case "ActiveEffect":
case "RegionBehavior":
case "Item":
isDoc = true; break;
}
Expand Down Expand Up @@ -401,7 +410,9 @@ export class MethodPatch extends AbstractPatch {
else if ( this.config.isSetter ) this.prevMethod = this.prevMethod?.set;
else this.prevMethod = this.prevMethod?.value;

this.regId = Patcher.addClassMethod(this.#cl, this.target, this.patchFn, { getter: this.config.isGetter, setter: this.config.isSetter });
this.regId = Patcher.addClassMethod(this.#cl, this.target, this.patchFn, {
getter: this.config.isGetter, setter: this.config.isSetter
});
}

/**
Expand All @@ -413,7 +424,9 @@ export class MethodPatch extends AbstractPatch {

// Add back the original, if any.
if ( this.prevMethod ) {
Patcher.addClassMethod(this.#cl, this.target, this.prevMethod, { getter: this.config.isGetter, setter: this.config.isSetter });
Patcher.addClassMethod(this.#cl, this.target, this.prevMethod, {
getter: this.config.isGetter, setter: this.config.isSetter
});
this.prevMethod = undefined;
}
this.regId = undefined;
Expand Down
2 changes: 1 addition & 1 deletion scripts/customEdges.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export function updateCachedEdges(placeable, edgesCache) {
canvas.edges.set(id, edge);
}
// canvas.perception.renderFlags.set({ refreshEdges: true, initializeLighting: true });
canvas.perception.update({ refreshEdges: true, initializeLighting: true })
if ( canvas.ready ) canvas.perception.update({ refreshEdges: true, initializeLighting: true })
}

/**
Expand Down

0 comments on commit 5cb2198

Please sign in to comment.