From e7ed0693a32e2c78d6f6e901f25922ec2a0ff6bc Mon Sep 17 00:00:00 2001 From: Tanish Manku <-h> Date: Fri, 21 Mar 2025 00:44:44 -0700 Subject: [PATCH] Add generation engine and signals --- .../realtime/src/KonvaApp/GenerationEngine.ts | 45 +++++++++++++++++++ .../signals/generation/generationSignals.ts | 45 +++++++++++++++++-- 2 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 frontend/realtime/src/KonvaApp/GenerationEngine.ts diff --git a/frontend/realtime/src/KonvaApp/GenerationEngine.ts b/frontend/realtime/src/KonvaApp/GenerationEngine.ts new file mode 100644 index 0000000000..b2058c0e68 --- /dev/null +++ b/frontend/realtime/src/KonvaApp/GenerationEngine.ts @@ -0,0 +1,45 @@ +import { invoke } from "@tauri-apps/api/core"; +import { + cancelGeneration, + finishGeneration, + onStartGeneration, +} from "~/signals/generation/generationSignals"; + +export class GenerationEngine { + private isGenerating = false; + + constructor() { + this.attachEventListeners(); + } + + private attachEventListeners() { + onStartGeneration((prompt) => { + this.invokeGeneration(prompt); + }); + } + + private async invokeGeneration(prompt: string) { + if (this.isGenerating) { + return; + } + + this.isGenerating = true; + console.log("Invoking generation for prompt:", prompt); + + try { + const base64BitmapResponse = await invoke("infer_image", { + prompt: prompt, + }); + + console.log("Generation finished with response:", base64BitmapResponse); + + const base64string = base64BitmapResponse as string; + finishGeneration(base64string); + } catch (error) { + console.error("Error during image processing:", error); + cancelGeneration(); + } finally { + this.isGenerating = false; + } + } +} diff --git a/frontend/realtime/src/signals/generation/generationSignals.ts b/frontend/realtime/src/signals/generation/generationSignals.ts index 49313698cc..7a04de74a6 100644 --- a/frontend/realtime/src/signals/generation/generationSignals.ts +++ b/frontend/realtime/src/signals/generation/generationSignals.ts @@ -1,4 +1,4 @@ -import { signal } from "@preact/signals-react"; +import { effect, signal } from "@preact/signals-react"; export enum GenerationLoadingState { INIT, @@ -6,8 +6,45 @@ export enum GenerationLoadingState { GENERATED, } +const initValue = { loadingState: GenerationLoadingState.INIT, prompt: "" }; + export const generationSignal = signal<{ - loadingState: GenerationLoadingState; - prompt: string; + loadingState: GenerationLoadingState; + prompt: string; imageB64?: string; -}>({ loadingState: GenerationLoadingState.INIT, prompt: "" }); \ No newline at end of file +}>(initValue); + +export const startGeneration = (prompt: string) => { + generationSignal.value = { + loadingState: GenerationLoadingState.GENERATING, + prompt, + imageB64: undefined, + }; +}; + +export const onStartGeneration = (callback: (prompt: string) => void) => { + effect(() => { + // If value just changed to GENERATING, notify the listeners + if ( + generationSignal.value.loadingState === GenerationLoadingState.GENERATING + ) { + callback(generationSignal.value.prompt); + } + }); +}; + +export const finishGeneration = (imageB64: string) => { + generationSignal.value = { + loadingState: GenerationLoadingState.GENERATED, + prompt: generationSignal.value.prompt, + imageB64, + }; +}; + +export const cancelGeneration = () => { + if ( + generationSignal.value.loadingState === GenerationLoadingState.GENERATING + ) { + generationSignal.value = initValue; + } +};