Skip to content

Commit

Permalink
Merge branch 'release/0.7.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
caewok committed Jun 10, 2023
2 parents 2bc6b3b + 508ed59 commit a8376e6
Show file tree
Hide file tree
Showing 8 changed files with 221 additions and 84 deletions.
3 changes: 3 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 0.7.0
Updated for v11. Update geometry lib to v0.2.0.

## 0.6.6
Update geometry lib to v0.1.5.

Expand Down
6 changes: 3 additions & 3 deletions module.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"name": "lightmask",
"minimumCoreVersion": "10",
"minimumCoreVersion": "11",
"id": "lightmask",
"title": "Light/Sound Mask",
"description": "Mask Foundry VTT lights and sounds",
"version": "This is auto replaced",
"library": false,
"manifestPlusVersion": "1.0.0",
"compatibility": {
"minimum": "10.279",
"verified": "10.291"
"minimum": "11.299",
"verified": "11.301"
},
"authors": [
{
Expand Down
12 changes: 8 additions & 4 deletions scripts/customEdges.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export function onCheckRelative(event) {
}

const previewData = this._getSubmitData(newData);
foundry.utils.mergeObject(this.object, previewData, {inplace: true});
this._previewChanges(previewData);
this.render();
}

Expand Down Expand Up @@ -99,8 +99,7 @@ export function onAddWallIDs(event) {
}

const previewData = this._getSubmitData(newData);
foundry.utils.mergeObject(this.object, previewData, {inplace: true});

this._previewChanges(previewData);
this.render();
}

Expand Down Expand Up @@ -280,5 +279,10 @@ export class TempWall {
other.intersectsWith.set(this, x);
}

_removeIntersections = Wall.prototype._removeIntersections;
_removeIntersections() {
for ( const other of this.intersectsWith.keys() ) {
other.intersectsWith.delete(this);
}
this.intersectsWith.clear();
}
}
2 changes: 1 addition & 1 deletion scripts/geometry
28 changes: 18 additions & 10 deletions scripts/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,21 @@ isEmpty
import { MODULE_ID, TEMPLATES, SHAPE, FLAGS } from "./const.js";
import { log, getFlag, noFlag, setFlag } from "./util.js";
import { registerLightMask } from "./patching.js";

import { registerGeometry } from "./geometry/registration.js";

import {
injectAmbientLightConfiguration,
injectAmbientSoundConfiguration,
injectTokenLightConfiguration } from "./render.js";

import { lightMaskPreUpdateAmbientLight } from "./preUpdate.js";

// ----- ClockwiseSweep ----- //
import { controlledWallIDs, TempWall } from "./customEdges.js";

// Hooks
import {
renderAmbientLightConfigHook,
renderAmbientSoundConfigHook,
renderTokenConfigHook,
updateAmbientLightHook,
updateAmbientSoundHook,
updateTokenHook } from "./render.js";

