update dr rs

This commit is contained in:
shenjack 2023-06-25 21:21:18 +08:00
parent 5c299f4571
commit 0a264c603d
5 changed files with 70 additions and 176 deletions

View File

@ -21,8 +21,6 @@ if TYPE_CHECKING:
def part_list_read_test(file_name: Optional[str] = "./configs/PartList.xml") -> None: ...
def read_ship_test(path: Optional[str] = "./configs/dock1.xml") -> None: ...
def load_and_save_test(file_name: str): ...
class SR1PartType_rs:
@ -76,6 +74,9 @@ if TYPE_CHECKING:
@property
def flip_y(self) -> bool: ...
class SaveStatus_rs:
def __init__(self, save_default: Optional[bool] = False) -> None: ...
class SR1Ship_rs:
""" 用于高效且省内存的读取 SR1Ship """
def __init__(self, file_path = './configs/dock1.xml', part_list = './configs/PartList.xml', ship_name = 'NewShip'): ...
@ -93,7 +94,8 @@ if TYPE_CHECKING:
def get_part_box(self, part_id: int) -> Optional[Tuple[Tuple[int, int], Tuple[int, int]]]: ...
def as_dict(self) -> Dict[int, List[Tuple[SR1PartType_rs, SR1PartData]]]:
"""用于返回一个包含所有已连接零件的字典"""
def save(self, file_path: str, save_status: Optional[SaveStatus_rs] = None) -> None: ...
class Console_rs:
def __init__(self) -> None: ...
def start(self) -> None: ...

View File

@ -44,7 +44,6 @@ fn module_init(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(sr1_data::part_list::read_part_list_py, m)?)?;
m.add_function(wrap_pyfunction!(sr1_data::ship::py_raw_ship_from_file, m)?)?;
m.add_function(wrap_pyfunction!(python::data::load_and_save_test, m)?)?;
m.add_function(wrap_pyfunction!(python::serde_test::test_ship_read_and_write, m)?)?;
m.add_class::<python::data::PySR1Ship>()?;
m.add_class::<python::data::PySR1PartList>()?;
m.add_class::<python::data::PySR1PartType>()?;

View File

