puppet opacity

This commit is contained in:
2026-08-29 19:11:49 +08:00
parent 55ed1f9d32
commit 7be507bff2
10 changed files with 131 additions and 27 deletions
+57 -16
View File
@@ -7,11 +7,14 @@ use tauri_specta::Event;
const SCENE_CONFIGURATION_ID: i64 = 1;
const MIN_PUPPET_SCALE: f64 = 0.5;
const MAX_PUPPET_SCALE: f64 = 2.0;
const MIN_PUPPET_OPACITY: f64 = 0.1;
const MAX_PUPPET_OPACITY: f64 = 1.0;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Type, sqlx::FromRow)]
#[serde(rename_all = "camelCase")]
pub struct SceneConfiguration {
pub puppet_scale: f64,
pub puppet_opacity: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize, Type, Event)]
@@ -22,7 +25,7 @@ pub struct SceneConfigurationChanged {
async fn get(database: &AppDatabase) -> Result<SceneConfiguration, sqlx::Error> {
sqlx::query_as::<_, SceneConfiguration>(
"SELECT puppet_scale FROM scene_configuration WHERE id = ?1",
"SELECT puppet_scale, puppet_opacity FROM scene_configuration WHERE id = ?1",
)
.bind(SCENE_CONFIGURATION_ID)
.fetch_one(database.pool())
@@ -40,13 +43,23 @@ async fn update(
"Puppet scale must be between {MIN_PUPPET_SCALE} and {MAX_PUPPET_SCALE}."
));
}
if !configuration.puppet_opacity.is_finite()
|| !(MIN_PUPPET_OPACITY..=MAX_PUPPET_OPACITY).contains(&configuration.puppet_opacity)
{
return Err(format!(
"Puppet opacity must be between {MIN_PUPPET_OPACITY} and {MAX_PUPPET_OPACITY}."
));
}
sqlx::query("UPDATE scene_configuration SET puppet_scale = ?1 WHERE id = ?2")
.bind(configuration.puppet_scale)
.bind(SCENE_CONFIGURATION_ID)
.execute(database.pool())
.await
.map_err(db::command_error)?;
sqlx::query(
"UPDATE scene_configuration SET puppet_scale = ?1, puppet_opacity = ?2 WHERE id = ?3",
)
.bind(configuration.puppet_scale)
.bind(configuration.puppet_opacity)
.bind(SCENE_CONFIGURATION_ID)
.execute(database.pool())
.await
.map_err(db::command_error)?;
get(database).await.map_err(db::command_error)
}
@@ -100,29 +113,57 @@ mod tests {
}
#[tokio::test]
async fn scene_configuration_defaults_to_unit_puppet_scale() {
async fn scene_configuration_defaults_preserve_the_current_appearance() {
let database = database().await;
assert_eq!(
get(&database).await.unwrap(),
SceneConfiguration { puppet_scale: 1.0 }
SceneConfiguration {
puppet_scale: 1.0,
puppet_opacity: 1.0,
}
);
}
#[tokio::test]
async fn puppet_scale_is_persisted_and_range_checked() {
async fn scene_configuration_is_persisted_and_range_checked() {
let database = database().await;
let configuration = update(&database, SceneConfiguration { puppet_scale: 1.5 })
.await
.expect("update scene configuration");
let configuration = update(
&database,
SceneConfiguration {
puppet_scale: 1.5,
puppet_opacity: 0.4,
},
)
.await
.expect("update scene configuration");
assert_eq!(configuration.puppet_scale, 1.5);
assert_eq!(configuration.puppet_opacity, 0.4);
assert_eq!(get(&database).await.unwrap(), configuration);
let error = update(&database, SceneConfiguration { puppet_scale: 2.1 })
.await
.expect_err("reject an out-of-range puppet scale");
let error = update(
&database,
SceneConfiguration {
puppet_scale: 2.1,
puppet_opacity: 0.4,
},
)
.await
.expect_err("reject an out-of-range puppet scale");
assert_eq!(error, "Puppet scale must be between 0.5 and 2.");
assert_eq!(get(&database).await.unwrap().puppet_scale, 1.5);
let error = update(
&database,
SceneConfiguration {
puppet_scale: 1.5,
puppet_opacity: 0.05,
},
)
.await
.expect_err("reject an out-of-range puppet opacity");
assert_eq!(error, "Puppet opacity must be between 0.1 and 1.");
assert_eq!(get(&database).await.unwrap().puppet_opacity, 0.4);
}
}