Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Rust] Use bitflags and box big enum variants to reduce size of types #109

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
# Next

- **[Change]** Match flag order for `DefineFont` and `DefineFontInfo`.

## Rust

- **[Breaking change]** Use bitflags instead of separate `bool` fields in `Bevel`, `ButtonCond`, `ButtonRecord`,
`ClipEventFlags`, `DefineDynamicText`, `DefineFont`, `DefineFontInfo`, `FileAttributes`, `Glow`, `GradientBevel`,
`GradientGlow`, `LineStyle` and `MorphLineStyle`.
- **[Breaking change]** Box big variants to reduce size of enums `FillStyle`, `MorphFillStyle`, `MorphShapeRecord`,
`ShapeRecord` and `Tag`.

# 0.14.0 (2022-05-07)

## Rust
Expand Down
14 changes: 14 additions & 0 deletions rs/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,18 @@ name = "swf_types"
path = "src/lib.rs"

[dependencies]
bitflags = "1.3.2"
hex = { version = "0.4.3", optional = true }
serde = { version = "1.0.137", optional = true, features = ["derive"] }
static_assertions = "1.1.0"
swf-fixed = "0.1.5"

[features]
# Serialization is enabled by default.
# Use `swf-types = { version = "...", default-features = false }` to disable it.
default = ["serde"]

# Adds implementation for `serde`'s `Serialiaze` and `Deserialize` traits.
# Adds implementation for `serde`'s `Serialize` and `Deserialize` traits.
serde = ["dep:serde", "dep:hex"]

[dev-dependencies]
Expand Down
61 changes: 61 additions & 0 deletions rs/src/bitflags.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@

