From 6bf49304633fabd2d670a392c3ceb0becb177094 Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Sun, 19 Feb 2023 11:47:15 +0800 Subject: [PATCH] DR_rs --- Difficult_Rocket/__init__.py | 6 +- Difficult_Rocket/client/render/sr1_ship.py | 4 +- libs/Difficult_Rocket_rs/__init__.py | 4 + libs/Difficult_Rocket_rs/src/Cargo.lock | 18 ++- libs/Difficult_Rocket_rs/src/Cargo.toml | 6 +- libs/Difficult_Rocket_rs/src/src/lib.rs | 4 +- libs/Difficult_Rocket_rs/src/src/sr1_data.rs | 56 ++++++++ .../Difficult_Rocket_rs/src/src/sr1_render.rs | 11 +- libs/Difficult_Rocket_rs/src/src/types.rs | 126 +++++++++++------- 9 files changed, 178 insertions(+), 57 deletions(-) create mode 100644 libs/Difficult_Rocket_rs/src/src/sr1_data.rs diff --git a/Difficult_Rocket/__init__.py b/Difficult_Rocket/__init__.py index 5a08208..be6e1d9 100644 --- a/Difficult_Rocket/__init__.py +++ b/Difficult_Rocket/__init__.py @@ -22,9 +22,9 @@ from Difficult_Rocket.api.types import Options from libs.MCDR.version import Version -game_version = Version("0.7.0.2") # 游戏版本 +game_version = Version("0.7.0.3") # 游戏版本 build_version = Version("1.1.0.0") # 编译文件版本(与游戏本体无关) -DR_rust_version = Version("0.2.0.0") # DR 的 Rust 编写部分的版本 +DR_rust_version = Version("0.2.2.0") # DR 的 Rust 编写部分的版本 __version__ = game_version long_version: int = 12 @@ -78,7 +78,7 @@ class _DR_option(Options): if sys.platform != 'darwin': # MacOS 的测试只能在 Macos 上跑 self.pyglet_macosx_dev_test = False try: - from libs.Difficult_Rocket_rs import test_call, get_version_str + from libs.Difficult_Rocket_rs import test_call, get_version_str, xml_read_test test_call(self) print(f'DR_rust available: {get_version_str()}') except ImportError: diff --git a/Difficult_Rocket/client/render/sr1_ship.py b/Difficult_Rocket/client/render/sr1_ship.py index 2a0ead1..b1be2b6 100644 --- a/Difficult_Rocket/client/render/sr1_ship.py +++ b/Difficult_Rocket/client/render/sr1_ship.py @@ -185,9 +185,11 @@ class SR1ShipRender(BaseScreen): print(f'hey! warning! id{part.id}') self.part_data[part.id] = part # 调用生成器 减少卡顿 - with contextlib.suppress(GeneratorExit): + try: self.gen_draw = self.gen_sprite(self.part_data) next(self.gen_draw) + except GeneratorExit: + self.drawing = False self.need_draw = False if DR_option.use_DR_rust: diff --git a/libs/Difficult_Rocket_rs/__init__.py b/libs/Difficult_Rocket_rs/__init__.py index dc0cd44..6099a68 100644 --- a/libs/Difficult_Rocket_rs/__init__.py +++ b/libs/Difficult_Rocket_rs/__init__.py @@ -20,6 +20,10 @@ if TYPE_CHECKING: def get_version_str() -> str: ... def simluation() -> None: ... + """ 用来测试 rust 的物理模拟能不能用 """ + + def xml_read_test() -> None: ... + """ 用来测试 rust 的 xml 读取""" class PartDatas: """ 用于在 PyObj 里塞一个浓眉大眼的 HashMap""" diff --git a/libs/Difficult_Rocket_rs/src/Cargo.lock b/libs/Difficult_Rocket_rs/src/Cargo.lock index 3323090..1c78ccd 100644 --- a/libs/Difficult_Rocket_rs/src/Cargo.lock +++ b/libs/Difficult_Rocket_rs/src/Cargo.lock @@ -116,9 +116,10 @@ dependencies = [ [[package]] name = "difficult_rocket_rs" -version = "0.2.0" +version = "0.2.2" dependencies = [ "pyo3", + "quick-xml", "rapier2d-f64", ] @@ -171,6 +172,12 @@ dependencies = [ "rawpointer", ] +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + [[package]] name = "memoffset" version = "0.7.1" @@ -398,6 +405,15 @@ dependencies = [ "syn", ] +[[package]] +name = "quick-xml" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc053f057dd768a56f62cd7e434c42c831d296968997e9ac1f76ea7c2d14c41" +dependencies = [ + "memchr", +] + [[package]] name = "quote" version = "1.0.23" diff --git a/libs/Difficult_Rocket_rs/src/Cargo.toml b/libs/Difficult_Rocket_rs/src/Cargo.toml index de91553..af98091 100644 --- a/libs/Difficult_Rocket_rs/src/Cargo.toml +++ b/libs/Difficult_Rocket_rs/src/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "difficult_rocket_rs" -version = "0.2.0" +version = "0.2.2" edition = "2021" license-file = '../../LICENSE' # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -17,6 +17,10 @@ opt-level = 3 [profile.release] codegen-units = 1 +[dependencies.quick-xml] +version = "0.27.1" + + [dependencies.rapier2d-f64] version = "0.17.1" features = ["simd-stable"] diff --git a/libs/Difficult_Rocket_rs/src/src/lib.rs b/libs/Difficult_Rocket_rs/src/src/lib.rs index c6849ab..1eb3d0f 100644 --- a/libs/Difficult_Rocket_rs/src/src/lib.rs +++ b/libs/Difficult_Rocket_rs/src/src/lib.rs @@ -8,6 +8,7 @@ mod sr1_render; mod simulator; +mod sr1_data; mod render; mod types; @@ -15,7 +16,7 @@ use pyo3::prelude::*; #[pyfunction] fn get_version_str() -> String { - return String::from("0.2.0.0"); + return String::from("0.2.2.0"); } #[pyfunction] @@ -34,6 +35,7 @@ fn module_init(_py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(test_call, m)?)?; m.add_function(wrap_pyfunction!(sr1_render::better_update_parts, m)?)?; m.add_function(wrap_pyfunction!(simulator::simluation, m)?)?; + m.add_function(wrap_pyfunction!(sr1_data::read_xml, m)?)?; m.add_class::()?; m.add_class::()?; m.add_class::()?; diff --git a/libs/Difficult_Rocket_rs/src/src/sr1_data.rs b/libs/Difficult_Rocket_rs/src/src/sr1_data.rs new file mode 100644 index 0000000..9b32d35 --- /dev/null +++ b/libs/Difficult_Rocket_rs/src/src/sr1_data.rs @@ -0,0 +1,56 @@ +/* + * ------------------------------- + * Difficult Rocket + * Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com + * All rights reserved + * ------------------------------- + */ + +use pyo3::prelude::*; + +use quick_xml::events::Event; +use quick_xml::reader::Reader; + + +#[pyfunction] +#[pyo3(name = "xml_read_test")] +pub fn read_xml() { + let xml = r#" + Test + Test 2 + "#; + let mut reader = Reader::from_str(xml); + reader.trim_text(true); + + let mut count = 0; + let mut txt = Vec::new(); + let mut buf = Vec::new(); + + // The `Reader` does not implement `Iterator` because it outputs borrowed data (`Cow`s) + loop { + // NOTE: this is the generic case when we don't know about the input BufRead. + // when the input is a &str or a &[u8], we don't actually need to use another + // buffer, we could directly call `reader.read_event()` + match reader.read_event_into(&mut buf) { + Err(e) => panic!("Error at position {}: {:?}", reader.buffer_position(), e), + // exits the loop when reaching end of file + Ok(Event::Eof) => break, + + Ok(Event::Start(e)) => { + match e.name().as_ref() { + b"tag1" => println!("attributes values: {:?}", + e.attributes().map(|a| a.unwrap().value) + .collect::>()), + b"tag2" => count += 1, + _ => (), + } + } + Ok(Event::Text(e)) => txt.push(e.unescape().unwrap().into_owned()), + + // There are several other `Event`s we do not consider here + _ => (), + } + // if we don't keep a borrow elsewhere, we can clear the buffer to keep memory usage low + buf.clear(); + } +} \ No newline at end of file diff --git a/libs/Difficult_Rocket_rs/src/src/sr1_render.rs b/libs/Difficult_Rocket_rs/src/src/sr1_render.rs index 56b2cf8..190d52b 100644 --- a/libs/Difficult_Rocket_rs/src/src/sr1_render.rs +++ b/libs/Difficult_Rocket_rs/src/src/sr1_render.rs @@ -52,6 +52,15 @@ pub mod types { #[allow(non_snake_case)] pub fn part_data_to_SR1PartData(input: &PyAny) -> PyResult { + let connections = match input.getattr(intern!(input.py(), "connections")) { + Ok(ok) => { + ok.extract()? + } + _ => { + None + } + }; + return Ok(SR1PartData{ x: input.getattr(intern!(input.py(), "x"))?.extract()?, y: input.getattr(intern!(input.py(), "y"))?.extract()?, @@ -65,7 +74,7 @@ pub mod types { flip_y: input.getattr(intern!(input.py(), "flip_y"))?.extract()?, explode: input.getattr(intern!(input.py(), "explode"))?.extract()?, textures: input.getattr(intern!(input.py(), "textures"))?.extract()?, - connections: None + connections // connections: input.getattr(intern!(input.py(), "connections"))?.extract()?, }) } diff --git a/libs/Difficult_Rocket_rs/src/src/types.rs b/libs/Difficult_Rocket_rs/src/src/types.rs index 6c746b7..a33d722 100644 --- a/libs/Difficult_Rocket_rs/src/src/types.rs +++ b/libs/Difficult_Rocket_rs/src/src/types.rs @@ -6,47 +6,39 @@ * ------------------------------- */ -#[allow(dead_code)] -pub mod sr1 { - use std::collections::HashMap; +pub mod sr1 { pub fn map_ptype_textures(ptype: String) -> String { - let mut value_map: HashMap<&str, &str> = HashMap::with_capacity(27 * 2); - value_map.insert("pod-1", "Pod"); - value_map.insert("detacher-1", "DetacherVertical"); - value_map.insert("detacher-2", "DetacherRadial"); - value_map.insert("wheel-1", "Wheel"); - value_map.insert("wheel-2", "Wheel"); - value_map.insert("fuselage-1", "Fuselage"); - value_map.insert("strut-1", "Beam"); - value_map.insert("fueltank-0", "TankTiny"); - value_map.insert("fueltank-1", "TankSmall"); - value_map.insert("fueltank-2", "TankMedium"); - value_map.insert("fueltank-3", "TankLarge"); - value_map.insert("fueltank-4", "Puffy750"); - value_map.insert("fueltank-5", "SideTank"); - value_map.insert("engine-0", "EngineTiny"); - value_map.insert("engine-1", "EngineSmall"); - value_map.insert("engine-2", "EngineMedium"); - value_map.insert("engine-3", "EngineLarge"); - value_map.insert("engine-4", "SolidRocketBooster"); - value_map.insert("ion-0", "EngineIon"); - value_map.insert("parachute-1", "ParachuteCanister"); - value_map.insert("nosecone-1", "NoseCone"); - value_map.insert("rcs-1", "RcsBlock"); - value_map.insert("solar-1", "SolarPanelBase"); - value_map.insert("battery-0", "Battery"); - value_map.insert("dock-1", "DockingConnector"); - value_map.insert("port-1", "DockingPort"); - value_map.insert("lander-1", "LanderLegPreview"); - let result = value_map.get(ptype.as_str()); - match result { - None => "Pod".to_string(), - Some(i) => { - let i = *i; - i.to_string() - } - } + match ptype.as_str() { + "pod-1" => "Pod", + "detacher-1" => "DetacherVertical", + "detacher-2" => "DetacherRadial", + "wheel-1" => "Wheel", + "wheel-2" => "Wheel", + "fuselage-1" => "Fuselage", + "strut-1" => "Beam", + "fueltank-0" => "TankTiny", + "fueltank-1" => "TankSmall", + "fueltank-2" => "TankMedium", + "fueltank-3" => "TankLarge", + "fueltank-4" => "Puffy750", + "fueltank-5" => "SideTank", + "engine-0" => "EngineTiny", + "engine-1" => "EngineSmall", + "engine-2" => "EngineMedium", + "engine-3" => "EngineLarge", + "engine-4" => "SolidRocketBooster", + "ion-0" => "EngineIon", + "parachute-1" => "ParachuteCanister", + "nosecone-1" => "NoseCone", + "rcs-1" => "RcsBlock", + "solar-1" => "SolarPanelBase", + "battery-0" => "Battery", + "dock-1" => "DockingConnector", + "port-1" => "DockingPort", + "lander-1" => "LanderLegPreview", + _ => "Pod", + }.to_string() } pub struct SR1PartData { @@ -62,7 +54,7 @@ pub mod sr1 { pub flip_y: bool, pub explode: bool, pub textures: String, - pub connections: Option> + pub connections: Option> } } @@ -80,6 +72,7 @@ pub mod math { Point2D{x, y} } + #[inline] pub fn new_00() -> Self { Point2D { x: 0.0, y :0.0 } } #[inline] @@ -90,9 +83,19 @@ pub mod math { } #[inline] - pub fn get_op(&self) -> f64 { + pub fn distance_00(&self) -> f64 { self.distance(&Point2D::new(0.0, 0.0)) } + + #[inline] + pub fn rotate_angle(&self, angle: f64) -> Self { + let radius = angle.to_radians(); + let sin = radius.sin(); + let cos = radius.cos(); + let x = self.x * cos - self.y * sin; + let y = self.x * sin + self.y * cos; + Point2D{ x, y } + } } #[derive(Clone, Copy)] @@ -125,6 +128,39 @@ pub mod math { CircularArc{data: CircularArc}, } + #[derive(Clone)] + pub struct Shape { + pub pos: Point2D, + pub angle: f64, + // 旋转角度 角度值 + pub bounds: Vec + } + + impl Shape { + pub fn new(x: Option, y: Option, angle: Option, bounds: Vec) -> Self { + let x = x.unwrap_or(0.0); + let y = y.unwrap_or(0.0); + let angle = angle.unwrap_or(0.0); + Shape { pos: Point2D::new(x, y), angle, bounds } + } + + pub fn new_width_height(width: f64, height: f64, angle: Option) -> Self { + let d_width = width / 2.0; + let d_height = height / 2.0; + let mut edges: Vec = vec![ + Edge::OneTimeLine{data: OneTimeLine::pos_new(-d_width, -d_height, d_width, -d_height)}, + Edge::OneTimeLine{data: OneTimeLine::pos_new(d_width, -d_height, d_width, d_height)}, + Edge::OneTimeLine{data: OneTimeLine::pos_new(d_width, d_height, -d_width, d_height)}, + Edge::OneTimeLine{data: OneTimeLine::pos_new(-d_width, d_height, -d_width, -d_height)} + ]; + if let Some(angle) = angle { + + } + Shape { pos: Point2D::new_00(), angle: 0.0, bounds: edges} + } + } + + impl OneTimeLine { #[inline] pub fn pos_new(x1: f64, y1: f64, x2: f64, y2: f64) -> Self { @@ -194,14 +230,6 @@ pub mod dr { } - #[derive(Clone)] - pub struct Shape { - pub x: f64, - pub y: f64, - pub angle: f64, - // 旋转角度 角度值 - pub bounds: Vec - } #[derive(Clone, Copy)] pub enum PartType {