Remove double-loop nesting of WI key processing

This commit is contained in:
Wolfsblvt 2024-07-06 01:53:26 +02:00
parent b5f77a2164
commit 0b9431cd9a
1 changed files with 64 additions and 55 deletions

View File

@ -3693,76 +3693,85 @@ async function checkWorldInfo(chat, maxContext, isDryRun) {
continue;
}
// If selectiveLogic isn't found, assume it's AND, only do this once per entry
const selectiveLogic = entry.selectiveLogic ?? 0;
// Cache the text to scan before the loop, it won't change its content
const textToScan = buffer.get(entry, scanState);
primary: for (let key of entry.key) {
// PRIMARY KEYWORDS
let primaryKeyMatch = entry.key.find(key => {
const substituted = substituteParams(key);
return substituted && buffer.matchKeys(textToScan, substituted.trim(), entry);
});
if (substituted && buffer.matchKeys(textToScan, substituted.trim(), entry)) {
log('has match on primary keyword', substituted);
if (!primaryKeyMatch) {
// Don't write logs for simple no-matches
continue;
}
//selective logic begins
if (
entry.selective && //all entries are selective now
Array.isArray(entry.keysecondary) && //always true
entry.keysecondary.length //ignore empties
) {
log('has secondary keywords. Checking logic', Object.entries(world_info_logic).find(x => x[1] === entry.selectiveLogic));
let hasAnyMatch = false;
let hasAllMatch = true;
secondary: for (let keysecondary of entry.keysecondary) {
const secondarySubstituted = substituteParams(keysecondary);
const hasSecondaryMatch = secondarySubstituted && buffer.matchKeys(textToScan, secondarySubstituted.trim(), entry);
const hasSecondaryKeywords = (
entry.selective && //all entries are selective now
Array.isArray(entry.keysecondary) && //always true
entry.keysecondary.length //ignore empties
);
if (hasSecondaryMatch) {
hasAnyMatch = true;
}
if (!hasSecondaryKeywords) {
// Handle cases where secondary is empty
log('activated by primary key match', primaryKeyMatch);
activatedNow.add(entry);
continue;
}
if (!hasSecondaryMatch) {
hasAllMatch = false;
}
// Simplified AND ANY / NOT ALL if statement. (Proper fix for PR#1356 by Bronya)
// If AND ANY logic and the main checks pass OR if NOT ALL logic and the main checks do not pass
if ((selectiveLogic === world_info_logic.AND_ANY && hasSecondaryMatch) || (selectiveLogic === world_info_logic.NOT_ALL && !hasSecondaryMatch)) {
if (selectiveLogic === world_info_logic.AND_ANY) {
log('activated. (AND ANY) Found match secondary keyword', secondarySubstituted);
} else {
log('activated. (NOT ALL) Found not matching secondary keyword', secondarySubstituted);
}
activatedNow.add(entry);
break secondary;
}
}
// SECONDARY KEYWORDS
const selectiveLogic = entry.selectiveLogic ?? 0; // If selectiveLogic isn't found, assume it's AND, only do this once per entry
log('Entry with primary key match', primaryKeyMatch, 'has secondary keywords. Checking with logic logic', Object.entries(world_info_logic).find(x => x[1] === entry.selectiveLogic));
// Handle NOT ANY logic
if (selectiveLogic === world_info_logic.NOT_ANY && !hasAnyMatch) {
log('activated. (NOT ANY) No secondary keywords found', entry.keysecondary);
activatedNow.add(entry);
break primary;
}
/** @type {() => boolean} */
function matchSecondaryKeys() {
let hasAnyMatch = false;
let hasAllMatch = true;
for (let keysecondary of entry.keysecondary) {
const secondarySubstituted = substituteParams(keysecondary);
const hasSecondaryMatch = secondarySubstituted && buffer.matchKeys(textToScan, secondarySubstituted.trim(), entry);
// Handle AND ALL logic
if (selectiveLogic === world_info_logic.AND_ALL && hasAllMatch) {
log('activated. (AND ALL) All secondary keywords found', entry.keysecondary);
activatedNow.add(entry);
break primary;
}
if (hasSecondaryMatch) hasAnyMatch = true;
if (!hasSecondaryMatch) hasAllMatch = false;
log('skipped. Secondary keywords not satisfied', entry.keysecondary);
break primary;
} else {
// Handle cases where secondary is empty
log('activated by primary keyword', substituted);
activatedNow.add(entry);
break primary;
// Simplified AND ANY / NOT ALL if statement. (Proper fix for PR#1356 by Bronya)
// If AND ANY logic and the main checks pass OR if NOT ALL logic and the main checks do not pass
if (selectiveLogic === world_info_logic.AND_ANY && hasSecondaryMatch) {
log('activated. (AND ANY) Found match secondary keyword', secondarySubstituted);
return true;
}
if (selectiveLogic === world_info_logic.NOT_ALL && !hasSecondaryMatch) {
log('activated. (NOT ALL) Found not matching secondary keyword', secondarySubstituted);
return true;
}
}
// Handle NOT ANY logic
if (selectiveLogic === world_info_logic.NOT_ANY && !hasAnyMatch) {
log('activated. (NOT ANY) No secondary keywords found', entry.keysecondary);
return true;
}
// Handle AND ALL logic
if (selectiveLogic === world_info_logic.AND_ALL && hasAllMatch) {
log('activated. (AND ALL) All secondary keywords found', entry.keysecondary);
return true;
}
return false;
}
const matched = matchSecondaryKeys();
if (!matched) {
log('skipped. Secondary keywords not satisfied', entry.keysecondary);
continue;
}
// Success logging was already done inside the function, so just add the entry
activatedNow.add(entry);
continue;
}
console.debug(`[WI] Search done. Found ${activatedNow.size} possible entries.`);