use std::io::Read; use rbx_dom_weak::WeakDom; mod rbx; mod mesh; mod primitives; pub mod data{ pub struct RobloxMeshBytes(Vec); impl RobloxMeshBytes{ pub fn new(bytes:Vec)->Self{ Self(bytes) } pub(crate) fn cursor(self)->std::io::Cursor>{ std::io::Cursor::new(self.0) } } } pub struct Model{ dom:WeakDom, } impl Model{ fn new(dom:WeakDom)->Self{ Self{dom} } pub fn into_place(self)->Place{ let Self{mut dom}=self; let context=roblox_emulator::context::Context::from_mut(&mut dom); let services=context.convert_into_place(); Place{dom,services} } } impl AsRef for Model{ fn as_ref(&self)->&WeakDom{ &self.dom } } pub struct Place{ dom:WeakDom, services:roblox_emulator::context::Services, } impl Place{ fn new(dom:WeakDom)->Option{ let context=roblox_emulator::context::Context::from_ref(&dom); Some(Self{ services:context.find_services()?, dom, }) } pub fn run_scripts(&mut self){ let Place{dom,services}=self; let runner=roblox_emulator::runner::Runner::new().unwrap(); let context=roblox_emulator::context::Context::from_mut(dom); let scripts=context.scripts(); let runnable=runner.runnable_context_with_services(context,services).unwrap(); for script in scripts{ if let Err(e)=runnable.run_script(script){ println!("runner error: {e}"); } } } } impl AsRef for Place{ fn as_ref(&self)->&WeakDom{ &self.dom } } #[derive(Debug)] pub enum ReadError{ RbxBinary(rbx_binary::DecodeError), RbxXml(rbx_xml::DecodeError), Io(std::io::Error), UnknownFileFormat, } impl std::fmt::Display for ReadError{ fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{ write!(f,"{self:?}") } } impl std::error::Error for ReadError{} pub fn read(input:R)->Result{ let mut buf=std::io::BufReader::new(input); let peek=std::io::BufRead::fill_buf(&mut buf).map_err(ReadError::Io)?; match &peek[0..8]{ b"rbx_binary::from_reader(buf).map(Model::new).map_err(ReadError::RbxBinary), b"rbx_xml::from_reader_default(buf).map(Model::new).map_err(ReadError::RbxXml), _=>Err(ReadError::UnknownFileFormat), } } //ConvertError pub fn convert( dom:impl AsRef, acquire_render_config_id:AcquireRenderConfigId, acquire_mesh_id:AcquireMeshId )->rbx::PartialMap1 where AcquireRenderConfigId:FnMut(Option<&str>)->strafesnet_common::model::RenderConfigId, AcquireMeshId:FnMut(&str)->strafesnet_common::model::MeshId, { rbx::convert(&dom.as_ref(),acquire_render_config_id,acquire_mesh_id) }