mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-06 02:00:46 +00:00
Better events (Rust side)
This commit is contained in:
1 parent
9cf87cda5b
commit
e75e5624ed
13 files changed
+187
-53
No files matched your search
Vendored
+13
-4
@@ -1,6 +1,15 @@
|
||||
{
|
||||
"files.exclude": {
|
||||
"**/*~": true,
|
||||
"frontend_old/**": true
|
||||
}
|
||||
"files.exclude": {
|
||||
"**/*~": true,
|
||||
".sqlx/**": true,
|
||||
"_elasticsearch/**": true,
|
||||
"_sql/**": true,
|
||||
"frontend_old/**": true,
|
||||
"includes/**": true,
|
||||
"target/**": true,
|
||||
"test_data/**": true,
|
||||
"tmp/**": true,
|
||||
"virtualenv/**": true,
|
||||
"windows_dlls/**": true,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
use crate::core::events::sendable_event_error::SendableEventError;
|
||||
use log::info;
|
||||
use serde::Serialize;
|
||||
use tauri::{AppHandle, Emitter};
|
||||
|
||||
// Tagged enums here are waaay too "Rustic"
|
||||
// #[derive(Clone, Serialize)]
|
||||
// #[serde(rename_all = "camelCase", rename_all_fields = "camelCase", tag = "event", content = "data")]
|
||||
// pub enum BasicEvent<T: Serialize> {
|
||||
// Success(T),
|
||||
// Failure(T),
|
||||
// }
|
||||
|
||||
#[derive(Copy, Clone, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum BasicEventStatus {
|
||||
Success,
|
||||
Failure,
|
||||
}
|
||||
|
||||
/// Wrap the event with "status" and "data" fields.
|
||||
#[derive(Clone, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
struct BasicEventWrapper<T: Serialize> {
|
||||
status: BasicEventStatus,
|
||||
data: T,
|
||||
}
|
||||
|
||||
pub trait BasicSendableEvent : Serialize {
|
||||
/// This is the name of the event that the frontend subscribes to.
|
||||
const FRONTEND_EVENT_NAME: &'static str;
|
||||
|
||||
/// This is the status of the event: Success, Failure, etc.
|
||||
const EVENT_STATUS: BasicEventStatus;
|
||||
|
||||
/// Default implementation of send().
|
||||
/// This serializes and sends the event to the frontend.
|
||||
fn send(&self, app: &AppHandle) -> Result<(), SendableEventError> {
|
||||
info!("Sending event to frontend: {}", Self::FRONTEND_EVENT_NAME);
|
||||
let wrapped = BasicEventWrapper {
|
||||
status: Self::EVENT_STATUS,
|
||||
data: self.clone(),
|
||||
};
|
||||
let result = app.emit(Self::FRONTEND_EVENT_NAME, wrapped);
|
||||
if let Err(err) = result {
|
||||
return Err(SendableEventError::from(err));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug, Copy, Clone, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerationServiceName {
|
||||
Sora,
|
||||
Fal,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GenerationAction {
|
||||
GenerateImage,
|
||||
GenerateVideo,
|
||||
RemoveBackground,
|
||||
#[serde(rename = "image_to_3d")]
|
||||
ImageTo3d,
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
use crate::core::events::basic_sendable_event_trait::{BasicEventStatus, BasicSendableEvent};
|
||||
use crate::core::events::generation_events::common::{GenerationAction, GenerationServiceName};
|
||||
use serde_derive::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct GenerationCompleteEvent {
|
||||
pub service: GenerationServiceName,
|
||||
pub action: GenerationAction,
|
||||
}
|
||||
|
||||
impl BasicSendableEvent for GenerationCompleteEvent {
|
||||
const FRONTEND_EVENT_NAME: &'static str = "generation-complete-event";
|
||||
const EVENT_STATUS: BasicEventStatus = BasicEventStatus::Success;
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
use crate::core::events::basic_sendable_event_trait::{BasicEventStatus, BasicSendableEvent};
|
||||
use crate::core::events::generation_events::common::{GenerationAction, GenerationServiceName};
|
||||
use serde_derive::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct GenerationEnqueueFailureEvent {
|
||||
pub service: GenerationServiceName,
|
||||
pub action: GenerationAction,
|
||||
|
||||
/// User-facing reason for the failure, if available.
|
||||
pub reason: Option<String>,
|
||||
}
|
||||
|
||||
impl BasicSendableEvent for GenerationEnqueueFailureEvent {
|
||||
const FRONTEND_EVENT_NAME: &'static str = "generation-enqueue-failure-event";
|
||||
const EVENT_STATUS: BasicEventStatus = BasicEventStatus::Failure;
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
use crate::core::events::basic_sendable_event_trait::{BasicEventStatus, BasicSendableEvent};
|
||||
use crate::core::events::generation_events::common::{GenerationAction, GenerationServiceName};
|
||||
use serde_derive::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct GenerationEnqueueSuccessEvent {
|
||||
pub service: GenerationServiceName,
|
||||
pub action: GenerationAction,
|
||||
}
|
||||
|
||||
impl BasicSendableEvent for GenerationEnqueueSuccessEvent {
|
||||
const FRONTEND_EVENT_NAME: &'static str = "generation-enqueue-success-event";
|
||||
const EVENT_STATUS: BasicEventStatus = BasicEventStatus::Success;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
use crate::core::events::basic_sendable_event_trait::{BasicEventStatus, BasicSendableEvent};
|
||||
use crate::core::events::generation_events::common::{GenerationAction, GenerationServiceName};
|
||||
use serde_derive::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct GenerationFailedEvent {
|
||||
pub service: GenerationServiceName,
|
||||
pub action: GenerationAction,
|
||||
|
||||
/// User-facing reason for the failure, if available.
|
||||
pub reason: Option<String>,
|
||||
}
|
||||
|
||||
impl BasicSendableEvent for GenerationFailedEvent {
|
||||
const FRONTEND_EVENT_NAME: &'static str = "generation-failed-event";
|
||||
const EVENT_STATUS: BasicEventStatus = BasicEventStatus::Failure;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
pub mod common;
|
||||
pub mod generation_enqueue_failure_event;
|
||||
pub mod generation_enqueue_success_event;
|
||||
pub mod generation_complete_event;
|
||||
pub mod generation_failed_event;
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod notification_event;
|
||||
pub mod basic_sendable_event_trait;
|
||||
pub mod generation_events;
|
||||
pub mod sendable_event_error;
|
||||
pub mod sendable_event_trait;
|
||||
@@ -1,45 +0,0 @@
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Clone, Copy, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum NotificationModelType {
|
||||
ImageSegmentation,
|
||||
TextEncoder,
|
||||
TextTokenizer,
|
||||
Unet,
|
||||
Vae,
|
||||
Json,
|
||||
ClipEncoder,
|
||||
FluxModel,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum NotificationEvent<'a> {
|
||||
ModelDownloadStarted {
|
||||
model_name: &'a str,
|
||||
model_type: NotificationModelType,
|
||||
},
|
||||
ModelDownloadProgress {
|
||||
model_name: &'a str,
|
||||
model_type: NotificationModelType,
|
||||
currently_downloaded_bytes: usize,
|
||||
total_file_bytes: usize,
|
||||
},
|
||||
ModelDownloadComplete {
|
||||
model_name: &'a str,
|
||||
model_type: NotificationModelType,
|
||||
},
|
||||
ModelLoading {
|
||||
model_name: String,
|
||||
model_type: NotificationModelType,
|
||||
},
|
||||
ModelInference {
|
||||
model_name: String,
|
||||
model_type: NotificationModelType,
|
||||
},
|
||||
ModelInferenceComplete {
|
||||
model_name: String,
|
||||
model_type: NotificationModelType,
|
||||
},
|
||||
}
|
||||
@@ -1,15 +1,17 @@
|
||||
use log::info;
|
||||
use crate::core::events::sendable_event_error::SendableEventError;
|
||||
use log::info;
|
||||
use serde::Serialize;
|
||||
use tauri::{AppHandle, Emitter};
|
||||
|
||||
/// Implement this on a Serializable object to be able to send it as an event to the frontend.
|
||||
#[deprecated(note = "Use BasicSendableEvent instead as it wraps the event with status and data fields.")]
|
||||
pub trait SendableEvent : Serialize {
|
||||
/// This is the name of the event that the frontend subscribes to.
|
||||
const FRONTEND_EVENT_NAME: &'static str;
|
||||
|
||||
/// Default implementation of send().
|
||||
/// This serializes and sends the event to the frontend.
|
||||
#[deprecated(note = "Use BasicSendableEvent instead as it wraps the event with status and data fields.")]
|
||||
fn send(&self, app: &AppHandle) -> Result<(), SendableEventError> {
|
||||
info!("Sending event to frontend: {}", Self::FRONTEND_EVENT_NAME);
|
||||
let result = app.emit(Self::FRONTEND_EVENT_NAME, self);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use crate::core::events::sendable_event_trait::SendableEvent;
|
||||
use crate::core::state::data_dir::app_data_root::AppDataRoot;
|
||||
use crate::core::state::data_dir::trait_data_subdir::DataSubdir;
|
||||
use crate::core::utils::download_url_to_temp_dir::download_url_to_temp_dir;
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
use crate::core::commands::response::failure_response_wrapper::{CommandErrorResponseWrapper, CommandErrorStatus};
|
||||
use crate::core::commands::response::shorthand::Response;
|
||||
use crate::core::events::basic_sendable_event_trait::BasicSendableEvent;
|
||||
use crate::core::events::generation_events::common::{GenerationAction, GenerationServiceName};
|
||||
use crate::core::events::generation_events::generation_enqueue_success_event::GenerationEnqueueSuccessEvent;
|
||||
use crate::core::events::sendable_event_trait::SendableEvent;
|
||||
use crate::core::state::data_dir::app_data_root::AppDataRoot;
|
||||
use crate::core::state::data_dir::trait_data_subdir::DataSubdir;
|
||||
@@ -38,6 +41,7 @@ use storyteller_client::media_files::get_media_file::get_media_file;
|
||||
use storyteller_client::utils::api_host::ApiHost;
|
||||
use tauri::{AppHandle, Emitter, Manager, State};
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use crate::core::events::generation_events::generation_enqueue_failure_event::GenerationEnqueueFailureEvent;
|
||||
|
||||
const SORA_IMAGE_UPLOAD_TIMEOUT: Duration = Duration::from_millis(1000 * 30); // 30 seconds
|
||||
|
||||
@@ -122,13 +126,26 @@ pub async fn sora_image_remix_command(
|
||||
Err(err) => {
|
||||
error!("error: {:?}", err);
|
||||
|
||||
// TODO(bt,2025-05-28): Remove old event types
|
||||
let event = SoraImageEnqueueFailureEvent {};
|
||||
let result = event.send(&app);
|
||||
|
||||
if let Err(err) = result {
|
||||
error!("Failed to emit event: {:?}", err);
|
||||
}
|
||||
|
||||
|
||||
let event = GenerationEnqueueFailureEvent {
|
||||
service: GenerationServiceName::Sora,
|
||||
action: GenerationAction::GenerateImage,
|
||||
reason: None,
|
||||
};
|
||||
|
||||
let result = event.send(&app);
|
||||
|
||||
if let Err(err) = result {
|
||||
error!("Failed to emit event: {:?}", err);
|
||||
}
|
||||
|
||||
let mut status = CommandErrorStatus::ServerError;
|
||||
let mut error_type = SoraImageRemixErrorType::ServerError;
|
||||
let mut error_message = "A server error occurred. Please try again. If it continues, please tell our staff about the problem.";
|
||||
@@ -160,6 +177,7 @@ pub async fn sora_image_remix_command(
|
||||
})
|
||||
}
|
||||
Ok(_) => {
|
||||
// TODO(bt,2025-05-28): Remove old event types
|
||||
let event = SoraImageEnqueueSuccessEvent {};
|
||||
let result = event.send(&app);
|
||||
|
||||
@@ -167,6 +185,17 @@ pub async fn sora_image_remix_command(
|
||||
error!("Failed to emit event: {:?}", err);
|
||||
}
|
||||
|
||||
let event = GenerationEnqueueSuccessEvent {
|
||||
service: GenerationServiceName::Sora,
|
||||
action: GenerationAction::GenerateImage,
|
||||
};
|
||||
|
||||
let result = event.send(&app);
|
||||
|
||||
if let Err(err) = result {
|
||||
error!("Failed to emit event: {:?}", err);
|
||||
}
|
||||
|
||||
Ok(().into())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user