use super::{ConstGmEvent, ConstGmObject, ConstGmObjectProperty, EventType};
use crate::{FilesystemPath, ResourceVersion, Tags, ViewPath};
use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
use smart_default::SmartDefault;
#[derive(Debug, Serialize, Deserialize, SmartDefault, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Object {
pub sprite_id: Option<FilesystemPath>,
pub solid: bool,
pub visible: bool,
pub sprite_mask_id: Option<FilesystemPath>,
pub persistent: bool,
pub parent_object_id: Option<FilesystemPath>,
pub physics_object: bool,
pub physics_sensor: bool,
pub physics_shape: usize,
pub physics_group: usize,
pub physics_density: f64,
pub physics_restitution: f64,
pub physics_linear_damping: f64,
pub physics_angular_damping: f64,
pub physics_friction: f64,
pub physics_start_awake: bool,
pub physics_kinematic: bool,
pub physics_shape_points: Vec<()>,
pub event_list: Vec<ObjectEvent>,
pub properties: Vec<ObjectProperty>,
pub overridden_properties: Vec<ObjectProperty>,
pub parent: ViewPath,
pub resource_version: ResourceVersion,
pub name: String,
pub tags: Tags,
pub resource_type: ConstGmObject,
}
#[derive(Debug, Serialize, Deserialize, SmartDefault, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ObjectEvent {
pub is_dn_d: bool,
#[serde(flatten)]
pub event_type: EventType,
pub collision_object_id: Option<FilesystemPath>,
pub parent: FilesystemPath,
pub resource_version: ResourceVersion,
#[serde(with = "serde_with::rust::string_empty_as_none")]
pub name: Option<String>,
pub tags: Tags,
pub resource_type: ConstGmEvent,
}
#[derive(Debug, Serialize, Deserialize, SmartDefault, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ObjectProperty {
pub var_type: ObjectPropertyTypes,
pub value: String,
pub range_enabled: bool,
pub range_min: f64,
pub range_max: f64,
pub list_items: Vec<String>,
pub multiselect: bool,
pub filters: serde_json::Value,
pub resource_version: ResourceVersion,
pub name: String,
pub tags: Tags,
pub resource_type: ConstGmObjectProperty,
}
#[derive(Debug, Serialize_repr, Deserialize_repr, SmartDefault, PartialEq, Clone)]
#[repr(u8)]
pub enum ObjectPropertyTypes {
#[default]
Real,
Integer,
String,
Boolean,
Expression,
Asset,
List,
Colour,
}
#[cfg(test)]
mod tests {
use crate::{object_yy::*, utils::TrailingCommaUtility, ViewPathLocation};
use include_dir::{include_dir, Dir, DirEntry};
use pretty_assertions::assert_eq;
#[test]
fn trivial_sprite_parsing() {
let all_objects: Dir = include_dir!("data/objects");
let tcu = TrailingCommaUtility::new();
for object_file in all_objects.find("**/*.yy").unwrap() {
if let DirEntry::File(file) = object_file {
println!("parsing {}", file.path);
let our_str = std::str::from_utf8(file.contents()).unwrap();
let our_str = tcu.clear_trailing_comma(our_str);
serde_json::from_str::<Object>(&our_str).unwrap();
}
}
}
#[test]
fn deep_equality() {
let object1 = include_str!("../../../data/objects/obj_animate_then_die.yy");
let parsed_object: Object =
serde_json::from_str(&TrailingCommaUtility::clear_trailing_comma_once(object1))
.unwrap();
let object = Object {
sprite_id: None,
solid: false,
visible: true,
sprite_mask_id: None,
persistent: false,
parent_object_id: None,
physics_object: false,
physics_sensor: false,
physics_shape: 1,
physics_group: 1,
physics_density: 0.5,
physics_restitution: 0.1,
physics_linear_damping: 0.1,
physics_angular_damping: 0.1,
physics_friction: 0.2,
physics_start_awake: true,
physics_kinematic: false,
physics_shape_points: vec![],
event_list: vec![ObjectEvent {
is_dn_d: false,
event_type: EventType::Other(OtherEvent::AnimationEnd),
collision_object_id: None,
parent: FilesystemPath::new("objects", "obj_animate_then_die"),
resource_version: ResourceVersion::default(),
name: None,
tags: vec![],
resource_type: ConstGmEvent::Const,
}],
properties: vec![],
overridden_properties: vec![],
parent: ViewPath {
name: "ui".to_string(),
path: ViewPathLocation("folders/Objects/ui.yy".to_owned()),
},
resource_version: ResourceVersion::default(),
name: "obj_animate_then_die".to_string(),
tags: vec![],
resource_type: ConstGmObject::Const,
};
assert_eq!(parsed_object, object);
}
}