From 4c9c92e9c805cf671d8c6fc68344ce5b5ff6eb7d Mon Sep 17 00:00:00 2001
From: xModo99 <xmodo999@gmail.com>
Date: Sat, 16 Mar 2024 13:21:02 +0000
Subject: [PATCH] [Ai Art] Decouple SD client from cache control

---
 src/art/artJS.js                 |  2 +-
 src/art/genAI/openPose.js        |  4 ++--
 src/art/genAI/stableDiffusion.js | 35 ++++++++++++++++++++------------
 src/endWeek/nextWeek/nextWeek.js |  4 ++--
 src/gui/options/options.js       | 14 ++++++-------
 5 files changed, 34 insertions(+), 25 deletions(-)

diff --git a/src/art/artJS.js b/src/art/artJS.js
index 9973e60eb11..1cdb2551559 100644
--- a/src/art/artJS.js
+++ b/src/art/artJS.js
@@ -679,7 +679,7 @@ App.Art.aiArtElement = function(slave, imageSize, isEventImage = null) {
 	function updateAndRefresh(index = null) {
 		container.classList.add("refreshing");
 
-		App.Art.GenAI.client.updateSlave(slave, index, isEventImage).then(() => {
+		App.Art.GenAI.staticCache.updateSlave(slave, index, isEventImage).then(() => {
 			refresh();
 		}).catch(error => {
 			console.log(error.message || error);
diff --git a/src/art/genAI/openPose.js b/src/art/genAI/openPose.js
index e2bcaa6ab97..df339675474 100644
--- a/src/art/genAI/openPose.js
+++ b/src/art/genAI/openPose.js
@@ -17,7 +17,7 @@ App.Art.GenAI.getOpenPoseData = (function() {
 							.then(value => {
 								return value.text();
 							}).then(obj => {
-								return App.Art.GenAI.client.renderOpenPoseJSON(obj);
+								return App.Art.GenAI.sdClient.renderOpenPoseJSON(obj);
 							});
 					case "PNG":
 						return fetch(`resources/poses/${slave.custom.aiPose.filename}.png`)
@@ -49,7 +49,7 @@ App.Art.GenAI.getOpenPoseData = (function() {
 			throw new Error(`Could not find pose in library: ${name}`);
 		}
 		if (!entry.cache) {
-			entry.cache = await App.Art.GenAI.client.renderOpenPoseJSON(entry.poseData);
+			entry.cache = await App.Art.GenAI.sdClient.renderOpenPoseJSON(entry.poseData);
 		}
 		return entry.cache;
 	}
diff --git a/src/art/genAI/stableDiffusion.js b/src/art/genAI/stableDiffusion.js
index 48975e582bd..6e891f8eeb4 100644
--- a/src/art/genAI/stableDiffusion.js
+++ b/src/art/genAI/stableDiffusion.js
@@ -506,11 +506,26 @@ App.Art.GenAI.StableDiffusionClient = class {
 				return obj.images[0];
 			});
 	}
+};
+
+
+App.Art.GenAI.sdClient = new App.Art.GenAI.StableDiffusionClient();
+
+
+/**
+ * Determines whether the current passage has the "temporary-images" tag
+ * @returns {boolean}
+ */
+function isTemporaryImage() {
+	return $(`[data-tags*=temporary-images]`).length > 0;
+}
 
+
+App.Art.GenAI.StaticCaching = class {
 	/**
 	 * @param {FC.SlaveState} slave
 	 * @param {boolean | null} isEventImage - Whether request is canceled on passage change and which step setting to use. true => V.aiSamplingStepsEvent, false => V.aiSamplingSteps, null => chosen based on passage tags
-	 * @returns {Promise<string>} - Base 64 encoded image (could be a jpeg or png)
+	 * @returns {Promise<string>} - Base 64 encoded image (could be a jpeg, png, or webp)
 	 */
 	async fetchImageForSlave(slave, isEventImage = null) {
 		let steps = V.aiSamplingSteps;
@@ -519,17 +534,17 @@ App.Art.GenAI.StableDiffusionClient = class {
 			isEventImage = false;
 		}
 		if (isEventImage === null) {
-			isEventImage = this.isTemporaryImage();
+			isEventImage = isTemporaryImage();
 		}
 		if (isEventImage === true) {
 			steps = V.aiSamplingStepsEvent;
 		}
 
-		const settings = await this.buildStableDiffusionSettings(slave, steps);
+		const settings = await App.Art.GenAI.sdClient.buildStableDiffusionSettings(slave, steps);
 		const body = JSON.stringify(settings);
 		// set up a passage switch handler to clear queued generation of event and temporary images upon passage change
 		const oldHandler = App.Utils.PassageSwitchHandler.get();
-		if (isEventImage || this.isTemporaryImage()) {
+		if (isEventImage || isTemporaryImage()) {
 			App.Utils.PassageSwitchHandler.set(() => {
 				// find where this request is in the queue
 				let rIndex = App.Art.GenAI.sdQueue.queue.findIndex(r => r.slaveID === slave.ID && r.body === body);
@@ -593,17 +608,11 @@ App.Art.GenAI.StableDiffusionClient = class {
 			slave.custom.aiDisplayImageIdx = imagePreexisting;
 		}
 	}
-
-	/**
-	 * Determines whether the current passage has the "temporary-images" tag
-	 * @returns {boolean}
-	 */
-	isTemporaryImage() {
-		return $(`[data-tags*=temporary-images]`).length > 0;
-	}
 };
 
-App.Art.GenAI.client = new App.Art.GenAI.StableDiffusionClient();
+App.Art.GenAI.staticCache = new App.Art.GenAI.StaticCaching();
+
+
 
 /**
  * Search slave's existing images for a match with the new image.
diff --git a/src/endWeek/nextWeek/nextWeek.js b/src/endWeek/nextWeek/nextWeek.js
index 4cc2007b645..96013a19548 100644
--- a/src/endWeek/nextWeek/nextWeek.js
+++ b/src/endWeek/nextWeek/nextWeek.js
@@ -448,12 +448,12 @@ App.EndWeek.nextWeek = function() {
 		// executing this between DOM loads still picks up the "temporary-images" tag of the event passages, so we'll queue auto regeneration for a DOM to load without the tag. (We're not calling this from the "Main" passage to ensure it isn't over-called by reloading saves)
 		(async () => {
 			const sleep = () => new Promise(r => setTimeout(r, 100));
-			while (App.Art.GenAI.client.isTemporaryImage()) {
+			while (isTemporaryImage()) {
 				await sleep();
 			}
 			V.slaves.forEach(s => {
 				if ((V.week - s.weekAcquired) % V.aiAutoGenFrequency === 0){
-					App.Art.GenAI.client.updateSlave(s, null, false)
+					App.Art.GenAI.staticCache.updateSlave(s, null, false)
 						.catch(error => {
 							console.log(error.message || error);
 						});
diff --git a/src/gui/options/options.js b/src/gui/options/options.js
index 81973925685..d943c552a9b 100644
--- a/src/gui/options/options.js
+++ b/src/gui/options/options.js
@@ -1334,7 +1334,7 @@ App.UI.artOptions = function() {
 				}
 
 				const samplerListSpan = App.UI.DOM.makeElement('span', `Fetching options, please wait...`);
-				App.Art.GenAI.client.getSamplerList().then(list => {
+				App.Art.GenAI.sdClient.getSamplerList().then(list => {
 					if (list.length === 0) {
 						samplerListSpan.textContent = `Could not fetch valid samplers. Check your configuration.`;
 						samplerListSpan.classList.add('error');
@@ -1381,7 +1381,7 @@ App.UI.artOptions = function() {
 					.addComment("The width of the image.");
 
 				const rfCheckSpan = App.UI.DOM.makeElement('span', `Validating Restore Faces...`);
-				App.Art.GenAI.client.canRestoreFaces().then(result => {
+				App.Art.GenAI.sdClient.canRestoreFaces().then(result => {
 					if (result) {
 						if (V.aiAdetailerFace && V.aiRestoreFaces) {
 							rfCheckSpan.textContent = `Do not use Restore Faces and ADetailer Restore Face at the same time. Pick one.`;
@@ -1399,7 +1399,7 @@ App.UI.artOptions = function() {
 					.addComment(App.UI.DOM.combineNodes("Use a model to restore faces after the image has been generated. May result in 'samey' faces. ", rfCheckSpan));
 
 				const adCheckSpan = App.UI.DOM.makeElement('span', `Validating ADetailer setup...`);
-				App.Art.GenAI.client.hasAdetailer().then(result => {
+				App.Art.GenAI.sdClient.hasAdetailer().then(result => {
 					if (result) {
 						adCheckSpan.textContent = "";
 					} else {
@@ -1419,7 +1419,7 @@ App.UI.artOptions = function() {
 						.addComment("Scales the dimensions of the image by this factor. Defaults to 1.75.");
 
 					const upscalerListSpan = App.UI.DOM.makeElement('span', `Fetching options, please wait...`);
-					App.Art.GenAI.client.getUpscalerList().then(list => {
+					App.Art.GenAI.sdClient.getUpscalerList().then(list => {
 						if (list.length === 0) {
 							upscalerListSpan.textContent = `Could not fetch valid upscalers. Check your configuration.`;
 							upscalerListSpan.classList.add('error');
@@ -1436,7 +1436,7 @@ App.UI.artOptions = function() {
 				}
 
 				const opCheckSpan = App.UI.DOM.makeElement('span', `Validating ControlNet and OpenPose setup...`);
-				App.Art.GenAI.client.hasOpenPose().then(result => {
+				App.Art.GenAI.sdClient.hasOpenPose().then(result => {
 					if (result) {
 						opCheckSpan.textContent = "";
 					} else {
@@ -1449,7 +1449,7 @@ App.UI.artOptions = function() {
 					.addComment(App.UI.DOM.combineNodes(`Use the ControlNet extension's OpenPose module to strictly control slave poses. `, opCheckSpan));
 				if (V.aiOpenPose) {
 					const opModelList = App.UI.DOM.makeElement('span', `Fetching options, please wait...`);
-					App.Art.GenAI.client.getOpenPoseModelList().then(list => {
+					App.Art.GenAI.sdClient.getOpenPoseModelList().then(list => {
 						if (list.length === 0) {
 							opModelList.textContent = `Could not fetch valid OpenPose models. Check your configuration.`;
 							opModelList.classList.add('error');
@@ -1491,7 +1491,7 @@ App.UI.artOptions = function() {
 					})
 					.addButton("Regenerate images for all slaves", () => {
 						// queue all slaves for regeneration in the background
-						V.slaves.forEach(s => App.Art.GenAI.client.updateSlave(s)
+						V.slaves.forEach(s => App.Art.GenAI.staticCache.updateSlave(s)
 							.catch(error => {
 								console.log(error.message || error);
 							}));
-- 
GitLab