@ -13,9 +13,31 @@ pub mod data {
use crate::sr1_data::part_list::RawPartList;
use crate::types::math::{Point2D, Rotatable};
use crate::types::sr1::SaveStatus;
use crate::types::sr1::{get_max_box, SR1PartData, SR1PartListTrait};
use crate::types::sr1::{SR1PartList, SR1PartType, SR1Ship};
#[pyclass]
#[pyo3(name = "SaveStatus_rs")]
#[derive(Clone, Debug)]
pub struct PySaveStatus {
pub status: SaveStatus,
}
#[pymethods]
impl PySaveStatus {
#[new]
fn new(save_default: bool) -> Self {
Self {
status: SaveStatus::new(save_default),
}
}
}
impl Default for PySaveStatus {
fn default() -> Self { Self::new(false) }
}
#[pyclass]
#[pyo3(name = "SR1PartType_rs")]
pub struct PySR1PartType {
@ -200,8 +222,8 @@ pub mod data {
None
}
fn save(&self, file_path: String) -> PyResult<()> {
self.ship.save(file_path).unwrap();
fn save(&self, file_path: String, save_status: Option<PySaveStatus>) -> PyResult<()> {
self.ship.save(file_path, &save_status.unwrap_or_default().status).unwrap();
Ok(())
}
}
@ -285,156 +307,3 @@ pub mod console {
}
}
}
pub mod serde_test {
use pyo3::prelude::*;
use quick_xml::de::from_str;
use quick_xml::events::{BytesEnd, BytesStart, Event};
use quick_xml::reader::Reader;
use quick_xml::se::to_string;
use quick_xml::writer::Writer;
use serde::{Deserialize, Serialize};
use std::fs;
use std::io::Cursor;
type IdType = i64;
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename = "Ship")]
pub struct TestShip {
#[serde(rename = "@version")]
pub version: i32,
#[serde(rename = "@liftedOff")]
pub lift_off: i8,
#[serde(rename = "@touchingGround")]
pub touching_ground: i8,
#[serde(rename = "Connections")]
pub connections: Connections,
#[serde(rename = "DisconnectedParts")]
pub disconnected_parts: Option<DisconnectedParts>,
#[serde(rename = "Parts")]
pub parts: Parts,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct DisconnectedParts {
#[serde(rename = "DisconnectedPart")]
pub disconnected_part: Option<Vec<DisconnectedPart>>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct DisconnectedPart {
#[serde(rename = "Parts")]
pub parts: Parts,
#[serde(rename = "Connections")]
pub connections: Connections,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Connections {
#[serde(rename = "Connection")]
pub connection: Option<Vec<Connection>>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Connection {
#[serde(rename = "@parentAttachPoint")]
pub parent_attach_point: i32,
#[serde(rename = "@childAttachPoint")]
pub child_attach_point: i32,
#[serde(rename = "@parentPart")]
pub parent_part: IdType,
#[serde(rename = "@childPart")]
pub child_part: IdType,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Parts {
#[serde(rename = "Part")]
pub part: Vec<Part>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Tank {
#[serde(rename = "@fuel")]
pub fuel: f64,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Part {
#[serde(rename = "Tank")]
pub tank: Option<Tank>,
// #[serde(rename = "@Engine")]
// pub engine: Option<Engine>,
// #[serde(rename = "@Pod")]
// pub pod: Option<Pod>,
#[serde(rename = "@partType")]
pub part_type_id: String,
#[serde(rename = "@id")]
pub id: i64,
#[serde(rename = "@x")]
pub x: f64,
#[serde(rename = "@y")]
pub y: f64,
#[serde(rename = "@editorAngle")]
pub editor_angle: i32,
#[serde(rename = "@angle")]
pub angle: f64,
#[serde(rename = "@angleV")]
pub angle_v: f64,
#[serde(rename = "@flippedX")]
pub flip_x: Option<i8>,
#[serde(rename = "@flippedY")]
pub flip_y: Option<i8>,
#[serde(rename = "@chuteX")]
pub chute_x: Option<f64>,
#[serde(rename = "@chuteY")]
pub chute_y: Option<f64>,
#[serde(rename = "@chuteAngle")]
pub chute_angle: Option<f64>,
#[serde(rename = "@chuteHeight")]
pub chute_height: Option<f64>,
#[serde(rename = "@extension")]
pub extension: Option<f64>,
#[serde(rename = "@inflate")]
pub inflate: Option<i8>,
#[serde(rename = "@inflation")]
pub inflation: Option<f64>,
#[serde(rename = "@exploded")]
pub exploded: Option<i8>,
#[serde(rename = "@rope")]
pub rope: Option<i8>,
#[serde(rename = "@activated")]
pub activated: Option<i8>,
#[serde(rename = "@deployed")]
pub deployed: Option<i8>,
}
pub fn writer_write_test(ship_data: &TestShip) -> String {
let mut writer: Writer<Cursor<Vec<u8>>> = Writer::new(Cursor::new(Vec::new()));
// ship attr
let mut ship_elem = BytesStart::new("Ship");
ship_elem.push_attribute(("version", ship_data.version.to_string().as_str()));
ship_elem.push_attribute(("liftedOff", ship_data.lift_off.to_string().as_str()));
ship_elem.push_attribute(("touchingGround", ship_data.touching_ground.to_string().as_str()));
writer.write_event(Event::Start(ship_elem)).unwrap();
writer.write_event(Event::End(BytesEnd::new("Ship"))).unwrap();
let result: Vec<u8> = writer.into_inner().into_inner();
return String::from_utf8(result).unwrap();
}
#[pyfunction]
#[pyo3(name = "test_ship_read_and_write")]
pub fn test_ship_read_and_write(file_name: String) -> PyResult<()> {
let file = fs::read_to_string(file_name).unwrap();
let ship: TestShip = from_str(&file).unwrap();
let writer_string = writer_write_test(&ship);
fs::write("./writer-test.xml", writer_string).unwrap();
let save_string = to_string(&ship).unwrap();
fs::write("./test-xml-rs.xml", save_string).unwrap();
Ok(())
}
}

View File

@ -689,6 +689,15 @@ pub mod sr1 {
pub disconnected: Option<Vec<(Vec<SR1PartData>, Option<Vec<Connection>>)>>,
}
#[derive(Debug, Clone, Copy)]
pub struct SaveStatus {
pub save_default: bool,
}
impl SaveStatus {
pub fn new(save_default: bool) -> Self { SaveStatus { save_default } }
}
impl SR1Ship {
pub fn from_file(file_name: String, ship_name: Option<String>) -> Option<Self> {
// 首先验证文件是否存在 不存在则返回None
@ -737,33 +746,41 @@ pub mod sr1 {
result
}
pub fn save(&self, file_name: String) -> Option<()> {
pub fn save(&self, file_name: String, save_status: &SaveStatus) -> Option<()> {
use quick_xml::events::{BytesEnd, BytesStart, Event};
use quick_xml::writer::Writer;
use std::fs;
use std::io::Cursor;
macro_rules! option_push_attr {
($elem: ident, $test_block: block, $push: expr) => {
($elem: ident, $test_block: expr, $push: expr) => {
if ($test_block) {
$elem.push_attribute($push);
}
};
}
fn write_parts(parts: &Vec<SR1PartData>, writer: &mut Writer<Cursor<Vec<u8>>>) -> () {
fn write_parts(parts: &Vec<SR1PartData>, writer: &mut Writer<Cursor<Vec<u8>>>, save_status: &SaveStatus) {
writer.write_event(Event::Start(BytesStart::new("Parts"))).unwrap();
for part in parts.iter() {
let mut part_attr = BytesStart::new("Part");
part_attr.push_attribute(("type", part.part_type_id.as_str()));
part_attr.push_attribute(("x", part.x.to_string().as_str()));
part_attr.push_attribute(("y", part.y.to_string().as_str()));
part_attr.push_attribute(("id", part.id.to_string().as_str()));
part_attr.push_attribute(("type", part.part_type_id.as_str()));
part_attr.push_attribute(("editorAngle", part.editor_angle.to_string().as_str()));
part_attr.push_attribute(("angle", part.angle.to_string().as_str()));
part_attr.push_attribute(("angleV", part.angle_v.to_string().as_str()));
part_attr.push_attribute(("flippedX", part.flip_x.to_string().as_str()));
part_attr.push_attribute(("flippedY", part.flip_y.to_string().as_str()));
option_push_attr!(
part_attr,
part.flip_x && !save_status.save_default,
("flippedX", part.flip_x.to_string().as_str())
);
option_push_attr!(
part_attr,
part.flip_y && !save_status.save_default,
("flippedY", part.flip_y.to_string().as_str())
);
part_attr.push_attribute(("activated", part.active.to_string().as_str()));
writer.write_event(Event::Start(part_attr)).unwrap();
match part.part_type {
@ -785,7 +802,20 @@ pub mod sr1 {
writer.write_event(Event::End(BytesEnd::new("Parts"))).unwrap();
}
fn write_data(data: &SR1Ship) -> String {
fn write_connections(connects: &Vec<Connection>, writer: &mut Writer<Cursor<Vec<u8>>>, save_status: &SaveStatus) {
writer.write_event(Event::Start(BytesStart::new("Connections"))).unwrap();
for connect in connects.iter() {
let mut connect_elem = BytesStart::new("Connection");
connect_elem.push_attribute(("parentAttachPoint", connect.parent_attach_point.to_string().as_str()));
connect_elem.push_attribute(("childAttachPoint", connect.child_attach_point.to_string().as_str()));
connect_elem.push_attribute(("parentPart", connect.parent_part.to_string().as_str()));
connect_elem.push_attribute(("childPart", connect.child_part.to_string().as_str()));
writer.write_event(Event::Empty(connect_elem)).unwrap();
}
writer.write_event(Event::End(BytesEnd::new("Connections"))).unwrap();
}
fn write_data(data: &SR1Ship, save_status: &SaveStatus) -> String {
let mut writer: Writer<Cursor<Vec<u8>>> = Writer::new(Cursor::new(Vec::new()));
{
@ -796,15 +826,13 @@ pub mod sr1 {
ship_elem.push_attribute(("touchingGround", data.touch_ground.to_string().as_str()));
writer.write_event(Event::Start(ship_elem)).unwrap();
}
{
// Parts
write_parts(&data.parts, &mut writer);
}
write_parts(&data.parts, &mut writer, save_status);
write_connections(&data.connections, &mut writer, save_status);
writer.write_event(Event::End(BytesEnd::new("Ship"))).unwrap();
return String::from_utf8(writer.into_inner().into_inner()).unwrap();
}
fs::write(file_name, write_data(self)).unwrap();
fs::write(file_name, write_data(self, save_status)).unwrap();
Some(())
}
}

View File

@ -38,9 +38,7 @@ if TYPE_CHECKING:
if DR_mod_runtime.use_DR_rust:
from .Difficult_Rocket_rs import (SR1PartList_rs,
SR1Ship_rs,
load_and_save_test,
test_ship_read_and_write)
SR1Ship_rs)
logger = logging.getLogger('client.dr_game_sr1_ship')
sr_tr = Tr(lang_path=Path('./mods/dr_game/lang'))
@ -154,8 +152,6 @@ class SR1ShipRender(BaseScreen):
self.xml_name = file_path
if DR_mod_runtime.use_DR_rust:
try:
load_and_save_test(self.xml_name)
test_ship_read_and_write(self.xml_name)
self.rust_ship = SR1Ship_rs(file_path, 'configs/PartList.xml', 'a_new_ship')
print(self.rust_ship.name)
print(self.rust_ship.img_pos)