Hooks.once("init", async function() {
log("Initializing...");

Expand Down Expand Up @@ -158,11 +160,17 @@ Hooks.on("canvasReady", async canvas => {
});

/* Render the parameters for a given selected shape */
Hooks.on("renderAmbientLightConfig", injectAmbientLightConfiguration);
Hooks.on("renderAmbientSoundConfig", injectAmbientSoundConfiguration);
Hooks.on("renderTokenConfig", injectTokenLightConfiguration);
Hooks.on("renderAmbientLightConfig", renderAmbientLightConfigHook);
Hooks.on("renderAmbientSoundConfig", renderAmbientSoundConfigHook);
Hooks.on("renderTokenConfig", renderTokenConfigHook);

/* Update the data for a given source */
Hooks.on("preUpdateToken", lightMaskPreUpdateAmbientLight);
Hooks.on("preUpdateAmbientLight", lightMaskPreUpdateAmbientLight);
Hooks.on("preUpdateAmbientSound", lightMaskPreUpdateAmbientLight);

/* Update whenever the flags change */
Hooks.on("updateAmbientLight", updateAmbientLightHook);
Hooks.on("updateAmbientSound", updateAmbientSoundHook);
Hooks.on("updateToken", updateTokenHook);

92 changes: 54 additions & 38 deletions scripts/patching.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ libWrapper,
LightSource,
SoundSource,
AmbientSoundConfig,
AmbientSoundDocument,
canvas,
GlobalLightSource
*/
Expand All @@ -11,72 +12,87 @@ GlobalLightSource
import {
identifyEdgesClockwiseSweepPolygon,
computeClockwiseSweep } from "./customEdges.js";
import { lightMaskActivateListeners } from "./render.js";
import {
_refreshAmbientSound,
defaultOptionsAmbientSoundConfig,
_renderAmbientSoundConfig,
closeAmbientSoundConfig,
_onChangeInputAmbientSoundConfig,
_previewChangesAmbientSoundConfig,
_resetPreviewAmbientSoundConfig,
_updateObjectAmbientSoundConfig } from "./sound_config.js";
_updateObjectAmbientSoundConfig,
_onUpdateAmbientSoundDocument,
getDataSoundConfig } from "./sound_config.js";

import { MODULE_ID, FLAGS } from "./const.js";
import { boundaryPolygon } from "./boundaryPolygon.js";
import { getFlag } from "./util.js";

export function registerLightMask() {
/**
* Helper to wrap methods.
* @param {string} method Method to wrap
* @param {function} fn Function to use for the wrap
* @param {object} [options] Options passed to libWrapper.register. E.g., { perf_mode: libWrapper.PERF_FAST}
*/
function wrap(method, fn, options = {}) { libWrapper.register(MODULE_ID, method, fn, libWrapper.WRAPPER, options); }

// ------ AmbientLightConfig ----- //
libWrapper.register(MODULE_ID, "AmbientLightConfig.prototype.activateListeners", lightMaskActivateListeners, libWrapper.WRAPPER);
/**
* Helper to wrap methods using mixed.
* @param {string} method Method to wrap
* @param {function} fn Function to use for the wrap
* @param {object} [options] Options passed to libWrapper.register. E.g., { perf_mode: libWrapper.PERF_FAST}
*/
function wrapMixed(method, fn, options = {}) { libWrapper.register(MODULE_ID, method, fn, libWrapper.MIXED, options); }

// ------ AmbientSoundConfig ----- //
libWrapper.register(MODULE_ID, "AmbientSoundConfig.prototype.activateListeners", lightMaskActivateListeners, libWrapper.WRAPPER);
libWrapper.register(MODULE_ID, "AmbientSoundConfig.defaultOptions", defaultOptionsAmbientSoundConfig, libWrapper.WRAPPER);
libWrapper.register(MODULE_ID, "AmbientSoundConfig.prototype._render", _renderAmbientSoundConfig, libWrapper.WRAPPER);
libWrapper.register(MODULE_ID, "AmbientSoundConfig.prototype.close", closeAmbientSoundConfig, libWrapper.WRAPPER);
libWrapper.register(MODULE_ID, "AmbientSoundConfig.prototype._onChangeInput", _onChangeInputAmbientSoundConfig, libWrapper.WRAPPER);
libWrapper.register(MODULE_ID, "AmbientSoundConfig.prototype._updateObject", _updateObjectAmbientSoundConfig, libWrapper.WRAPPER);

Object.defineProperty(AmbientSoundConfig.prototype, "_previewChanges", {
value: _previewChangesAmbientSoundConfig,
writable: true,
configurable: true
});

Object.defineProperty(AmbientSoundConfig.prototype, "_resetPreview", {
value: _resetPreviewAmbientSoundConfig,
/**
* Helper to add a method to a class.
* @param {class} cl Either Class.prototype or Class
* @param {string} name Name of the method
* @param {function} fn Function to use for the method
*/
function addClassMethod(cl, name, fn) {
Object.defineProperty(cl, name, {
value: fn,
writable: true,
configurable: true
});
}

export function registerLightMask() {

// ------ AmbientLightConfig ----- //

// ------ AmbientSoundConfig ----- //
// wrap("AmbientSoundConfig.prototype.activateListeners", lightMaskActivateListeners);
wrap("AmbientSoundConfig.defaultOptions", defaultOptionsAmbientSoundConfig);
wrap("AmbientSoundConfig.prototype._render", _renderAmbientSoundConfig);
wrap("AmbientSoundConfig.prototype.close", closeAmbientSoundConfig);
wrap("AmbientSoundConfig.prototype._onChangeInput", _onChangeInputAmbientSoundConfig);
wrap("AmbientSoundConfig.prototype._updateObject", _updateObjectAmbientSoundConfig);
wrap("AmbientSoundConfig.prototype.getData", getDataSoundConfig);

addClassMethod(AmbientSoundConfig.prototype, "_previewChanges", _previewChangesAmbientSoundConfig);
addClassMethod(AmbientSoundConfig.prototype, "_resetPreview", _resetPreviewAmbientSoundConfig);

addClassMethod(AmbientSoundDocument.prototype, "_onUpdate", _onUpdateAmbientSoundDocument);

// ------ TokenConfig ----- //
libWrapper.register(MODULE_ID, "TokenConfig.prototype.activateListeners", lightMaskActivateListeners, libWrapper.WRAPPER);
// wrap("TokenConfig.prototype.activateListeners", lightMaskActivateListeners);

// ------ DefaultTokenConfig ----- //
libWrapper.register(MODULE_ID, "DefaultTokenConfig.prototype.activateListeners", lightMaskActivateListeners, libWrapper.WRAPPER);
// wrap("DefaultTokenConfig.prototype.activateListeners", lightMaskActivateListeners);

// ----- Light Source ----- //
Object.defineProperty(LightSource.prototype, "boundaryPolygon", {
value: boundaryPolygon,
writable: true,
configurable: true
});
addClassMethod(LightSource.prototype, "boundaryPolygon", boundaryPolygon);

// ----- Sound Source ----- //
libWrapper.register(MODULE_ID, "AmbientSound.prototype._refresh", _refreshAmbientSound, libWrapper.WRAPPER);
Object.defineProperty(SoundSource.prototype, "boundaryPolygon", {
value: boundaryPolygon,
writable: true,
configurable: true
});
addClassMethod(SoundSource.prototype, "boundaryPolygon", boundaryPolygon);

// ----- Sweep ----- //
libWrapper.register(MODULE_ID, "LightSource.prototype._getPolygonConfiguration", _getPolygonConfigurationLightSource, libWrapper.WRAPPER);
libWrapper.register(MODULE_ID, "SoundSource.prototype._getPolygonConfiguration", _getPolygonConfigurationSoundSource, libWrapper.WRAPPER);
libWrapper.register(MODULE_ID, "ClockwiseSweepPolygon.prototype._identifyEdges", identifyEdgesClockwiseSweepPolygon, libWrapper.MIXED, { perf_mode: libWrapper.PERF_FAST});
libWrapper.register(MODULE_ID, "ClockwiseSweepPolygon.prototype._compute", computeClockwiseSweep, libWrapper.WRAPPER, { perf_mode: libWrapper.PERF_FAST});
wrap("LightSource.prototype._getPolygonConfiguration", _getPolygonConfigurationLightSource);
wrap("SoundSource.prototype._getPolygonConfiguration", _getPolygonConfigurationSoundSource);
wrapMixed("ClockwiseSweepPolygon.prototype._identifyEdges", identifyEdgesClockwiseSweepPolygon, { perf_mode: libWrapper.PERF_FAST});
wrap("ClockwiseSweepPolygon.prototype._compute", computeClockwiseSweep, { perf_mode: libWrapper.PERF_FAST});
}

// ----- Light Source ----- //
Expand Down
96 changes: 87 additions & 9 deletions scripts/render.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,43 @@
/* globals
flattenObject,
foundry,
renderTemplate,
DefaultTokenConfig
*/

/* eslint no-unused-vars: ["error", { "argsIgnorePattern": "^_" }] */
"use strict";

import { log } from "./util.js";
import { FLAGS, MODULE_ID, TEMPLATES, HTML_INJECTION, SHAPE, CONFIG_BLOCK_IDS } from "./const.js";
import { onAddWallIDs, onCheckRelative } from "./customEdges.js";


/**
* Wrap activateListeners to catch when user clicks the button to add custom wall ids.
* @param {Application} application The Application instance being rendered
* @param {jQuery} html The inner HTML of the document that will be displayed and may be modified
* @param {object} data The object of data used when rendering the application
*/
export function lightMaskActivateListeners(wrapped, html) {
log(`lightMaskActivateListeners html[0] is length ${html[0].length}`, html, this);
export function renderAmbientLightConfigHook(app, html, data) {
injectAmbientLightConfiguration(app, html, data);
activateListeners(app, html);
}

export async function renderAmbientSoundConfigHook(app, html, data) {
injectAmbientSoundConfiguration(app, html, data);
activateListeners(app, html);
}

html.on("change", "#lightmaskshapes", shapeChanged.bind(this));
html.on("click", ".saveWallsButton", onAddWallIDs.bind(this));
html.on("click", ".lightmaskRelativeCheckbox", onCheckRelative.bind(this));
export function renderTokenConfigHook(app, html, data) {
injectTokenLightConfiguration(app, html, data);
activateListeners(app, html);
}

return wrapped(html);
/**
* Catch when user clicks the button to add custom wall ids, changes the shape, or clicks the checkbox.
*/
function activateListeners(app, html) {
html.on("change", "#lightmaskshapes", shapeChanged.bind(app));
html.on("click", ".saveWallsButton", onAddWallIDs.bind(app));
html.on("click", ".lightmaskRelativeCheckbox", onCheckRelative.bind(app));
}

function shapeChanged(event) {
Expand Down Expand Up @@ -115,3 +131,65 @@ async function injectConfiguration(app, html, data, type) {
const shape = data[d]?.flags?.lightmask?.shape;
if ( shape ) configShapeSubmenu(shape);
}

/**
* Hook updateAmbientLight to set render flag based on change to the config.
* @param {Document} document The existing Document which was updated
* @param {object} change Differential data that was used to update the document
* @param {DocumentModificationContext} options Additional options which modified the update request
* @param {string} userId The ID of the User who triggered the update workflow
*/
export function updateAmbientLightHook(doc, data, _options, _userId) {
const changeFlags = [
`flags.${MODULE_ID}.${FLAGS.SHAPE}`,
`flags.${MODULE_ID}.${FLAGS.SIDES}`,
`flags.${MODULE_ID}.${FLAGS.POINTS}`,
`flags.${MODULE_ID}.${FLAGS.RELATIVE}`,
`flags.${MODULE_ID}.${FLAGS.CUSTOM_WALLS.IDS}`,
`flags.${MODULE_ID}.${FLAGS.CUSTOM_WALLS.EDGES}`,
`flags.${MODULE_ID}.${FLAGS.ELLIPSE.MINOR}`
];

const changed = new Set(Object.keys(flattenObject(data)));
if ( changeFlags.some(k => changed.has(k)) ) doc.object.renderFlags.set({
refresh: true
});
}

export function updateAmbientSoundHook(doc, data, _options, _userId) {
const changeFlags = [
`flags.${MODULE_ID}.${FLAGS.SHAPE}`,
`flags.${MODULE_ID}.${FLAGS.SIDES}`,
`flags.${MODULE_ID}.${FLAGS.POINTS}`,
`flags.${MODULE_ID}.${FLAGS.ROTATION}`,
`flags.${MODULE_ID}.${FLAGS.RELATIVE}`,
`flags.${MODULE_ID}.${FLAGS.CUSTOM_WALLS.IDS}`,
`flags.${MODULE_ID}.${FLAGS.CUSTOM_WALLS.EDGES}`,
`flags.${MODULE_ID}.${FLAGS.ELLIPSE.MINOR}`
];

const changed = new Set(Object.keys(flattenObject(data)));
if ( changeFlags.some(k => changed.has(k)) ) doc.object.renderFlags.set({
refresh: true
});
}

export function updateTokenHook(doc, data, _options, _userId) {
const changeFlags = [
`flags.${MODULE_ID}.${FLAGS.SHAPE}`,
`flags.${MODULE_ID}.${FLAGS.SIDES}`,
`flags.${MODULE_ID}.${FLAGS.POINTS}`,
`flags.${MODULE_ID}.${FLAGS.ROTATION}`,
`flags.${MODULE_ID}.${FLAGS.RELATIVE}`,
`flags.${MODULE_ID}.${FLAGS.CUSTOM_WALLS.IDS}`,
`flags.${MODULE_ID}.${FLAGS.CUSTOM_WALLS.EDGES}`,
`flags.${MODULE_ID}.${FLAGS.ELLIPSE.MINOR}`
];

const changed = new Set(Object.keys(flattenObject(data)));
if ( changeFlags.some(k => changed.has(k)) ) {
doc.object.updateLightSource();
}
}


Loading

0 comments on commit a8376e6

Please sign in to comment.