use super::*;
use serde_json::{json, Value};
use std::process::Child;
#[derive(Debug, Default)]
pub struct LaunchProcess {
pub process: Option<Child>,
pub command: Option<Vec<String>>,
pub envs: Option<HashMap<String, String>>,
}
impl LaunchProcess {
pub fn process(child: Child) -> Self {
Self {
process: Some(child),
..Default::default()
}
}
pub fn command(mut self, arg: String) -> Self {
match self.command.as_mut() {
Some(args) => {
args.push(arg);
}
None => {
self.command = Some(vec![arg]);
}
};
self
}
pub fn envs(mut self, envs: HashMap<String, String>) -> Self {
self.envs = Some(envs);
self
}
fn command_as_str(&self) -> String {
if let Some(cmd) = &self.command {
cmd.join(" ")
} else {
String::from("None")
}
}
fn envs_as_str(&self) -> String {
if let Some(vars) = &self.envs {
format!("{:?}", vars)
} else {
String::from("None")
}
}
pub fn debug(&self) -> String {
format!(
"Command: {}\nEnvs: {}",
self.command_as_str(),
self.envs_as_str()
)
}
}
pub trait DccEngineEnv: fmt::Debug + Send + Sync {
fn launch_vanilla_maya(&self, project: &Project) -> AnyResult<LaunchProcess>;
fn launch_custom_maya(&self, project: &Project) -> AnyResult<LaunchProcess>;
fn launch_3ds_max(&self, project: &Project) -> AnyResult<LaunchProcess>;
fn launch_blender(&self, project: &Project) -> AnyResult<LaunchProcess>;
fn launch_zbrush(&self, project: &Project) -> AnyResult<LaunchProcess>;
fn launch_vanilla_mari(&self, project: &Project) -> AnyResult<LaunchProcess>;
fn launch_custom_mari(&self, project: &Project) -> AnyResult<LaunchProcess>;
fn launch_substance_painter(&self, project: &Project) -> AnyResult<LaunchProcess>;
fn launch_substance_designer(&self, project: &Project) -> AnyResult<LaunchProcess>;
fn launch_unity(&self, project: &Project) -> AnyResult<LaunchProcess>;
fn launch_unreal(&self, project: &Project) -> AnyResult<LaunchProcess>;
}
#[allow(dead_code)]
#[derive(Deserialize, Debug, Default)]
pub struct SkyHookResponse {
#[serde(rename = "ReturnValue")]
return_value: Vec<String>,
#[serde(rename = "Success")]
success: bool,
}
#[derive(Serialize, Default)]
pub struct SkyHookPayload {
#[serde(rename = "FunctionName")]
function_name: String,
#[serde(rename = "Parameters")]
param: Value,
}
impl SkyHookPayload {
pub fn ozone_script(num: u8, assets: HashSet<ProductionAsset>) -> AnyResult<Self> {
Ok(Self {
function_name: format!("ozone_script_{}", num),
..Default::default()
}
.selected_assets(assets)?)
}
pub fn selected_assets(mut self, assets: HashSet<ProductionAsset>) -> AnyResult<Self> {
self.param = json!({ "selected_assets": AssetRequestBuilder::new(assets).finish()? });
Ok(self)
}
pub fn with_str_params(mut self, param: &[(&str, &str)]) -> Self {
self.param = param
.iter()
.map(|(k, v)| (String::from(*k), String::from(*v)))
.collect();
self
}
pub fn echo_message(msg: &str) -> Self {
Self {
function_name: "echo_message".into(),
..Default::default()
}
.with_str_params(&[("message", msg)])
}
pub fn open_maya_scene(path: &Path) -> Self {
Self {
function_name: "open_scene".into(),
..Default::default()
}
.with_str_params(&[("path", &path.to_string_lossy().to_string())])
}
}
struct AssetRequestBuilder {
input: Vec<ProductionAsset>,
output: Vec<StandardAsset>,
}
impl AssetRequestBuilder {
fn new(assets: HashSet<ProductionAsset>) -> Self {
Self {
input: assets.into_iter().collect(),
output: vec![],
}
}
fn standard_assets(mut self) -> AnyResult<Self> {
let mut output = vec![];
while let Some(a) = self.input.pop() {
output.push(
a.inner_standard_owned()
.context("Unsupported inner type of ProductionAsset")?,
);
}
self.output = output;
Ok(self)
}
fn finish(mut self) -> AnyResult<Vec<StandardAsset>> {
self = self.standard_assets()?;
Ok(self.output)
}
}