Skip to content

Commit 55744f5

Browse files
committed
feat: ability to add additional events to filters and variables
1 parent 32cac69 commit 55744f5

3 files changed

Lines changed: 110 additions & 55 deletions

File tree

‎src/backend/events/filters/filter-manager.js‎

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,20 @@ const logger = require("../../logwrapper");
55
const EventEmitter = require("events");
66

77
class FilterManager extends EventEmitter {
8+
9+
#registeredFilters = [];
10+
11+
/**
12+
* @type {Record<string, Array<{ eventSourceId: string, eventId: string }>>}
13+
*/
14+
#additionalFilterEvents = {};
15+
816
constructor() {
917
super();
10-
11-
this._registeredFilters = [];
1218
}
1319

1420
registerFilter(filter) {
15-
const idConflict = this._registeredFilters.some(
21+
const idConflict = this.#registeredFilters.some(
1622
f => f.id === filter.id
1723
);
1824

@@ -26,27 +32,39 @@ class FilterManager extends EventEmitter {
2632
return;
2733
}
2834

29-
// TODO: validate the filter better
30-
31-
this._registeredFilters.push(filter);
35+
this.#registeredFilters.push(filter);
3236

3337
logger.debug(`Registered Event Filter ${filter.id}`);
3438

3539
this.emit("filterRegistered", filter);
3640
}
3741

42+
addEventToFilter(filterId, eventSourceId, eventId) {
43+
const additionalEvents = this.#additionalFilterEvents[filterId] ?? [];
44+
45+
additionalEvents.push({ eventSourceId, eventId });
46+
47+
this.#additionalFilterEvents[filterId] = additionalEvents;
48+
}
49+
3850
getFilterById(filterId) {
39-
return this._registeredFilters.find(f => f.id === filterId);
51+
return this.#registeredFilters.find(f => f.id === filterId);
4052
}
4153

4254
getAllFilters() {
43-
return this._registeredFilters;
55+
return this.#registeredFilters;
4456
}
4557

4658
getFiltersForEvent(eventSourceId, eventId) {
47-
const filters = this._registeredFilters
48-
.filter(f => f.events
49-
.some(e => e.eventSourceId === eventSourceId && e.eventId === eventId));
59+
const filters = this.#registeredFilters
60+
.filter((f) => {
61+
if (!f.events || f.events.length === 0) {
62+
return true;
63+
}
64+
const events = f.events;
65+
const additionalEvents = this.#additionalFilterEvents[f.id] ?? [];
66+
return [...events, ...additionalEvents].some(e => e.eventSourceId === eventSourceId && e.eventId === eventId);
67+
});
5068
return filters;
5169
}
5270

@@ -90,7 +108,7 @@ const manager = new FilterManager();
90108
ipcMain.on("getFiltersForEvent", (event, data) => {
91109
logger.info("got 'get all filters' request");
92110
const { eventSourceId, eventId } = data;
93-
event.returnValue = manager.getFiltersForEvent(eventSourceId, eventId).map(f => {
111+
event.returnValue = manager.getFiltersForEvent(eventSourceId, eventId).map((f) => {
94112
return {
95113
id: f.id,
96114
name: f.name,

‎src/backend/variables/replace-variable-manager.js‎

Lines changed: 68 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -10,83 +10,94 @@ const macroManager = require("./macro-manager");
1010
const frontendCommunicator = require("../common/frontend-communicator");
1111
const { getCustomVariable } = require("../common/custom-variable-manager");
1212
const util = require("../utility");
13+
class ReplaceVariableManager extends EventEmitter {
14+
#registeredVariableHandlers = new Map();
15+
#variableAndAliasHandlers = new Map();
16+
#registeredLookupHandlers = new Map();
17+
18+
/**
19+
* @type {Record<string, Array<{ eventSourceId: string, eventId: string }>>}
20+
*/
21+
additionalVariableEvents = {};
1322

14-
function preeval(options, variable) {
15-
if (!variable.triggers) {
16-
return;
23+
constructor() {
24+
super();
1725
}
1826

19-
const optionsTrigger = options.trigger || { type: null };
20-
const display = options.trigger.type ? options.trigger.type.toLowerCase() : "unknown trigger";
27+
#preeval(options, variable) {
28+
if (!variable.triggers) {
29+
return;
30+
}
2131

22-
const varTrigger = variable.triggers[optionsTrigger.type];
23-
if (varTrigger == null || varTrigger === false) {
24-
throw new ExpressionVariableError(
25-
`$${variable.handle} does not support being triggered by: ${display}`,
26-
variable.position,
27-
variable.handle
28-
);
29-
}
32+
const optionsTrigger = options.trigger || { type: null };
33+
const display = options.trigger.type ? options.trigger.type.toLowerCase() : "unknown trigger";
3034

31-
if (Array.isArray(varTrigger)) {
32-
if (!varTrigger.some((id) => id === options.trigger.id)) {
35+
const varTrigger = variable.triggers[optionsTrigger.type];
36+
if (varTrigger == null || varTrigger === false) {
3337
throw new ExpressionVariableError(
34-
`$${variable.handle} does not support this specific trigger type: ${display}`,
38+
`$${variable.handle} does not support being triggered by: ${display}`,
3539
variable.position,
3640
variable.handle
3741
);
3842
}
39-
}
40-
}
4143

42-
class ReplaceVariableManager extends EventEmitter {
43-
constructor() {
44-
super();
45-
this._registeredVariableHandlers = new Map();
46-
this._variableAndAliasHandlers = new Map();
47-
this._registeredLookupHandlers = new Map();
44+
if (Array.isArray(varTrigger)) {
45+
if (optionsTrigger.type === "event") {
46+
const additionalEvents = this.additionalVariableEvents[variable.handle]?.map(e => `${e.eventSourceId}:${e.eventId}`) ?? [];
47+
varTrigger.push(...additionalEvents);
48+
}
49+
if (!varTrigger.some(id => id === options.trigger.id)) {
50+
throw new ExpressionVariableError(
51+
`$${variable.handle} does not support this specific trigger type: ${display}`,
52+
variable.position,
53+
variable.handle
54+
);
55+
}
56+
}
4857
}
4958

5059
registerReplaceVariable(variable) {
51-
if (this._registeredVariableHandlers.has(variable.definition.handle)) {
60+
if (this.#registeredVariableHandlers.has(variable.definition.handle)) {
5261
throw new TypeError(`A variable with the handle ${variable.definition.handle} already exists.`);
5362
}
54-
this._registeredVariableHandlers.set(variable.definition.handle, {
63+
this.#registeredVariableHandlers.set(variable.definition.handle, {
5564
definition: variable.definition,
5665
handle: variable.definition.handle,
5766
argsCheck: variable.argsCheck,
5867
evaluator: variable.evaluator,
5968
triggers: variable.definition.triggers
6069
});
6170

62-
this._variableAndAliasHandlers = this._generateVariableAndAliasHandlers();
71+
this.#variableAndAliasHandlers = this._generateVariableAndAliasHandlers();
6372

6473
logger.debug(`Registered replace variable ${variable.definition.handle}`);
6574

6675
this.emit("replaceVariableRegistered", variable);
6776

6877
frontendCommunicator.send("replace-variable-registered", variable.definition);
6978
}
79+
7080
getReplaceVariables() {
7181
// Map register variables Map to array
72-
const registeredVariables = this._registeredVariableHandlers;
82+
const registeredVariables = this.#registeredVariableHandlers;
7383
const variables = [];
7484
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
7585
for (const [key, value] of registeredVariables) {
7686
variables.push(value);
7787
}
7888
return variables;
7989
}
90+
8091
getVariableHandlers() {
81-
return this._registeredVariableHandlers;
92+
return this.#registeredVariableHandlers;
8293
}
8394

8495
registerLookupHandler(prefix, lookup) {
85-
this._registeredLookupHandlers.set(prefix, lookup);
96+
this.#registeredLookupHandlers.set(prefix, lookup);
8697
}
8798

8899
_generateVariableAndAliasHandlers() {
89-
return Array.from(this._registeredVariableHandlers.entries()).reduce((map, [mainHandle, varConfig]) => {
100+
return Array.from(this.#registeredVariableHandlers.entries()).reduce((map, [mainHandle, varConfig]) => {
90101
map.set(mainHandle, varConfig);
91102
if (varConfig.definition.aliases) {
92103
varConfig.definition.aliases.forEach((alias) => {
@@ -103,12 +114,12 @@ class ReplaceVariableManager extends EventEmitter {
103114
evaluateText(input, metadata, trigger, onlyValidate) {
104115
if (input.includes("$")) {
105116
return expressionish({
106-
handlers: this._variableAndAliasHandlers,
117+
handlers: this.#variableAndAliasHandlers,
107118
expression: input,
108119
metadata,
109120
trigger,
110-
preeval,
111-
lookups: this._registeredLookupHandlers,
121+
preeval: (options, variable) => this.#preeval(options, variable),
122+
lookups: this.#registeredLookupHandlers,
112123
onlyValidate: !!onlyValidate
113124
});
114125
}
@@ -185,12 +196,22 @@ class ReplaceVariableManager extends EventEmitter {
185196

186197
return errors;
187198
}
199+
200+
addEventToVariable(variableHandle, eventSourceId, eventId) {
201+
const additionalEvents = this.additionalVariableEvents[variableHandle] ?? [];
202+
203+
additionalEvents.push({ eventSourceId, eventId });
204+
205+
this.additionalVariableEvents[variableHandle] = additionalEvents;
206+
207+
frontendCommunicator.send("additional-variable-events-updated", this.additionalVariableEvents);
208+
}
188209
}
189210

190211
const manager = new ReplaceVariableManager();
191212

192213
// custom variable shorthand
193-
manager.registerLookupHandler("$", (name) => ({
214+
manager.registerLookupHandler("$", name => ({
194215
evaluator: (trigger, ...path) => {
195216
let result = getCustomVariable(name);
196217
for (const item of path) {
@@ -204,7 +225,7 @@ manager.registerLookupHandler("$", (name) => ({
204225
}));
205226

206227
// Effect Output shorthand
207-
manager.registerLookupHandler("&", (name) => ({
228+
manager.registerLookupHandler("&", name => ({
208229
evaluator: (trigger, ...path) => {
209230
let result = trigger.effectOutputs;
210231
if (result != null) {
@@ -222,15 +243,15 @@ manager.registerLookupHandler("&", (name) => ({
222243
}));
223244

224245
// Preset effect Args shorthand
225-
manager.registerLookupHandler("#", (name) => ({
246+
manager.registerLookupHandler("#", name => ({
226247
evaluator: (trigger) => {
227248
const arg = (trigger.metadata?.presetListArgs || {})[name];
228249
return arg == null ? null : arg;
229250
}
230251
}));
231252

232253
// Macro Args shorthand
233-
manager.registerLookupHandler("^", (name) => ({
254+
manager.registerLookupHandler("^", name => ({
234255
evaluator: (trigger, ...args) => {
235256
const { macroArgs, macroNamedArgs } = trigger;
236257
if (
@@ -239,7 +260,7 @@ manager.registerLookupHandler("^", (name) => ({
239260
macroNamedArgs != null &&
240261
typeof name === "string"
241262
) {
242-
const namedArgIdx = macroNamedArgs.findIndex((item) => item === name);
263+
const namedArgIdx = macroNamedArgs.findIndex(item => item === name);
243264
if (namedArgIdx > -1) {
244265
return macroArgs[namedArgIdx];
245266
}
@@ -248,7 +269,7 @@ manager.registerLookupHandler("^", (name) => ({
248269
}));
249270

250271
// Macro shorthand
251-
manager.registerLookupHandler("%", (name) => ({
272+
manager.registerLookupHandler("%", name => ({
252273
evaluator: (trigger, ...macroArgs) => {
253274
const macro = macroManager.getMacroByName(name);
254275
if (macro != null) {
@@ -265,8 +286,8 @@ manager.registerLookupHandler("%", (name) => ({
265286
frontendCommunicator.on("getReplaceVariableDefinitions", () => {
266287
logger.debug("got 'get all vars' request");
267288
return Array.from(manager.getVariableHandlers().values())
268-
.map((v) => v.definition)
269-
.filter((v) => !v.hidden);
289+
.map(v => v.definition)
290+
.filter(v => !v.hidden);
270291
});
271292

272293
frontendCommunicator.onAsync("validateVariables", async (eventData) => {
@@ -283,4 +304,9 @@ frontendCommunicator.onAsync("validateVariables", async (eventData) => {
283304
return errors;
284305
});
285306

307+
frontendCommunicator.on("get-additional-variable-events", () => {
308+
logger.debug("got 'get-additional-variable-events' request");
309+
return manager.additionalVariableEvents;
310+
});
311+
286312
module.exports = manager;

‎src/gui/app/services/replace-variable.service.js‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,20 @@
1111
*/
1212
service.allVariables = backendCommunicator.fireEventSync("getReplaceVariableDefinitions");
1313

14+
service.additionalVariableEvents = backendCommunicator.fireEventSync("get-additional-variable-events");
15+
1416
service.triggerCache = {};
1517

1618
backendCommunicator.on("replace-variable-registered", (definition) => {
1719
service.allVariables.push(definition);
1820
service.triggerCache = {};
1921
});
2022

23+
backendCommunicator.on("additional-variable-events-updated", (additionalVariableEvents) => {
24+
service.additionalVariableEvents = additionalVariableEvents;
25+
service.triggerCache = {};
26+
});
27+
2128
/**
2229
* @param {{ dataOutput: "number" | "text"; type: string; id: string; }} triggerData
2330
*/
@@ -32,7 +39,7 @@
3239
return service.triggerCache[cacheKey];
3340
}
3441

35-
const filtered = service.allVariables.filter(v => {
42+
const filtered = service.allVariables.filter((v) => {
3643

3744
if (triggerData.dataOutput === "number") {
3845
if (v.possibleDataOutput == null || !v.possibleDataOutput.includes("number")) {
@@ -50,6 +57,10 @@
5057
}
5158

5259
if (Array.isArray(variableTrigger)) {
60+
if (triggerData.type === "event") {
61+
const additionalEvents = service.additionalVariableEvents[v.handle]?.map(e => `${e.eventSourceId}:${e.eventId}`) ?? [];
62+
variableTrigger.push(...additionalEvents);
63+
}
5364
if (variableTrigger.some(id => id === triggerData.id)) {
5465
return true;
5566
}

0 commit comments

Comments
 (0)