Skip to content

Commit

Permalink
Implement tick_action serialization.
Browse files Browse the repository at this point in the history
  • Loading branch information
kpreid committed Oct 7, 2023
1 parent c3146d5 commit 6609d74
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 26 deletions.
43 changes: 29 additions & 14 deletions all-is-cubes/src/save/conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ mod block {
use super::*;
use crate::block::{
AnimationChange, AnimationHint, Atom, Block, BlockAttributes, BlockCollision, Composite,
Modifier, Move, Primitive, Quote, RotationPlacementRule, Zoom,
Modifier, Move, Primitive, Quote, RotationPlacementRule, TickAction, Zoom,
};
use crate::math::{Rgb, Rgba};
use schema::{BlockSer, ModifierSer};
Expand Down Expand Up @@ -115,8 +115,8 @@ mod block {
}
}

impl From<&Primitive> for schema::PrimitiveSer {
fn from(value: &Primitive) -> Self {
impl<'a> From<&'a Primitive> for schema::PrimitiveSer<'a> {
fn from(value: &'a Primitive) -> Self {
match value {
Primitive::Indirect(definition) => schema::PrimitiveSer::IndirectV1 {
definition: definition.clone(),
Expand Down Expand Up @@ -148,8 +148,8 @@ mod block {
}
}

impl From<schema::PrimitiveSer> for Primitive {
fn from(value: schema::PrimitiveSer) -> Self {
impl<'a> From<schema::PrimitiveSer<'a>> for Primitive {
fn from(value: schema::PrimitiveSer<'a>) -> Self {
match value {
schema::PrimitiveSer::IndirectV1 { definition } => Primitive::Indirect(definition),
schema::PrimitiveSer::AtomV1 {
Expand Down Expand Up @@ -179,38 +179,53 @@ mod block {
}
}

impl From<&BlockAttributes> for schema::BlockAttributesV1Ser {
fn from(value: &BlockAttributes) -> Self {
impl<'a> From<&'a BlockAttributes> for schema::BlockAttributesV1Ser<'a> {
fn from(value: &'a BlockAttributes) -> Self {
let &BlockAttributes {
ref display_name,
selectable,
rotation_rule,
tick_action: _, // TODO: serialize tick_action once it is cleaner
ref tick_action,
animation_hint,
} = value;
schema::BlockAttributesV1Ser {
display_name: display_name.to_string(),
selectable,
rotation_rule: rotation_rule.into(),
tick_action: tick_action.as_ref().map(
|&TickAction {
ref operation,
period,
}| schema::TickActionSer {
operation: Cow::Borrowed(operation),
period,
},
),
animation_hint: animation_hint.into(),
}
}
}

impl From<schema::BlockAttributesV1Ser> for BlockAttributes {
fn from(value: schema::BlockAttributesV1Ser) -> Self {
impl<'a> From<schema::BlockAttributesV1Ser<'a>> for BlockAttributes {
fn from(value: schema::BlockAttributesV1Ser<'a>) -> Self {
// TODO: implement deserializing all attributes
let schema::BlockAttributesV1Ser {
display_name,
selectable,
rotation_rule,
tick_action,
animation_hint,
} = value;
Self {
display_name: display_name.into(),
selectable,
rotation_rule: rotation_rule.into(),
tick_action: None,
tick_action: tick_action.map(|schema::TickActionSer { operation, period }| {
TickAction {
operation: operation.into_owned(),
period,
}
}),
animation_hint: animation_hint.into(),
}
}
Expand Down Expand Up @@ -567,9 +582,9 @@ mod op {
S: Serializer,
{
match self {
op::Operation::Paint(brush) => {
schema::OperationSer::PaintV1 { blocks: brush.entries_for_serialization() }
}
op::Operation::Paint(brush) => schema::OperationSer::PaintV1 {
blocks: brush.entries_for_serialization(),
},
}
.serialize(serializer)
}
Expand Down
27 changes: 17 additions & 10 deletions all-is-cubes/src/save/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use alloc::borrow::Cow;
use alloc::string::String;
use alloc::sync::Arc;
use alloc::vec::Vec;
use core::num::NonZeroU16;

use ordered_float::NotNan;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -62,30 +63,30 @@ pub(crate) enum BehaviorV1Ser {

#[derive(Debug, Deserialize, Serialize)]
#[serde(tag = "type")]
pub(crate) enum BlockSer {
pub(crate) enum BlockSer<'a> {
BlockV1 {
primitive: PrimitiveSer,
primitive: PrimitiveSer<'a>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
modifiers: Vec<ModifierSer>,
},
}

#[derive(Debug, Deserialize, Serialize)]
#[serde(tag = "type")]
pub(crate) enum PrimitiveSer {
pub(crate) enum PrimitiveSer<'a> {
AirV1,
AtomV1 {
color: RgbaSer,
#[serde(default, skip_serializing_if = "is_default")]
light_emission: RgbSer,
#[serde(flatten)]
attributes: BlockAttributesV1Ser,
attributes: BlockAttributesV1Ser<'a>,
#[serde(default, skip_serializing_if = "is_default")]
collision: BlockCollisionSer,
},
RecurV1 {
#[serde(flatten)]
attributes: BlockAttributesV1Ser,
attributes: BlockAttributesV1Ser<'a>,
space: universe::URef<space::Space>,
#[serde(default, skip_serializing_if = "is_default")]
offset: [i32; 3],
Expand All @@ -97,15 +98,15 @@ pub(crate) enum PrimitiveSer {
}

#[derive(Debug, Deserialize, Serialize)]
pub(crate) struct BlockAttributesV1Ser {
pub(crate) struct BlockAttributesV1Ser<'a> {
#[serde(default, skip_serializing_if = "String::is_empty")]
pub display_name: String,
pub display_name: String, // TODO: Cow
#[serde(default = "return_true", skip_serializing_if = "is_true")]
pub selectable: bool,
#[serde(default, skip_serializing_if = "is_default")]
pub rotation_rule: RotationPlacementRuleSer,
// TODO: tick_action is a kludge but we should serialize it or its replacement
// pub(crate) tick_action: Option<VoxelBrush<'static>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub tick_action: Option<TickActionSer<'a>>,
#[serde(default, skip_serializing_if = "is_default")]
pub animation_hint: AnimationHintSer,
}
Expand Down Expand Up @@ -136,6 +137,12 @@ pub(crate) enum RotationPlacementRuleSer {
},
}

/// Unversioned because it's versioned by the parent struct
#[derive(Debug, Deserialize, Serialize)]
pub(crate) struct TickActionSer<'a> {
pub operation: Cow<'a, crate::op::Operation>,
pub period: NonZeroU16,
}
#[derive(Copy, Clone, Debug, PartialEq, Deserialize, Serialize)]
#[serde(tag = "type")]
pub(crate) enum AnimationHintSer {
Expand Down Expand Up @@ -231,7 +238,7 @@ pub(crate) enum InventorySer {
/// Not tagged since it will only appear inside an [`InventorySer`].
#[derive(Debug, Deserialize, Serialize)]
pub(crate) struct InvStackSer {
pub(crate) count: core::num::NonZeroU16,
pub(crate) count: NonZeroU16,
pub(crate) item: inv::Tool,
}

Expand Down
23 changes: 21 additions & 2 deletions all-is-cubes/src/save/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ use alloc::string::ToString;
use alloc::sync::Arc;
use alloc::vec::Vec;
use core::fmt;
use core::num::NonZeroU16;

use euclid::vec3;
use pretty_assertions::assert_eq;
use serde_json::{from_value, json, to_value};

use crate::{behavior, op};
use crate::block::{
self, AnimationChange, AnimationHint, Block, BlockDef, Modifier, Resolution, AIR,
};
Expand All @@ -23,6 +23,7 @@ use crate::space::{self, BlockIndex, LightPhysics, Space, SpacePhysics};
use crate::time::{self, Tick};
use crate::transaction::Transaction as _;
use crate::universe::{Name, PartialUniverse, URef, Universe};
use crate::{behavior, op};

#[track_caller]
/// Serialize and deserialize and assert the value is equal.
Expand Down Expand Up @@ -162,14 +163,17 @@ fn block_atom_default() {

#[test]
fn block_atom_with_all_attributes() {
// TODO: tick_action is not serialized yet,
assert_round_trip_value(
&Block::builder()
.color(Rgba::new(1.0, 0.5, 0.0, 0.5))
.collision(block::BlockCollision::None)
.display_name("foo")
.selectable(false)
.rotation_rule(block::RotationPlacementRule::Attach { by: Face6::PX })
.tick_action(Some(block::TickAction {
operation: op::Operation::Paint(VoxelBrush::new([([0, 0, 0], AIR)])),
period: NonZeroU16::new(3).unwrap(),
}))
.light_emission(Rgb::new(1.0, 0.0, 10.0))
.animation_hint(AnimationHint {
redefinition: AnimationChange::ColorSameCategory,
Expand All @@ -188,6 +192,21 @@ fn block_atom_with_all_attributes() {
"type": "AttachV1",
"by": "PX",
},
"tick_action": {
"period": 3,
"operation": {
"type": "PaintV1",
"blocks": [
[
[0, 0, 0],
{
"type": "BlockV1",
"primitive": {"type": "AirV1"},
}
]
]
}
},
"light_emission": [1.0, 0.0, 10.0],
"animation_hint": {
"type": "AnimationHintV1",
Expand Down

0 comments on commit 6609d74

Please sign in to comment.