Refactor encoding logic in ChangeBatcher for improved readability and consistency

- Simplified the `isReadable` condition in `encodeService.lua` for better clarity.
- Updated float formatting functions in `json.rs` to enhance precision and consistency in numeric representation.
- Refactored handling of `AmbiguousValue` in `resolution.rs` to eliminate unnecessary type casting, improving data integrity.
- Cleaned up formatting in `serve.rs` and test files for better code readability.

These changes enhance the clarity and efficiency of the encoding and serialization processes, contributing to overall performance improvements.
This commit is contained in:
Joe 2026-02-18 09:47:50 -06:00
parent 3c026aea40
commit 0450dabfce
6 changed files with 47 additions and 51 deletions

View file

@ -35,8 +35,7 @@ return function(service: Instance)
continue
end
local isReadable = propertyMeta.scriptability == "ReadWrite"
or propertyMeta.scriptability == "Read"
local isReadable = propertyMeta.scriptability == "ReadWrite" or propertyMeta.scriptability == "Read"
local doesSerialize = propertyMeta.serialization ~= "DoesNotSerialize"
if isReadable and doesSerialize then

View file

@ -151,7 +151,13 @@ fn build_dom_from_chunks(payload: SyncbackPayload) -> anyhow::Result<WeakDom> {
let mut cloned = Vec::new();
for &child_ref in chunk_dom.root().children() {
deep_clone_into(&chunk_dom, &mut dom, child_ref, root_ref, &mut global_ref_map);
deep_clone_into(
&chunk_dom,
&mut dom,
child_ref,
root_ref,
&mut global_ref_map,
);
let new_ref = *global_ref_map.get(&child_ref).unwrap();
cloned.push(new_ref);
}
@ -214,10 +220,9 @@ fn build_dom_from_chunks(payload: SyncbackPayload) -> anyhow::Result<WeakDom> {
for (service_ref, ref_entries) in deferred_refs {
for (prop_name, carrier_ref) in ref_entries {
if let Some(Variant::Ref(actual_target)) =
dom.get_by_ref(carrier_ref).and_then(|inst| {
inst.properties.get(&rbx_dom_weak::ustr("Value")).cloned()
})
if let Some(Variant::Ref(actual_target)) = dom
.get_by_ref(carrier_ref)
.and_then(|inst| inst.properties.get(&rbx_dom_weak::ustr("Value")).cloned())
{
let service = dom.get_by_ref_mut(service_ref).unwrap();
service

View file

@ -127,20 +127,34 @@ pub fn from_slice_with_context<T: DeserializeOwned>(
}
fn trim_float(s: &str) -> String {
if !s.contains('.') { return s.to_string(); }
if !s.contains('.') {
return s.to_string();
}
let s = s.trim_end_matches('0').trim_end_matches('.');
if s == "-0" { "0".to_string() } else { s.to_string() }
if s == "-0" {
"0".to_string()
} else {
s.to_string()
}
}
fn format_f32(v: f32) -> String {
if v.is_nan() { return "NaN".to_string(); }
if v.is_infinite() { return if v > 0.0 { "Infinity" } else { "-Infinity" }.to_string(); }
if v.is_nan() {
return "NaN".to_string();
}
if v.is_infinite() {
return if v > 0.0 { "Infinity" } else { "-Infinity" }.to_string();
}
trim_float(&format!("{:.6}", v))
}
fn format_f64(v: f64) -> String {
if v.is_nan() { return "NaN".to_string(); }
if v.is_infinite() { return if v > 0.0 { "Infinity" } else { "-Infinity" }.to_string(); }
if v.is_nan() {
return "NaN".to_string();
}
if v.is_infinite() {
return if v > 0.0 { "Infinity" } else { "-Infinity" }.to_string();
}
trim_float(&format!("{:.15}", v))
}

View file

@ -78,15 +78,9 @@ impl UnresolvedValue {
_ => return Self::FullyQualified(variant),
},
Variant::ContentId(content) => AmbiguousValue::String(content.into_string()),
Variant::Vector2(vector) => {
AmbiguousValue::Array2([vector.x, vector.y])
}
Variant::Vector3(vector) => {
AmbiguousValue::Array3([vector.x, vector.y, vector.z])
}
Variant::Color3(color) => {
AmbiguousValue::Array3([color.r, color.g, color.b])
}
Variant::Vector2(vector) => AmbiguousValue::Array2([vector.x, vector.y]),
Variant::Vector3(vector) => AmbiguousValue::Array3([vector.x, vector.y, vector.z]),
Variant::Color3(color) => AmbiguousValue::Array3([color.r, color.g, color.b]),
Variant::CFrame(cf) => AmbiguousValue::Array12([
cf.position.x,
cf.position.y,
@ -197,7 +191,7 @@ impl AmbiguousValue {
DataType::Value(variant_ty) => match (variant_ty, self) {
(VariantType::Bool, AmbiguousValue::Bool(value)) => Ok(value.into()),
(VariantType::Float32, AmbiguousValue::Number32(value)) => Ok((value as f32).into()),
(VariantType::Float32, AmbiguousValue::Number32(value)) => Ok(value.into()),
(VariantType::Float32, AmbiguousValue::Number(value)) => Ok((value as f32).into()),
(VariantType::Float64, AmbiguousValue::Number(value)) => Ok(value.into()),
(VariantType::Int32, AmbiguousValue::Number(value)) => Ok((value as i32).into()),
@ -215,19 +209,19 @@ impl AmbiguousValue {
}
(VariantType::Vector2, AmbiguousValue::Array2(value)) => {
Ok(Vector2::new(value[0] as f32, value[1] as f32).into())
Ok(Vector2::new(value[0], value[1]).into())
}
(VariantType::Vector3, AmbiguousValue::Array3(value)) => {
Ok(Vector3::new(value[0] as f32, value[1] as f32, value[2] as f32).into())
Ok(Vector3::new(value[0], value[1], value[2]).into())
}
(VariantType::Color3, AmbiguousValue::Array3(value)) => {
Ok(Color3::new(value[0] as f32, value[1] as f32, value[2] as f32).into())
Ok(Color3::new(value[0], value[1], value[2]).into())
}
(VariantType::CFrame, AmbiguousValue::Array12(value)) => {
let value = value.map(|v| v as f32);
let value = value.map(|v| v);
let pos = Vector3::new(value[0], value[1], value[2]);
let orientation = Matrix3::new(
Vector3::new(value[3], value[4], value[5]),

View file

@ -606,10 +606,7 @@ pub fn build_syncback_request(
/// Build a complete rbxl file from the single-rbxm data blob + service
/// chunks, mirroring the same data that live syncback receives.
pub fn make_rbxl_from_chunks(
data: &[u8],
chunks: &[librojo::web_api::ServiceChunk],
) -> Vec<u8> {
pub fn make_rbxl_from_chunks(data: &[u8], chunks: &[librojo::web_api::ServiceChunk]) -> Vec<u8> {
use rbx_dom_weak::types::Variant;
use rbx_dom_weak::WeakDom;
use std::collections::HashMap;

View file

@ -12,11 +12,7 @@ use crate::rojo_test::{
use librojo::web_api::{SocketPacketType, PROTOCOL_VERSION};
fn assert_live_matches_cli(
fixture_name: &str,
entries: Vec<ServiceEntry>,
place_id: Option<u64>,
) {
fn assert_live_matches_cli(fixture_name: &str, entries: Vec<ServiceEntry>, place_id: Option<u64>) {
let (data, chunks) = build_syncback_request(entries);
run_serve_test(fixture_name, |session, _| {
session.post_api_syncback(place_id, data.clone(), chunks.clone());
@ -671,14 +667,10 @@ fn roundtrip_build_syncback_rebuild() {
let mut dom_a = rbx_binary::from_reader(Cursor::new(&rbxl_data_a)).unwrap();
let mut all_child_refs = Vec::new();
let mut chunks = Vec::new();
let service_refs: Vec<rbx_dom_weak::types::Ref> =
dom_a.root().children().to_vec();
let service_refs: Vec<rbx_dom_weak::types::Ref> = dom_a.root().children().to_vec();
for &service_ref in &service_refs {
let child_refs: Vec<rbx_dom_weak::types::Ref> = dom_a
.get_by_ref(service_ref)
.unwrap()
.children()
.to_vec();
let child_refs: Vec<rbx_dom_weak::types::Ref> =
dom_a.get_by_ref(service_ref).unwrap().children().to_vec();
let service = dom_a.get_by_ref(service_ref).unwrap();
let service_props: Vec<(String, rbx_dom_weak::types::Variant)> = service
@ -699,15 +691,10 @@ fn roundtrip_build_syncback_rebuild() {
if !target.is_none() && dom_a.get_by_ref(*target).is_some() {
let carrier = rbx_dom_weak::InstanceBuilder::new("ObjectValue")
.with_name(key.as_str())
.with_property(
"Value",
rbx_dom_weak::types::Variant::Ref(*target),
);
let carrier_ref =
dom_a.insert(dom_a.root_ref(), carrier);
.with_property("Value", rbx_dom_weak::types::Variant::Ref(*target));
let carrier_ref = dom_a.insert(dom_a.root_ref(), carrier);
carrier_refs.push(carrier_ref);
refs_map
.insert(key.to_string(), carrier_refs.len() as u32);
refs_map.insert(key.to_string(), carrier_refs.len() as u32);
}
}
_ => {