gled-core 2.32.1

The engine of gled without a user interface: inputs, timing, rendering, Art-Net/DMX output and storage
Documentation
//! `/scene/...`: the addresses of a scene instance, which is the selected one,
//! a grid tile or a quick one, and the routing to what it does.

use rosc::OscMessage;

use super::args::{parse_f32, parse_index, parse_rgb, parse_u32, parse_uuid};
use super::effect::{parse_target_effect_action, parse_target_effect_curve_action};
use super::target::{
    parse_target_action, parse_target_curve_action, parse_target_input_action,
    parse_target_palette_overwrite_action,
};
use super::unknown_address;
use crate::action::UiAction;
use crate::storage::asset::project::scene_instance_path::{
    QuickSceneInstanceIndex, SceneInstanceUnion, selected_scene_instance_index,
};
use crate::storage::asset::scene::Scene;
use crate::storage::asset::scene::grid::GridLocation;
use crate::storage::asset_id::AssetId;

pub(super) fn parse_scene_message(msg: &OscMessage, path: &[&str]) -> Result<UiAction, ()> {
    match path {
        ["scene", "selected", "effect", "add"] => {
            Ok(UiAction::AddSceneEffect(selected_scene_instance_index()))
        }
        ["scene", "selected", "effect", effect_index, action] => {
            let effect_index = parse_index(effect_index)?;
            parse_target_effect_action(msg, selected_scene_instance_index(), effect_index, action)
        }
        [
            "scene",
            "selected",
            "effect",
            effect_index,
            curve_field,
            sub_action,
        ] if matches!(
            *curve_field,
            "opacity" | "color_shift" | "beat_progression" | "beat_offset"
        ) =>
        {
            let effect_index = parse_index(effect_index)?;
            parse_target_effect_curve_action(
                msg,
                selected_scene_instance_index(),
                effect_index,
                curve_field,
                sub_action,
            )
        }
        [
            "scene",
            "selected",
            "effect",
            effect_index,
            "config",
            "u32",
            config_index,
        ] => Ok(UiAction::SetSceneEffectAnimationConfigU32(
            selected_scene_instance_index(),
            parse_index(effect_index)?,
            parse_index(config_index)?,
            parse_u32(msg, 0)?,
        )),
        [
            "scene",
            "selected",
            "effect",
            effect_index,
            "config",
            "f32",
            config_index,
        ] => Ok(UiAction::SetSceneEffectAnimationConfigF32(
            selected_scene_instance_index(),
            parse_index(effect_index)?,
            parse_index(config_index)?,
            parse_f32(msg, 0)?,
        )),
        ["scene", "selected", "palette_overwrite", action] => {
            parse_target_palette_overwrite_action(msg, selected_scene_instance_index(), action)
        }
        [
            "scene",
            "selected",
            "palette_overwrite",
            "gradient",
            gradient_index,
        ] => Ok(UiAction::SetScenePaletteOverwriteGradient(
            selected_scene_instance_index(),
            parse_index(gradient_index)?,
            parse_rgb(msg)?,
        )),
        ["scene", "selected", input_kind, mode]
            if matches!(
                *input_kind,
                "activation_input" | "flash_input" | "dimmer_input"
            ) =>
        {
            parse_target_input_action(msg, selected_scene_instance_index(), input_kind, mode)
        }
        ["scene", "selected", curve_field, sub_action]
            if matches!(*curve_field, "opacity" | "beat_offset") =>
        {
            parse_target_curve_action(
                msg,
                selected_scene_instance_index(),
                curve_field,
                sub_action,
            )
        }
        ["scene", "selected", action] => {
            parse_target_action(msg, selected_scene_instance_index(), action)
        }

        ["scene", "grid", col, row, "add"] => {
            let location = parse_grid_location(col, row)?;
            let scene_id = parse_scene_id(msg, 0)?;
            Ok(UiAction::AddScene(location, scene_id))
        }
        ["scene", "grid", col, row, "effect", "add"] => {
            let location = parse_grid_location(col, row)?;
            Ok(UiAction::AddSceneEffect(SceneInstanceUnion::Grid(location)))
        }
        ["scene", "quick", index, "effect", "add"] => {
            let index = parse_quick_index(index)?;
            Ok(UiAction::AddSceneEffect(SceneInstanceUnion::Quick(
                QuickSceneInstanceIndex { index },
            )))
        }
        ["scene", "grid", col, row, "effect", effect_index, action] => {
            let location = parse_grid_location(col, row)?;
            let effect_index = parse_index(effect_index)?;
            let target = SceneInstanceUnion::Grid(location);
            parse_target_effect_action(msg, target, effect_index, action)
        }
        [
            "scene",
            "grid",
            col,
            row,
            "effect",
            effect_index,
            curve_field,
            sub_action,
        ] if matches!(
            *curve_field,
            "opacity" | "color_shift" | "beat_progression" | "beat_offset"
        ) =>
        {
            let location = parse_grid_location(col, row)?;
            let effect_index = parse_index(effect_index)?;
            parse_target_effect_curve_action(
                msg,
                SceneInstanceUnion::Grid(location),
                effect_index,
                curve_field,
                sub_action,
            )
        }
        [
            "scene",
            "grid",
            col,
            row,
            "effect",
            effect_index,
            "config",
            "u32",
            config_index,
        ] => {
            let location = parse_grid_location(col, row)?;
            Ok(UiAction::SetSceneEffectAnimationConfigU32(
                SceneInstanceUnion::Grid(location),
                parse_index(effect_index)?,
                parse_index(config_index)?,
                parse_u32(msg, 0)?,
            ))
        }
        [
            "scene",
            "grid",
            col,
            row,
            "effect",
            effect_index,
            "config",
            "f32",
            config_index,
        ] => {
            let location = parse_grid_location(col, row)?;
            Ok(UiAction::SetSceneEffectAnimationConfigF32(
                SceneInstanceUnion::Grid(location),
                parse_index(effect_index)?,
                parse_index(config_index)?,
                parse_f32(msg, 0)?,
            ))
        }
        ["scene", "grid", col, row, "palette_overwrite", action] => {
            let location = parse_grid_location(col, row)?;
            parse_target_palette_overwrite_action(msg, SceneInstanceUnion::Grid(location), action)
        }
        [
            "scene",
            "grid",
            col,
            row,
            "palette_overwrite",
            "gradient",
            gradient_index,
        ] => {
            let location = parse_grid_location(col, row)?;
            Ok(UiAction::SetScenePaletteOverwriteGradient(
                SceneInstanceUnion::Grid(location),
                parse_index(gradient_index)?,
                parse_rgb(msg)?,
            ))
        }
        ["scene", "grid", col, row, input_kind, mode]
            if matches!(
                *input_kind,
                "activation_input" | "flash_input" | "dimmer_input"
            ) =>
        {
            let location = parse_grid_location(col, row)?;
            parse_target_input_action(msg, SceneInstanceUnion::Grid(location), input_kind, mode)
        }
        ["scene", "grid", col, row, curve_field, sub_action]
            if matches!(*curve_field, "opacity" | "beat_offset") =>
        {
            let location = parse_grid_location(col, row)?;
            parse_target_curve_action(
                msg,
                SceneInstanceUnion::Grid(location),
                curve_field,
                sub_action,
            )
        }
        ["scene", "grid", col, row, action] => {
            let location = parse_grid_location(col, row)?;
            let target = SceneInstanceUnion::Grid(location);
            parse_target_action(msg, target, action)
        }
        ["scene", "quick", index, "effect", effect_index, action] => {
            let index = parse_quick_index(index)?;
            let effect_index = parse_index(effect_index)?;
            let target = SceneInstanceUnion::Quick(QuickSceneInstanceIndex { index });
            parse_target_effect_action(msg, target, effect_index, action)
        }
        [
            "scene",
            "quick",
            index,
            "effect",
            effect_index,
            curve_field,
            sub_action,
        ] if matches!(
            *curve_field,
            "opacity" | "color_shift" | "beat_progression" | "beat_offset"
        ) =>
        {
            let index = parse_quick_index(index)?;
            let effect_index = parse_index(effect_index)?;
            parse_target_effect_curve_action(
                msg,
                SceneInstanceUnion::Quick(QuickSceneInstanceIndex { index }),
                effect_index,
                curve_field,
                sub_action,
            )
        }
        [
            "scene",
            "quick",
            index,
            "effect",
            effect_index,
            "config",
            "u32",
            config_index,
        ] => {
            let index = parse_quick_index(index)?;
            Ok(UiAction::SetSceneEffectAnimationConfigU32(
                SceneInstanceUnion::Quick(QuickSceneInstanceIndex { index }),
                parse_index(effect_index)?,
                parse_index(config_index)?,
                parse_u32(msg, 0)?,
            ))
        }
        [
            "scene",
            "quick",
            index,
            "effect",
            effect_index,
            "config",
            "f32",
            config_index,
        ] => {
            let index = parse_quick_index(index)?;
            Ok(UiAction::SetSceneEffectAnimationConfigF32(
                SceneInstanceUnion::Quick(QuickSceneInstanceIndex { index }),
                parse_index(effect_index)?,
                parse_index(config_index)?,
                parse_f32(msg, 0)?,
            ))
        }
        ["scene", "quick", index, "palette_overwrite", action] => {
            let index = parse_quick_index(index)?;
            parse_target_palette_overwrite_action(
                msg,
                SceneInstanceUnion::Quick(QuickSceneInstanceIndex { index }),
                action,
            )
        }
        [
            "scene",
            "quick",
            index,
            "palette_overwrite",
            "gradient",
            gradient_index,
        ] => {
            let index = parse_quick_index(index)?;
            Ok(UiAction::SetScenePaletteOverwriteGradient(
                SceneInstanceUnion::Quick(QuickSceneInstanceIndex { index }),
                parse_index(gradient_index)?,
                parse_rgb(msg)?,
            ))
        }
        ["scene", "quick", index, input_kind, mode]
            if matches!(
                *input_kind,
                "activation_input" | "flash_input" | "dimmer_input"
            ) =>
        {
            let index = parse_quick_index(index)?;
            parse_target_input_action(
                msg,
                SceneInstanceUnion::Quick(QuickSceneInstanceIndex { index }),
                input_kind,
                mode,
            )
        }
        ["scene", "quick", index, curve_field, sub_action]
            if matches!(*curve_field, "opacity" | "beat_offset") =>
        {
            let index = parse_quick_index(index)?;
            parse_target_curve_action(
                msg,
                SceneInstanceUnion::Quick(QuickSceneInstanceIndex { index }),
                curve_field,
                sub_action,
            )
        }
        ["scene", "quick", index, action] => {
            let index = parse_quick_index(index)?;
            let target = SceneInstanceUnion::Quick(QuickSceneInstanceIndex { index });
            parse_target_action(msg, target, action)
        }
        ["scene", "reorder", from_col, from_row, to_col, to_row] => {
            let from = parse_grid_location(from_col, from_row)?;
            let to = parse_grid_location(to_col, to_row)?;
            Ok(UiAction::SwapScenes(from, to))
        }
        _ => unknown_address(msg),
    }
}

fn parse_grid_location(col: &str, row: &str) -> Result<GridLocation, ()> {
    let col = col.parse::<usize>().map_err(|_| ())?;
    let row = row.parse::<usize>().map_err(|_| ())?;
    Ok(GridLocation::new(col, row))
}

fn parse_quick_index(index: &str) -> Result<usize, ()> {
    let index = index.parse::<usize>().map_err(|_| ())?;
    Ok(index)
}

fn parse_scene_id(msg: &OscMessage, index: usize) -> Result<AssetId<Scene>, ()> {
    Ok(AssetId::from_uuid(parse_uuid(msg, index)?))
}