oxygengine-core 0.44.0

Core module for Oxygengine
Documentation
use crate::{
    app::AppBuilder,
    ecs::pipeline::{PipelineBuilder, PipelineBuilderError},
};
pub use intuicio_essentials as intuicio;
use intuicio_essentials::core::{
    function::FunctionQuery, registry::Registry, struct_type::StructQuery,
};
use pest::Parser;
use serde::{Deserialize, Serialize};

#[allow(clippy::upper_case_acronyms)]
mod parser {
    #[derive(Parser)]
    #[grammar = "scripting.pest"]
    pub(super) struct ScriptReferenceParser;
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ScriptStructReference {
    #[serde(default)]
    pub module_name: Option<String>,
    pub name: String,
}

impl ScriptStructReference {
    pub fn query(&self) -> StructQuery {
        StructQuery {
            name: Some(self.name.as_str().into()),
            module_name: self.module_name.as_ref().map(|name| name.as_str().into()),
            ..Default::default()
        }
    }

    pub fn parse(content: &str) -> Result<Self, String> {
        match parser::ScriptReferenceParser::parse(parser::Rule::main_struct_reference, content) {
            Ok(mut ast) => {
                let mut ast = ast.next().unwrap().into_inner();
                let mut ast = ast.next().unwrap().into_inner();
                let a = ast.next().unwrap();
                let b = ast.next();
                let (module_name, name) = if let Some(b) = b {
                    (Some(a.as_str().to_owned()), b.as_str().to_owned())
                } else {
                    (None, a.as_str().to_owned())
                };
                Ok(Self { module_name, name })
            }
            Err(error) => Err(format!("{}", error)),
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ScriptFunctionReference {
    #[serde(default)]
    pub struct_type: Option<ScriptStructReference>,
    #[serde(default)]
    pub module_name: Option<String>,
    pub name: String,
}

impl ScriptFunctionReference {
    pub fn query(&self) -> FunctionQuery {
        FunctionQuery {
            struct_query: self
                .struct_type
                .as_ref()
                .map(|struct_type| struct_type.query()),
            name: Some(self.name.as_str().into()),
            module_name: self.module_name.as_ref().map(|name| name.as_str().into()),
            ..Default::default()
        }
    }

    pub fn parse(content: &str) -> Result<Self, String> {
        match parser::ScriptReferenceParser::parse(parser::Rule::main_function_reference, content) {
            Ok(mut ast) => {
                let mut ast = ast.next().unwrap().into_inner();
                let mut ast = ast.next().unwrap().into_inner();
                let a = ast.next().unwrap();
                let b = ast.next();
                let c = ast.next();
                let (struct_type, module_name, name) =
                    if a.as_rule() == parser::Rule::struct_reference {
                        let b = b.unwrap();
                        let struct_type = ScriptStructReference::parse(a.as_str())?;
                        if let Some(c) = c {
                            (
                                Some(struct_type),
                                Some(b.as_str().to_owned()),
                                c.as_str().to_owned(),
                            )
                        } else {
                            (Some(struct_type), None, b.as_str().to_owned())
                        }
                    } else if let Some(b) = b {
                        (None, Some(a.as_str().to_owned()), b.as_str().to_owned())
                    } else {
                        (None, None, a.as_str().to_owned())
                    };
                Ok(Self {
                    struct_type,
                    module_name,
                    name,
                })
            }
            Err(error) => Err(format!("{}", error)),
        }
    }
}

pub struct Scripting {
    pub registry: Registry,
}

impl Scripting {
    pub fn install(registry: &mut Registry) {
        *registry = std::mem::take(registry).with_basic_types();
    }
}

pub fn bundle_installer<PB>(
    builder: &mut AppBuilder<PB>,
    registry: Registry,
) -> Result<(), PipelineBuilderError>
where
    PB: PipelineBuilder,
{
    builder.install_resource(Scripting { registry });
    Ok(())
}