macro_rules! serde_bitflags {
(
$(#[$outer:meta])*
$vis:vis struct $BitFlags:ident: $T:ty {
$(
#[serde(name = $serde:literal)]
$(#[$inner:ident $($args:tt)*])*
const $Flag:ident = $value:expr;
)*
}
) => {
::bitflags::bitflags! {
$(#[$outer])*
$vis struct $BitFlags: $T {
$(
$(#[$inner $($args)*])*
const $Flag = $value;
)*
}
}

#[cfg(feature = "serde")]
impl ::serde::Serialize for $BitFlags {
fn serialize<S: ::serde::Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
use ::serde::ser::SerializeStruct;

const NB_FLAGS: usize = [$($serde),*].len();
let mut map = ser.serialize_struct(stringify!($BitFlags), NB_FLAGS)?;
$(
map.serialize_field($serde, &self.contains($BitFlags::$Flag))?;
)*
map.end()
}
}

#[cfg(feature = "serde")]
impl<'de> ::serde::Deserialize<'de> for $BitFlags {
fn deserialize<D: ::serde::Deserializer<'de>>(de: D) -> Result<Self, D::Error> {
#[derive(::serde::Deserialize)]
#[allow(non_snake_case)]
struct $BitFlags {
$(
#[serde(rename = $serde)]
$Flag: bool,
)*
}

let flags = <$BitFlags as ::serde::Deserialize>::deserialize(de)?;

let mut out = Self::empty();
$(
if flags.$Flag {
out.insert(Self::$Flag);
}
)*
Ok(out)
}
}
}
}
53 changes: 40 additions & 13 deletions rs/src/button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@ use crate::{BlendMode, SoundInfo};
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ButtonRecord {
pub state_up: bool,
pub state_over: bool,
pub state_down: bool,
pub state_hit_test: bool,
#[cfg_attr(feature = "serde", serde(flatten))]
pub state: ButtonStates,
pub character_id: u16,
pub depth: u16,
pub matrix: Matrix,
Expand All @@ -23,6 +21,19 @@ pub struct ButtonRecord {
pub blend_mode: BlendMode,
}

serde_bitflags! {
pub struct ButtonStates: u8 {
#[serde(name = "state_up")]
const UP = 1 << 0;
#[serde(name = "state_over")]
const OVER = 1 << 1;
#[serde(name = "state_down")]
const DOWN = 1 << 2;
#[serde(name = "state_hit_test")]
const HIT_TEST = 1 << 3;
}
}

#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ButtonCondAction {
Expand All @@ -35,18 +46,34 @@ pub struct ButtonCondAction {
pub actions: Vec<u8>,
}

serde_bitflags! {
pub struct ButtonStateTransitions: u16 {
#[serde(name = "idle_to_over_up")]
const IDLE_TO_OVER_UP = 1 << 0;
#[serde(name = "over_up_to_idle")]
const OVER_UP_TO_IDLE = 1 << 1;
#[serde(name = "over_up_to_over_down")]
const OVER_UP_TO_OVER_DOWN = 1 << 2;
#[serde(name = "over_down_to_over_up")]
const OVER_DOWN_TO_OVER_UP = 1 << 3;
#[serde(name = "over_down_to_out_down")]
const OVER_DOWN_TO_OUT_DOWN = 1 << 4;
#[serde(name = "out_down_to_over_down")]
const OUT_DOWN_TO_OVER_DOWN = 1 << 5;
#[serde(name = "out_down_to_idle")]
const OUT_DOWN_TO_IDLE = 1 << 6;
#[serde(name = "idle_to_over_down")]
const IDLE_TO_OVER_DOWN = 1 << 7;
#[serde(name = "over_down_to_idle")]
const OVER_DOWN_TO_IDLE = 1 << 8;
}
}

#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ButtonCond {
pub idle_to_over_up: bool,
pub over_up_to_idle: bool,
pub over_up_to_over_down: bool,
pub over_down_to_over_up: bool,
pub over_down_to_out_down: bool,
pub out_down_to_over_down: bool,
pub out_down_to_idle: bool,
pub idle_to_over_down: bool,
pub over_down_to_idle: bool,
#[cfg_attr(feature = "serde", serde(flatten))]
pub transitions: ButtonStateTransitions,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub key_press: Option<u32>,
}
Expand Down
83 changes: 65 additions & 18 deletions rs/src/filters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,40 @@ use crate::fixed::{Sfixed16P16, Sfixed8P8};
use crate::float_is::Is;
use crate::gradient::ColorStop;

macro_rules! decl_filter_flags {
($(#[$meta:meta])* $vis:vis struct $name:ident;) => {
serde_bitflags! {
$(#[$meta])*
$vis struct $name: u8 {
#[serde(name = "composite_source")]
const COMPOSITE_SOURCE = 1 << 5;
#[serde(name = "knockout")]
const KNOCKOUT = 1 << 6;
#[serde(name = "inner")]
const INNER = 1 << 7;
}
}
}
}

macro_rules! decl_filter_flags_full {
($(#[$meta:meta])* $vis:vis struct $name:ident;) => {
serde_bitflags! {
$(#[$meta])*
$vis struct $name: u8 {
#[serde(name = "on_top")]
const ON_TOP = 1 << 4;
#[serde(name = "composite_source")]
const COMPOSITE_SOURCE = 1 << 5;
#[serde(name = "knockout")]
const KNOCKOUT = 1 << 6;
#[serde(name = "inner")]
const INNER = 1 << 7;
}
}
}
}

#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Blur {
Expand All @@ -24,13 +58,15 @@ pub struct Bevel {
pub angle: Sfixed16P16,
pub distance: Sfixed16P16,
pub strength: Sfixed8P8,
pub inner: bool,
pub knockout: bool,
pub composite_source: bool,
pub on_top: bool,
#[cfg_attr(feature = "serde", serde(flatten))]
pub flags: BevelFlags,
pub passes: u8,
}

decl_filter_flags_full! {
pub struct BevelFlags;
}

#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug)]
pub struct ColorMatrix {
Expand Down Expand Up @@ -82,25 +118,31 @@ pub struct DropShadow {
pub angle: Sfixed16P16,
pub distance: Sfixed16P16,
pub strength: Sfixed8P8,
pub inner: bool,
pub knockout: bool,
pub composite_source: bool,
#[cfg_attr(feature = "serde", serde(flatten))]
pub flags: DropShadowFlags,
pub passes: u8,
}

decl_filter_flags! {
pub struct DropShadowFlags;
}

#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Glow {
pub color: StraightSRgba8,
pub blur_x: Sfixed16P16,
pub blur_y: Sfixed16P16,
pub strength: Sfixed8P8,
pub inner: bool,
pub knockout: bool,
pub composite_source: bool,
#[cfg_attr(feature = "serde", serde(flatten))]
pub flags: GlowFlags,
pub passes: u8,
}

decl_filter_flags! {
pub struct GlowFlags;
}

#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct GradientBevel {
Expand All @@ -110,13 +152,15 @@ pub struct GradientBevel {
pub angle: Sfixed16P16,
pub distance: Sfixed16P16,
pub strength: Sfixed8P8,
pub inner: bool,
pub knockout: bool,
pub composite_source: bool,
pub on_top: bool,
#[cfg_attr(feature = "serde", serde(flatten))]
pub flags: GradientBevelFlags,
pub passes: u8,
}

decl_filter_flags_full! {
pub struct GradientBevelFlags;
}

#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct GradientGlow {
Expand All @@ -126,9 +170,12 @@ pub struct GradientGlow {
pub angle: Sfixed16P16,
pub distance: Sfixed16P16,
pub strength: Sfixed8P8,
pub inner: bool,
pub knockout: bool,
pub composite_source: bool,
pub on_top: bool,
#[cfg_attr(feature = "serde", serde(flatten))]
pub flags: GradientGlowFlags,
pub passes: u8,
}

decl_filter_flags_full! {
pub struct GradientGlowFlags;
}

Loading