Skip to content

Commit

Permalink
Implement enum attributes (#470)
Browse files Browse the repository at this point in the history
  • Loading branch information
kennethloeffler authored Nov 1, 2024
1 parent 8ecd2fa commit d9f0841
Show file tree
Hide file tree
Showing 22 changed files with 335 additions and 25 deletions.
6 changes: 3 additions & 3 deletions docs/attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ This document describes the Attribute binary format. In this format there is no
- [Vector2](#vector2)
- [Vector3](#vector3)
- [CFrame](#cframe)
- [EnumItem](#EnumItem)
- [EnumItem](#enumitem)
- [NumberSequence](#numbersequence)
- [ColorSequence](#colorsequence)
- [NumberRange](#numberrange)
Expand All @@ -27,7 +27,7 @@ This document describes the Attribute binary format. In this format there is no

## Document Conventions

This document assumes a basic understanding of Rust's convention for numeric types. For example:
This document assumes a basic understanding of Rust's convention for numeric types. For example:

- `u32` is an unsigned 32-bit integer
- `f32` is a 32-bit floating point
Expand Down Expand Up @@ -189,7 +189,7 @@ Demonstrating the axis-aligned rotation matrix case, a `CFrame` with the value `
### EnumItem
**Type ID `0x15`**

The `EnumItem` type is composed of two parts:
The `EnumItem` type is composed of two parts:

| Field Name | Format | Value |
|:-----------|:--------------------|:-------------------------------------------------------|
Expand Down
12 changes: 6 additions & 6 deletions rbx_binary/src/serializer/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use ahash::{HashMap, HashMapExt, HashSetExt};
use rbx_dom_weak::{
types::{
Attributes, Axes, BinaryString, BrickColor, CFrame, Color3, Color3uint8, ColorSequence,
ColorSequenceKeypoint, Content, Enum, Faces, Font, MaterialColors, Matrix3, NumberRange,
NumberSequence, NumberSequenceKeypoint, PhysicalProperties, Ray, Rect, Ref,
ColorSequenceKeypoint, Content, Enum, EnumItem, Faces, Font, MaterialColors, Matrix3,
NumberRange, NumberSequence, NumberSequenceKeypoint, PhysicalProperties, Ray, Rect, Ref,
SecurityCapabilities, SharedString, Tags, UDim, UDim2, UniqueId, Variant, VariantType,
Vector2, Vector3, Vector3int16,
},
Expand Down Expand Up @@ -970,10 +970,10 @@ impl<'dom, 'db, W: Write> SerializerState<'dom, 'db, W> {
let mut buf = Vec::with_capacity(values.len());

for (i, rbx_value) in values {
if let Variant::Enum(value) = rbx_value.as_ref() {
buf.push(value.to_u32());
} else {
return type_mismatch(i, &rbx_value, "Enum");
match rbx_value.as_ref() {
Variant::Enum(value) => buf.push(value.to_u32()),
Variant::EnumItem(EnumItem { value, .. }) => buf.push(*value),
_ => return type_mismatch(i, &rbx_value, "Enum or EnumItem"),
}
}

Expand Down
1 change: 1 addition & 0 deletions rbx_binary/src/tests/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,5 @@ binary_tests! {
folder_with_font_attribute,
number_values_with_security_capabilities,
lighting_with_int32_attribute,
folder_with_enum_attribute,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
source: rbx_binary/src/tests/util.rs
expression: decoded_viewed
---
- referent: referent-0
name: Folder
class: Folder
properties:
Attributes:
Attributes:
AnEnumValue:
EnumItem:
type: Material
value: 512
Capabilities:
SecurityCapabilities: 0
Sandboxed:
Bool: false
SourceAssetId:
Int64: -1
Tags:
Tags: []
children: []
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
source: rbx_binary/src/tests/util.rs
expression: text_roundtrip
---
num_types: 1
num_instances: 1
chunks:
- Inst:
type_id: 0
type_name: Folder
object_format: 0
referents:
- 0
- Prop:
type_id: 0
prop_name: AttributesSerialize
prop_type: String
values:
- "\u0001\u0000\u0000\u0000\u000b\u0000\u0000\u0000AnEnumValue\u0015\b\u0000\u0000\u0000Material\u0000\u0002\u0000\u0000"
- Prop:
type_id: 0
prop_name: Capabilities
prop_type: SecurityCapabilities
values:
- 0
- Prop:
type_id: 0
prop_name: Name
prop_type: String
values:
- Folder
- Prop:
type_id: 0
prop_name: DefinesCapabilities
prop_type: Bool
values:
- false
- Prop:
type_id: 0
prop_name: SourceAssetId
prop_type: Int64
values:
- -1
- Prop:
type_id: 0
prop_name: Tags
prop_type: String
values:
- ""
- Prnt:
version: 0
links:
- - 0
- -1
- End
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
source: rbx_binary/src/tests/util.rs
expression: text_decoded
---
num_types: 1
num_instances: 1
chunks:
- Meta:
entries:
- - ExplicitAutoJoints
- "true"
- Inst:
type_id: 0
type_name: Folder
object_format: 0
referents:
- 0
- Prop:
type_id: 0
prop_name: AttributesSerialize
prop_type: String
values:
- "\u0001\u0000\u0000\u0000\u000b\u0000\u0000\u0000AnEnumValue\u0015\b\u0000\u0000\u0000Material\u0000\u0002\u0000\u0000"
- Prop:
type_id: 0
prop_name: Capabilities
prop_type: SecurityCapabilities
values:
- 0
- Prop:
type_id: 0
prop_name: DefinesCapabilities
prop_type: Bool
values:
- false
- Prop:
type_id: 0
prop_name: Name
prop_type: String
values:
- Folder
- Prop:
type_id: 0
prop_name: SourceAssetId
prop_type: Int64
values:
- -1
- Prop:
type_id: 0
prop_name: Tags
prop_type: String
values:
- ""
- Prnt:
version: 0
links:
- - 0
- -1
- End
13 changes: 13 additions & 0 deletions rbx_dom_lua/src/EncodedValue.lua
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,19 @@ types = {
end,
},

EnumItem = {
fromPod = function(pod)
return Enum[pod.type]:FromValue(pod.value)
end,

toPod = function(roblox)
return {
type = tostring(roblox.EnumType),
value = roblox.Value,
}
end,
},

Faces = {
fromPod = function(pod)
local faces = {}
Expand Down
15 changes: 15 additions & 0 deletions rbx_dom_lua/src/allValues.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
0.0
]
},
"TestEnumItem": {
"EnumItem": {
"type": "Material",
"value": 256
}
},
"TestNumber": {
"Float64": 1337.0
},
Expand Down Expand Up @@ -182,6 +188,15 @@
},
"ty": "Enum"
},
"EnumItem": {
"value": {
"EnumItem": {
"type": "Material",
"value": 256
}
},
"ty": "EnumItem"
},
"Faces": {
"value": {
"Faces": [
Expand Down
3 changes: 2 additions & 1 deletion rbx_dom_lua/test
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/bin/sh

cargo run --bin rbx_reflector values ./src/allValues.json
rojo build test-place.project.json -o TestPlace.rbxlx
run-in-roblox --script run-tests.lua --place TestPlace.rbxlx
run-in-roblox --script run-tests.lua --place TestPlace.rbxlx
23 changes: 19 additions & 4 deletions rbx_reflector/src/cli/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ use anyhow::bail;
use clap::Parser;
use rbx_types::{
Attributes, Axes, BinaryString, BrickColor, CFrame, Color3, Color3uint8, ColorSequence,
ColorSequenceKeypoint, Content, CustomPhysicalProperties, Enum, Faces, Font, MaterialColors,
Matrix3, NumberRange, NumberSequence, NumberSequenceKeypoint, PhysicalProperties, Ray, Rect,
Region3int16, Tags, TerrainMaterials, UDim, UDim2, Variant, VariantType, Vector2, Vector2int16,
Vector3, Vector3int16,
ColorSequenceKeypoint, Content, CustomPhysicalProperties, Enum, EnumItem, Faces, Font,
MaterialColors, Matrix3, NumberRange, NumberSequence, NumberSequenceKeypoint,
PhysicalProperties, Ray, Rect, Region3int16, Tags, TerrainMaterials, UDim, UDim2, Variant,
VariantType, Vector2, Vector2int16, Vector3, Vector3int16,
};
use serde::Serialize;

Expand Down Expand Up @@ -45,6 +45,13 @@ impl ValuesSubcommand {
"TestUDim2",
UDim2::new(UDim::new(1.0, 2), UDim::new(3.0, 4)),
)
.with(
"TestEnumItem",
EnumItem {
ty: "Material".into(),
value: 256,
},
)
.into(),
);
values.insert("Axes", Axes::all().into());
Expand Down Expand Up @@ -80,6 +87,14 @@ impl ValuesSubcommand {
);
values.insert("Content", Content::from("rbxassetid://12345").into());
values.insert("Enum", Enum::from_u32(1234).into());
values.insert(
"EnumItem",
EnumItem {
ty: "Material".into(),
value: 256,
}
.into(),
);
values.insert("Faces", Faces::all().into());
values.insert("Float32", 15.0f32.into());
values.insert("Float64", 15123.0f64.into());
Expand Down
2 changes: 2 additions & 0 deletions rbx_types/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
# 1.10.0 (2024-08-22)
* Add support for `Int32` values within `Attributes` ([#439])
* Add `len` and `is_empty` to `Tags` ([#438])
* Added support for `EnumItem` attributes. [#470]

[#470]: https://github.com/rojo-rbx/rbx-dom/pull/470
[#438]: https://github.com/rojo-rbx/rbx-dom/pull/438
[#439]: https://github.com/rojo-rbx/rbx-dom/pull/439

Expand Down
3 changes: 3 additions & 0 deletions rbx_types/src/attributes/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ pub(crate) enum AttributeError {
#[error(transparent)]
Io(#[from] std::io::Error),

#[error(transparent)]
Utf8(#[from] std::string::FromUtf8Error),

#[error(transparent)]
BadAttributeValue(#[from] crate::Error),

Expand Down
13 changes: 12 additions & 1 deletion rbx_types/src/attributes/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::{
};

use crate::{
BinaryString, BrickColor, CFrame, Color3, ColorSequence, ColorSequenceKeypoint, Font,
BinaryString, BrickColor, CFrame, Color3, ColorSequence, ColorSequenceKeypoint, EnumItem, Font,
FontStyle, FontWeight, Matrix3, NumberRange, NumberSequence, NumberSequenceKeypoint, Rect,
UDim, UDim2, Variant, VariantType, Vector2, Vector3,
};
Expand Down Expand Up @@ -202,6 +202,17 @@ pub(crate) fn read_attributes<R: Read>(
}
.into(),

VariantType::EnumItem => {
let enum_type = read_string(&mut value)?;
let value = read_u32(&mut value)?;

EnumItem {
ty: String::from_utf8(enum_type)?,
value,
}
}
.into(),

other => return Err(AttributeError::UnsupportedVariantType(other)),
};

Expand Down
2 changes: 1 addition & 1 deletion rbx_types/src/attributes/type_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ type_ids! {
// ??? => 0x12,
// ??? => 0x13,
CFrame => 0x14,
// ??? => 0x15,
EnumItem => 0x15,
// ??? => 0x16,
NumberSequence => 0x17,
// ??? => 0x18,
Expand Down
4 changes: 4 additions & 0 deletions rbx_types/src/attributes/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ pub(crate) fn write_attributes<W: Write>(
font.cached_face_id.as_deref().unwrap_or_default(),
)?;
}
Variant::EnumItem(enum_item) => {
write_string(&mut writer, &enum_item.ty)?;
write_u32(&mut writer, enum_item.value)?;
}

other_variant => unreachable!("variant {:?} was not implemented", other_variant),
}
Expand Down
Loading

0 comments on commit d9f0841

Please sign in to comment.