diff --git a/mods/dr_game/Difficult_Rocket_rs/__init__.py b/mods/dr_game/Difficult_Rocket_rs/__init__.py index b6bdab9..f2c200f 100644 --- a/mods/dr_game/Difficult_Rocket_rs/__init__.py +++ b/mods/dr_game/Difficult_Rocket_rs/__init__.py @@ -9,6 +9,9 @@ from .lib import * # noqa: F403 from typing import TYPE_CHECKING, Dict, Tuple, Optional, List if TYPE_CHECKING: + IdType = int + RawConnectionData = Tuple[int, int, IdType, IdType] + def get_version_str() -> str: """ 获取版本号 @@ -163,6 +166,42 @@ if TYPE_CHECKING: def __init__(self, save_default: Optional[bool] = False) -> None: ... + class SR1Connection_rs: # NOQA + """用于存储一堆连接的信息 + 同时提供了一些好用的 API + 至少总比你在那里吭哧吭哧在 Python 里搜快 + pub datas: Vec""" + + def search_connection_by_parent( + self, parent_id: IdType + ) -> List[RawConnectionData]: + """通过父节点搜索连接""" + ... + + def search_connection_by_child(self, child_id: IdType) -> List[RawConnectionData]: + """通过子节点搜索连接""" + ... + + def search_connection_by_id(self, any_id: IdType) -> List[RawConnectionData]: + """通过父子中任意一个 id 搜索连接""" + ... + + def search_by_both_id( + self, parent_id: IdType, child_id: IdType + ) -> List[RawConnectionData]: + """通过父子双方 id 获取连接 + + 保险起见, 我还是返回一个 Vec + + 万一真有 双/多 连接呢""" + ... + + def get_raw_data(self) -> List[RawConnectionData]: + """获取原始数据 + + 万一你确实需要吭哧吭哧去处理原始数据呢""" + ... + class SR1Ship_rs: # NOQA """用于高效且省内存的读取 SR1Ship""" @@ -206,11 +245,6 @@ if TYPE_CHECKING: """-x -y +x +y 左下右上""" ... - @property - def connection(self) -> List[Tuple[int, int, int, int]]: - """获取所有连接信息""" - ... - def get_part_box( self, part_id: int ) -> Optional[Tuple[Tuple[int, int], Tuple[int, int]]]: @@ -229,6 +263,10 @@ if TYPE_CHECKING: ) -> None: ... + def parts(self) -> SR1PartArray_rs: + """获取装在这个玩意里面的零件列表""" + ... + class Console_rs: # NOQA def __init__(self) -> None: ... diff --git a/mods/dr_game/Difficult_Rocket_rs/src/Cargo.lock b/mods/dr_game/Difficult_Rocket_rs/src/Cargo.lock index 1f8fa20..2dfcd59 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/Cargo.lock +++ b/mods/dr_game/Difficult_Rocket_rs/src/Cargo.lock @@ -146,7 +146,7 @@ dependencies = [ [[package]] name = "difficult_rocket_rs" -version = "0.3.3" +version = "0.3.4" dependencies = [ "anyhow", "dict_derive", diff --git a/mods/dr_game/Difficult_Rocket_rs/src/Cargo.toml b/mods/dr_game/Difficult_Rocket_rs/src/Cargo.toml index ea7b0bc..7672a93 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/Cargo.toml +++ b/mods/dr_game/Difficult_Rocket_rs/src/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "difficult_rocket_rs" -version = "0.3.3" +version = "0.3.4" edition = "2021" license-file = '../../LICENSE' authors = ["shenjackyuanjie <3695888@qq.com>"] diff --git a/mods/dr_game/Difficult_Rocket_rs/src/src/python/data.rs b/mods/dr_game/Difficult_Rocket_rs/src/src/python/data.rs index 051db48..dea68cb 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/src/python/data.rs +++ b/mods/dr_game/Difficult_Rocket_rs/src/src/python/data.rs @@ -5,7 +5,7 @@ use pyo3::prelude::*; use crate::dr_physics::math::{Point2D, Rotate}; use crate::sr1_parse::part_list::RawPartList; -use crate::sr1_parse::ship::RawShip; +use crate::sr1_parse::ship::{Connection, Connections, RawConnectionData, RawShip}; use crate::sr1_parse::SaveStatus; use crate::sr1_parse::{get_max_box, SR1PartData, SR1PartListTrait}; use crate::sr1_parse::{SR1PartList, SR1PartType, SR1Ship}; @@ -207,41 +207,47 @@ impl PySR1PartData { } #[pyclass] -#[derive(Clone, Debug)] -#[pyo3(name = "SR1PartTypeArrayIterator_rs")] -pub struct PySR1PartDataIterator { - pub datas: Vec<(PySR1PartType, PySR1PartData)>, - pub index: usize, +#[derive(Debug, Clone)] +#[pyo3(name = "SR1Connection_rs")] +pub struct PySR1Connections { + pub datas: Vec, } #[pymethods] -impl PySR1PartDataIterator { - fn __next__(mut slf: PyRefMut<'_, Self>) -> Option<(PySR1PartType, PySR1PartData)> { - if slf.index < slf.datas.len() { - slf.index += 1; - Some(slf.datas[slf.index - 1].clone()) - } else { - None - } +impl PySR1Connections { + /// 通过父节点获取连接 + fn search_connection_by_parent(&self, parent_id: IdType) -> Vec { + self.datas.iter().filter(|x| x.parent_part == parent_id).map(|x| x.as_raw_data()).collect() } -} - -/// 用来存一堆 PartData 的数组 -#[pyclass] -#[derive(Clone, Debug)] -#[pyo3(name = "SR1PartArray_rs")] -pub struct PySR1PartArray { - pub datas: Vec<(PySR1PartType, PySR1PartData)>, - pub part_list: SR1PartList, -} - -#[pymethods] -impl PySR1PartArray { - fn __iter__(&self) -> PySR1PartDataIterator { - PySR1PartDataIterator { - datas: self.datas.clone(), - index: 0, - } + /// 通过子节点获取连接 + fn search_by_child(&self, child_id: IdType) -> Vec { + self.datas.iter().filter(|x| x.child_part == child_id).map(|x| x.as_raw_data()).collect() + } + /// 通过父子中任意一个 id 搜索连接 + fn search_by_id(&self, any_id: IdType) -> Vec { + self.datas + .iter() + .filter(|x| x.parent_part == any_id || x.child_part == any_id) + .map(|x| x.as_raw_data()) + .collect() + } + /// 通过父子双方 id 获取连接 + /// + /// 保险期间, 我还是返回一个 Vec + /// + /// 万一真有 双/多 连接呢 + fn search_by_both_id(&self, parent_id: IdType, child_id: IdType) -> Vec { + self.datas + .iter() + .filter(|x| x.parent_part == parent_id && x.child_part == child_id) + .map(|x| x.as_raw_data()) + .collect() + } + /// 获取所有连接的原始数据 + /// + /// 万一你确实需要吭哧吭哧去处理原始数据呢 + fn get_raw_data(&self) -> Vec { + self.datas.iter().map(|x| x.as_raw_data()).collect() } } @@ -272,41 +278,28 @@ impl PySR1Ship { } } - fn parts(&self) -> PySR1PartArray { - let mut parts: Vec<(PySR1PartType, PySR1PartData)> = Vec::new(); - for part_data in self.ship.parts.iter() { - if let Some(part_type) = self.part_list.get_part_type(&part_data.part_type_id) { - let part_type = PySR1PartType::new(part_type.clone()); - let py_part_data = PySR1PartData::new(part_data.clone()); - parts.push((part_type, py_part_data)); - } - } - PySR1PartArray { - datas: parts, - part_list: self.part_list.clone(), - } - } - - fn disconnected_parts(&self) -> Vec { + fn disconnected_parts(&self) -> Vec<(Vec<(PySR1PartType, PySR1PartData)>, PySR1Connections)> { match self.ship.disconnected.as_ref() { Some(parts) => { if parts.is_empty() { return Vec::new(); } let mut result = Vec::with_capacity(parts.len()); - for (part_group, _) in parts.iter() { - let mut part_list = Vec::with_capacity(part_group.len()); + for (part_group, connections) in parts.iter() { + let mut group_parts = Vec::with_capacity(part_group.len()); for part_data in part_group.iter() { if let Some(part_type) = self.part_list.get_part_type(&part_data.part_type_id) { let part_type = PySR1PartType::new(part_type.clone()); let py_part_data = PySR1PartData::new(part_data.clone()); - part_list.push((part_type, py_part_data)); + group_parts.push((part_type, py_part_data)); } } - result.push(PySR1PartArray { - datas: part_list, - part_list: self.part_list.clone(), - }); + result.push(( + group_parts, + PySR1Connections { + datas: connections.clone().unwrap_or_default(), + }, + )); } result } @@ -357,18 +350,10 @@ impl PySR1Ship { mass } - #[getter] - fn get_connection(&self) -> Vec<(i32, i32, IdType, IdType)> { - let mut connections = Vec::new(); - for connect in self.ship.connections.iter() { - connections.push(( - connect.parent_attach_point, - connect.child_attach_point, - connect.parent_part, - connect.child_part, - )); + fn connections(&self) -> PySR1Connections { + PySR1Connections { + datas: self.ship.connections.clone(), } - connections } fn as_list(&self) -> Vec<(PySR1PartType, PySR1PartData)> { diff --git a/mods/dr_game/Difficult_Rocket_rs/src/src/sr1_parse/data_structure/ship.rs b/mods/dr_game/Difficult_Rocket_rs/src/src/sr1_parse/data_structure/ship.rs index f8da2a4..383f239 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/src/sr1_parse/data_structure/ship.rs +++ b/mods/dr_game/Difficult_Rocket_rs/src/src/sr1_parse/data_structure/ship.rs @@ -155,6 +155,8 @@ pub struct DisconnectedPart { pub connects: Connections, } +pub type RawConnectionData = (i32, i32, IdType, IdType); + #[derive(Debug, Serialize, Deserialize, Clone)] pub struct Connection { #[serde(rename = "@parentAttachPoint")] @@ -167,6 +169,18 @@ pub struct Connection { pub child_part: IdType, } +impl Connection { + /// 真有地方需要 + pub fn as_raw_data(&self) -> RawConnectionData { + ( + self.parent_attach_point, + self.child_attach_point, + self.parent_part, + self.child_part, + ) + } +} + impl SR1PartDataTrait for Part { fn to_sr_part_data(&self) -> SR1PartData { let attr = SR1PartDataAttr::from_raw(self, None, true);