forked from StrafesNET/strafe-project
update rbx-dom
This commit is contained in:
@@ -13,11 +13,11 @@ authors = ["Rhys Lloyd <krakow20@gmail.com>"]
|
||||
bytemuck = "1.14.3"
|
||||
glam = "0.30.0"
|
||||
lazy-regex = "3.1.0"
|
||||
rbx_binary = { version = "0.7.4", registry = "strafesnet" }
|
||||
rbx_dom_weak = { version = "2.7.0", registry = "strafesnet" }
|
||||
rbx_binary = "1.0.0"
|
||||
rbx_dom_weak = "3.0.0"
|
||||
rbx_mesh = "0.3.1"
|
||||
rbx_reflection_database = { version = "0.2.10", registry = "strafesnet" }
|
||||
rbx_xml = { version = "0.13.3", registry = "strafesnet" }
|
||||
rbx_reflection_database = "1.0.0"
|
||||
rbx_xml = "1.0.0"
|
||||
rbxassetid = { version = "0.1.0", path = "../rbxassetid", registry = "strafesnet" }
|
||||
roblox_emulator = { version = "0.4.7", path = "../roblox_emulator", registry = "strafesnet" }
|
||||
strafesnet_common = { version = "0.6.0", path = "../common", registry = "strafesnet" }
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use std::io::Read;
|
||||
use rbx_dom_weak::ustr;
|
||||
use rbxassetid::{RobloxAssetId,RobloxAssetIdParseErr};
|
||||
use strafesnet_common::model::Mesh;
|
||||
use strafesnet_deferred_loader::{loader::Loader,texture::Texture};
|
||||
@@ -171,12 +172,12 @@ impl Loader for MeshLoader{
|
||||
return Err(MeshError::MissingInstance);
|
||||
};
|
||||
if physics_data.is_empty(){
|
||||
if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=instance.properties.get("PhysicsData"){
|
||||
if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=instance.properties.get(&ustr("PhysicsData")){
|
||||
physics_data=data.as_ref();
|
||||
}
|
||||
}
|
||||
if mesh_data.is_empty(){
|
||||
if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=instance.properties.get("MeshData"){
|
||||
if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=instance.properties.get(&ustr("MeshData")){
|
||||
mesh_data=data.as_ref();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::collections::HashMap;
|
||||
use crate::loader::MeshIndex;
|
||||
use crate::primitives::{self,CubeFace,CubeFaceDescription,WedgeFaceDescription,CornerWedgeFaceDescription,FaceDescription,Primitives};
|
||||
use rbx_dom_weak::ustr;
|
||||
use strafesnet_common::aabb::Aabb;
|
||||
use strafesnet_common::map;
|
||||
use strafesnet_common::model;
|
||||
@@ -389,6 +390,18 @@ enum RobloxBasePartDescription{
|
||||
Wedge(RobloxWedgeDescription),
|
||||
CornerWedge(RobloxCornerWedgeDescription),
|
||||
}
|
||||
|
||||
// TODO: initialize all ustrs in a top level struct thrown around as a reference
|
||||
// struct UstrKludge{
|
||||
// }
|
||||
|
||||
fn get_content_url(content:&rbx_dom_weak::types::Content)->Option<&str>{
|
||||
match content.value(){
|
||||
rbx_dom_weak::types::ContentType::Uri(uri)=>Some(uri.as_str()),
|
||||
_=>None,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_texture_description<'a>(
|
||||
temp_objects:&mut Vec<rbx_dom_weak::types::Ref>,
|
||||
render_config_deferred_loader:&mut RenderConfigDeferredLoader<&'a str>,
|
||||
@@ -401,69 +414,74 @@ fn get_texture_description<'a>(
|
||||
temp_objects.clear();
|
||||
recursive_collect_superclass(temp_objects,&dom,object,"Decal");
|
||||
for &mut decal_ref in temp_objects{
|
||||
if let Some(decal)=dom.get_by_ref(decal_ref){
|
||||
if let (
|
||||
Some(rbx_dom_weak::types::Variant::Content(content)),
|
||||
let Some(decal)=dom.get_by_ref(decal_ref) else{
|
||||
println!("Decal get_by_ref failed");
|
||||
continue;
|
||||
};
|
||||
let (
|
||||
Some(rbx_dom_weak::types::Variant::ContentId(content)),
|
||||
Some(rbx_dom_weak::types::Variant::Enum(normalid)),
|
||||
Some(rbx_dom_weak::types::Variant::Color3(decal_color3)),
|
||||
Some(rbx_dom_weak::types::Variant::Float32(decal_transparency)),
|
||||
) = (
|
||||
decal.properties.get("Texture"),
|
||||
decal.properties.get("Face"),
|
||||
decal.properties.get("Color3"),
|
||||
decal.properties.get("Transparency"),
|
||||
) {
|
||||
let render_id=render_config_deferred_loader.acquire_render_config_id(Some(content.as_ref()));
|
||||
if let Ok(cube_face)=normalid.to_u32().try_into(){
|
||||
let (roblox_texture_color,roblox_texture_transform)=if decal.class=="Texture"{
|
||||
//generate tranform
|
||||
if let (
|
||||
Some(&rbx_dom_weak::types::Variant::Float32(offset_studs_u)),
|
||||
Some(&rbx_dom_weak::types::Variant::Float32(offset_studs_v)),
|
||||
Some(&rbx_dom_weak::types::Variant::Float32(studs_per_tile_u)),
|
||||
Some(&rbx_dom_weak::types::Variant::Float32(studs_per_tile_v)),
|
||||
) = (
|
||||
decal.properties.get("OffsetStudsU"),
|
||||
decal.properties.get("OffsetStudsV"),
|
||||
decal.properties.get("StudsPerTileU"),
|
||||
decal.properties.get("StudsPerTileV"),
|
||||
)
|
||||
{
|
||||
let (size_u,size_v)=match cube_face{
|
||||
CubeFace::Right=>(size.z,size.y),//right
|
||||
CubeFace::Top=>(size.x,size.z),//top
|
||||
CubeFace::Back=>(size.x,size.y),//back
|
||||
CubeFace::Left=>(size.z,size.y),//left
|
||||
CubeFace::Bottom=>(size.x,size.z),//bottom
|
||||
CubeFace::Front=>(size.x,size.y),//front
|
||||
};
|
||||
(
|
||||
glam::vec4(decal_color3.r,decal_color3.g,decal_color3.b,1.0-*decal_transparency),
|
||||
RobloxTextureTransform{
|
||||
offset_studs_u,
|
||||
offset_studs_v,
|
||||
studs_per_tile_u,
|
||||
studs_per_tile_v,
|
||||
size_u,
|
||||
size_v,
|
||||
}
|
||||
)
|
||||
}else{
|
||||
(glam::Vec4::ONE,RobloxTextureTransform::identity())
|
||||
}
|
||||
}else{
|
||||
(glam::Vec4::ONE,RobloxTextureTransform::identity())
|
||||
};
|
||||
part_texture_description[cube_face]=Some(RobloxFaceTextureDescription{
|
||||
render:render_id,
|
||||
color:roblox_texture_color,
|
||||
transform:roblox_texture_transform,
|
||||
});
|
||||
}else{
|
||||
println!("NormalId is invalid");
|
||||
}
|
||||
)=(
|
||||
decal.properties.get(&ustr("Texture")),
|
||||
decal.properties.get(&ustr("Face")),
|
||||
decal.properties.get(&ustr("Color3")),
|
||||
decal.properties.get(&ustr("Transparency")),
|
||||
)else{
|
||||
println!("Decal is missing a required property");
|
||||
continue;
|
||||
};
|
||||
let texture_id=Some(content.as_str());
|
||||
let render_id=render_config_deferred_loader.acquire_render_config_id(texture_id);
|
||||
let Ok(cube_face)=normalid.to_u32().try_into()else{
|
||||
println!("NormalId is invalid");
|
||||
continue;
|
||||
};
|
||||
let (roblox_texture_color,roblox_texture_transform)=if decal.class=="Texture"{
|
||||
//generate tranform
|
||||
if let (
|
||||
Some(&rbx_dom_weak::types::Variant::Float32(offset_studs_u)),
|
||||
Some(&rbx_dom_weak::types::Variant::Float32(offset_studs_v)),
|
||||
Some(&rbx_dom_weak::types::Variant::Float32(studs_per_tile_u)),
|
||||
Some(&rbx_dom_weak::types::Variant::Float32(studs_per_tile_v)),
|
||||
) = (
|
||||
decal.properties.get(&ustr("OffsetStudsU")),
|
||||
decal.properties.get(&ustr("OffsetStudsV")),
|
||||
decal.properties.get(&ustr("StudsPerTileU")),
|
||||
decal.properties.get(&ustr("StudsPerTileV")),
|
||||
)
|
||||
{
|
||||
let (size_u,size_v)=match cube_face{
|
||||
CubeFace::Right=>(size.z,size.y),//right
|
||||
CubeFace::Top=>(size.x,size.z),//top
|
||||
CubeFace::Back=>(size.x,size.y),//back
|
||||
CubeFace::Left=>(size.z,size.y),//left
|
||||
CubeFace::Bottom=>(size.x,size.z),//bottom
|
||||
CubeFace::Front=>(size.x,size.y),//front
|
||||
};
|
||||
(
|
||||
glam::vec4(decal_color3.r,decal_color3.g,decal_color3.b,1.0-*decal_transparency),
|
||||
RobloxTextureTransform{
|
||||
offset_studs_u,
|
||||
offset_studs_v,
|
||||
studs_per_tile_u,
|
||||
studs_per_tile_v,
|
||||
size_u,
|
||||
size_v,
|
||||
}
|
||||
)
|
||||
}else{
|
||||
(glam::Vec4::ONE,RobloxTextureTransform::identity())
|
||||
}
|
||||
}
|
||||
}else{
|
||||
(glam::Vec4::ONE,RobloxTextureTransform::identity())
|
||||
};
|
||||
part_texture_description[cube_face]=Some(RobloxFaceTextureDescription{
|
||||
render:render_id,
|
||||
color:roblox_texture_color,
|
||||
transform:roblox_texture_transform,
|
||||
});
|
||||
}
|
||||
part_texture_description
|
||||
}
|
||||
@@ -529,12 +547,12 @@ pub fn convert<'a>(
|
||||
Some(rbx_dom_weak::types::Variant::Color3uint8(color3)),
|
||||
Some(rbx_dom_weak::types::Variant::Bool(can_collide)),
|
||||
) = (
|
||||
object.properties.get("CFrame"),
|
||||
object.properties.get("Size"),
|
||||
object.properties.get("Velocity"),
|
||||
object.properties.get("Transparency"),
|
||||
object.properties.get("Color"),
|
||||
object.properties.get("CanCollide"),
|
||||
object.properties.get(&ustr("CFrame")),
|
||||
object.properties.get(&ustr("Size")),
|
||||
object.properties.get(&ustr("Velocity")),
|
||||
object.properties.get(&ustr("Transparency")),
|
||||
object.properties.get(&ustr("Color")),
|
||||
object.properties.get(&ustr("CanCollide")),
|
||||
)
|
||||
{
|
||||
let model_transform=planar64_affine3_from_roblox(cf,size);
|
||||
@@ -553,7 +571,7 @@ pub fn convert<'a>(
|
||||
|
||||
//TODO: also detect "CylinderMesh" etc here
|
||||
let shape=match object.class.as_str(){
|
||||
"Part"=>if let Some(rbx_dom_weak::types::Variant::Enum(shape))=object.properties.get("Shape"){
|
||||
"Part"=>if let Some(rbx_dom_weak::types::Variant::Enum(shape))=object.properties.get(&ustr("Shape")){
|
||||
Shape::Primitive(shape.to_u32().try_into().expect("Funky roblox PartType"))
|
||||
}else{
|
||||
panic!("Part has no Shape!");
|
||||
@@ -623,15 +641,19 @@ pub fn convert<'a>(
|
||||
(MeshAvailability::Immediate,mesh_id)
|
||||
},
|
||||
Shape::MeshPart=>if let (
|
||||
Some(rbx_dom_weak::types::Variant::Content(mesh_asset_id)),
|
||||
Some(rbx_dom_weak::types::Variant::Content(texture_asset_id)),
|
||||
Some(rbx_dom_weak::types::Variant::Content(mesh_content)),
|
||||
Some(rbx_dom_weak::types::Variant::Content(texture_content)),
|
||||
)=(
|
||||
object.properties.get("MeshId"),
|
||||
object.properties.get("TextureID"),
|
||||
// mesh must exist
|
||||
object.properties.get(&ustr("MeshContent")),
|
||||
// texture is allowed to be none
|
||||
object.properties.get(&ustr("TextureContent")),
|
||||
){
|
||||
let mesh_asset_id=get_content_url(mesh_content).expect("MeshPart Mesh is not a Uri");
|
||||
let texture_asset_id=get_content_url(texture_content);
|
||||
(
|
||||
MeshAvailability::DeferredMesh(render_config_deferred_loader.acquire_render_config_id(Some(texture_asset_id.as_ref()))),
|
||||
mesh_deferred_loader.acquire_mesh_id(MeshIndex::file_mesh(mesh_asset_id.as_ref())),
|
||||
MeshAvailability::DeferredMesh(render_config_deferred_loader.acquire_render_config_id(texture_asset_id)),
|
||||
mesh_deferred_loader.acquire_mesh_id(MeshIndex::file_mesh(mesh_asset_id)),
|
||||
)
|
||||
}else{
|
||||
panic!("Mesh has no Mesh or Texture");
|
||||
@@ -640,13 +662,13 @@ pub fn convert<'a>(
|
||||
let mut content="";
|
||||
let mut mesh_data:&[u8]=&[];
|
||||
let mut physics_data:&[u8]=&[];
|
||||
if let Some(rbx_dom_weak::types::Variant::Content(asset_id))=object.properties.get("AssetId"){
|
||||
if let Some(rbx_dom_weak::types::Variant::ContentId(asset_id))=object.properties.get(&ustr("AssetId")){
|
||||
content=asset_id.as_ref();
|
||||
}
|
||||
if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=object.properties.get("MeshData"){
|
||||
if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=object.properties.get(&ustr("MeshData")){
|
||||
mesh_data=data.as_ref();
|
||||
}
|
||||
if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=object.properties.get("PhysicsData"){
|
||||
if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=object.properties.get(&ustr("PhysicsData")){
|
||||
physics_data=data.as_ref();
|
||||
}
|
||||
let part_texture_description=get_texture_description(&mut temp_objects,render_config_deferred_loader,dom,object,size);
|
||||
|
||||
@@ -15,7 +15,7 @@ run-service=[]
|
||||
glam = "0.30.0"
|
||||
mlua = { version = "0.10.1", features = ["luau"] }
|
||||
phf = { version = "0.11.2", features = ["macros"] }
|
||||
rbx_dom_weak = { version = "2.7.0", registry = "strafesnet" }
|
||||
rbx_reflection = { version = "4.7.0", registry = "strafesnet" }
|
||||
rbx_reflection_database = { version = "0.2.10", registry = "strafesnet" }
|
||||
rbx_types = { version = "1.10.0", registry = "strafesnet" }
|
||||
rbx_dom_weak = "3.0.0"
|
||||
rbx_reflection = "5.0.0"
|
||||
rbx_reflection_database = "1.0.0"
|
||||
rbx_types = "2.0.0"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use rbx_dom_weak::{types::Ref,InstanceBuilder,WeakDom};
|
||||
use rbx_dom_weak::{types::Ref,ustr,InstanceBuilder,WeakDom};
|
||||
|
||||
pub fn class_is_a(class:&str,superclass:&str)->bool{
|
||||
class==superclass
|
||||
@@ -70,8 +70,8 @@ impl Context{
|
||||
{
|
||||
//Lowercase and upper case workspace property!
|
||||
let game=self.dom.root_mut();
|
||||
game.properties.insert("workspace".to_owned(),rbx_types::Variant::Ref(workspace));
|
||||
game.properties.insert("Workspace".to_owned(),rbx_types::Variant::Ref(workspace));
|
||||
game.properties.insert(ustr("workspace"),rbx_types::Variant::Ref(workspace));
|
||||
game.properties.insert(ustr("Workspace"),rbx_types::Variant::Ref(workspace));
|
||||
}
|
||||
self.dom.insert(game,InstanceBuilder::new("Lighting"));
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::collections::{hash_map::Entry,HashMap};
|
||||
|
||||
use mlua::{FromLua,FromLuaMulti,IntoLua,IntoLuaMulti};
|
||||
use rbx_types::Ref;
|
||||
use rbx_dom_weak::{InstanceBuilder,WeakDom};
|
||||
use rbx_dom_weak::{ustr,Ustr,InstanceBuilder,WeakDom};
|
||||
|
||||
use crate::runner::vector3::Vector3;
|
||||
|
||||
@@ -58,7 +58,7 @@ fn get_full_name(dom:&rbx_dom_weak::WeakDom,instance:&rbx_dom_weak::Instance)->S
|
||||
pub fn get_name_source(lua:&mlua::Lua,script:Instance)->Result<(String,String),mlua::Error>{
|
||||
dom_mut(lua,|dom|{
|
||||
let instance=script.get(dom)?;
|
||||
let source=match instance.properties.get("Source"){
|
||||
let source=match instance.properties.get(&ustr("Source")){
|
||||
Some(rbx_dom_weak::types::Variant::String(s))=>s.clone(),
|
||||
_=>Err(mlua::Error::external("Missing script.Source"))?,
|
||||
};
|
||||
@@ -97,25 +97,6 @@ impl Instance{
|
||||
}
|
||||
type_from_lua_userdata!(Instance);
|
||||
|
||||
//TODO: update rbx_reflection and use dom.superclasses_iter
|
||||
pub struct SuperClassIter<'a> {
|
||||
database: &'a rbx_reflection::ReflectionDatabase<'a>,
|
||||
descriptor: Option<&'a rbx_reflection::ClassDescriptor<'a>>,
|
||||
}
|
||||
impl<'a> SuperClassIter<'a> {
|
||||
fn next_descriptor(&self) -> Option<&'a rbx_reflection::ClassDescriptor<'a>> {
|
||||
let superclass = self.descriptor?.superclass.as_ref()?;
|
||||
self.database.classes.get(superclass)
|
||||
}
|
||||
}
|
||||
impl<'a> Iterator for SuperClassIter<'a> {
|
||||
type Item = &'a rbx_reflection::ClassDescriptor<'a>;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let next_descriptor = self.next_descriptor();
|
||||
std::mem::replace(&mut self.descriptor, next_descriptor)
|
||||
}
|
||||
}
|
||||
|
||||
impl mlua::UserData for Instance{
|
||||
fn add_fields<F:mlua::UserDataFields<Self>>(fields:&mut F){
|
||||
fields.add_field_method_get("Parent",|lua,this|{
|
||||
@@ -148,7 +129,7 @@ impl mlua::UserData for Instance{
|
||||
fields.add_field_method_get("ClassName",|lua,this|{
|
||||
dom_mut(lua,|dom|{
|
||||
let instance=this.get(dom)?;
|
||||
Ok(instance.class.clone())
|
||||
Ok(instance.class.to_owned())
|
||||
})
|
||||
});
|
||||
}
|
||||
@@ -227,26 +208,21 @@ impl mlua::UserData for Instance{
|
||||
});
|
||||
methods.add_meta_function(mlua::MetaMethod::Index,|lua,(this,index):(Instance,mlua::String)|{
|
||||
let index_str=&*index.to_str()?;
|
||||
let index_ustr=ustr(index_str);
|
||||
dom_mut(lua,|dom|{
|
||||
let instance=this.get(dom)?;
|
||||
//println!("__index t={} i={index:?}",instance.name);
|
||||
let db=rbx_reflection_database::get();
|
||||
let class=db.classes.get(instance.class.as_str()).ok_or_else(||mlua::Error::runtime("Class missing"))?;
|
||||
//Find existing property
|
||||
match instance.properties.get(index_str)
|
||||
match instance.properties.get(&index_ustr)
|
||||
.cloned()
|
||||
//Find default value
|
||||
.or_else(||db.find_default_property(class,index_str).cloned())
|
||||
//Find virtual property
|
||||
.or_else(||{
|
||||
SuperClassIter{
|
||||
database:db,
|
||||
descriptor:Some(class),
|
||||
}
|
||||
.find_map(|class|
|
||||
find_virtual_property(&instance.properties,class,index_str)
|
||||
)
|
||||
})
|
||||
.or_else(||db.superclasses_iter(class).find_map(|class|
|
||||
find_virtual_property(&instance.properties,class,&index_ustr)
|
||||
))
|
||||
{
|
||||
Some(rbx_types::Variant::Int32(val))=>return val.into_lua(lua),
|
||||
Some(rbx_types::Variant::Int64(val))=>return val.into_lua(lua),
|
||||
@@ -260,11 +236,7 @@ impl mlua::UserData for Instance{
|
||||
}
|
||||
//find a function with a matching name
|
||||
if let Some(function)=class_methods_store_mut(lua,|cf|{
|
||||
let mut iter=SuperClassIter{
|
||||
database:db,
|
||||
descriptor:Some(class),
|
||||
};
|
||||
iter.find_map(|class|{
|
||||
db.superclasses_iter(class).find_map(|class|{
|
||||
let mut class_methods=cf.get_or_create_class_methods(&class.name)?;
|
||||
class_methods.get_or_create_function(lua,index_str)
|
||||
.transpose()
|
||||
@@ -294,21 +266,22 @@ impl mlua::UserData for Instance{
|
||||
let instance=this.get_mut(dom)?;
|
||||
//println!("__newindex t={} i={index:?} v={value:?}",instance.name);
|
||||
let index_str=&*index.to_str()?;
|
||||
let index_ustr=ustr(index_str);
|
||||
let db=rbx_reflection_database::get();
|
||||
let class=db.classes.get(instance.class.as_str()).ok_or_else(||mlua::Error::runtime("Class missing"))?;
|
||||
let mut iter=SuperClassIter{
|
||||
database:db,
|
||||
descriptor:Some(class),
|
||||
};
|
||||
let property=iter.find_map(|cls|cls.properties.get(index_str)).ok_or_else(||mlua::Error::runtime(format!("Property '{index_str}' missing on class '{}'",class.name)))?;
|
||||
let property=db.superclasses_iter(class).find_map(|cls|
|
||||
cls.properties.get(index_str)
|
||||
).ok_or_else(||
|
||||
mlua::Error::runtime(format!("Property '{index_str}' missing on class '{}'",class.name))
|
||||
)?;
|
||||
match &property.data_type{
|
||||
rbx_reflection::DataType::Value(rbx_types::VariantType::Vector3)=>{
|
||||
let typed_value:Vector3=*value.as_userdata().ok_or_else(||mlua::Error::runtime("Expected Userdata"))?.borrow()?;
|
||||
instance.properties.insert(index_str.to_owned(),rbx_types::Variant::Vector3(typed_value.into()));
|
||||
instance.properties.insert(index_ustr,rbx_types::Variant::Vector3(typed_value.into()));
|
||||
},
|
||||
rbx_reflection::DataType::Value(rbx_types::VariantType::Float32)=>{
|
||||
let typed_value:f32=coerce_float32(&value).ok_or_else(||mlua::Error::runtime("Expected f32"))?;
|
||||
instance.properties.insert(index_str.to_owned(),rbx_types::Variant::Float32(typed_value));
|
||||
instance.properties.insert(index_ustr,rbx_types::Variant::Float32(typed_value));
|
||||
},
|
||||
rbx_reflection::DataType::Enum(enum_name)=>{
|
||||
let typed_value=match &value{
|
||||
@@ -324,27 +297,27 @@ impl mlua::UserData for Instance{
|
||||
},
|
||||
_=>Err(mlua::Error::runtime("Expected Enum")),
|
||||
}?;
|
||||
instance.properties.insert(index_str.to_owned(),rbx_types::Variant::Enum(typed_value));
|
||||
instance.properties.insert(index_ustr,rbx_types::Variant::Enum(typed_value));
|
||||
},
|
||||
rbx_reflection::DataType::Value(rbx_types::VariantType::Color3)=>{
|
||||
let typed_value:crate::runner::color3::Color3=*value.as_userdata().ok_or_else(||mlua::Error::runtime("Expected Color3"))?.borrow()?;
|
||||
instance.properties.insert(index_str.to_owned(),rbx_types::Variant::Color3(typed_value.into()));
|
||||
instance.properties.insert(index_ustr,rbx_types::Variant::Color3(typed_value.into()));
|
||||
},
|
||||
rbx_reflection::DataType::Value(rbx_types::VariantType::Bool)=>{
|
||||
let typed_value=value.as_boolean().ok_or_else(||mlua::Error::runtime("Expected boolean"))?;
|
||||
instance.properties.insert(index_str.to_owned(),rbx_types::Variant::Bool(typed_value));
|
||||
instance.properties.insert(index_ustr,rbx_types::Variant::Bool(typed_value));
|
||||
},
|
||||
rbx_reflection::DataType::Value(rbx_types::VariantType::String)=>{
|
||||
let typed_value=value.as_str().ok_or_else(||mlua::Error::runtime("Expected boolean"))?;
|
||||
instance.properties.insert(index_str.to_owned(),rbx_types::Variant::String(typed_value.to_owned()));
|
||||
instance.properties.insert(index_ustr,rbx_types::Variant::String(typed_value.to_owned()));
|
||||
},
|
||||
rbx_reflection::DataType::Value(rbx_types::VariantType::NumberSequence)=>{
|
||||
let typed_value:crate::runner::number_sequence::NumberSequence=*value.as_userdata().ok_or_else(||mlua::Error::runtime("Expected NumberSequence"))?.borrow()?;
|
||||
instance.properties.insert(index_str.to_owned(),rbx_types::Variant::NumberSequence(typed_value.into()));
|
||||
instance.properties.insert(index_ustr,rbx_types::Variant::NumberSequence(typed_value.into()));
|
||||
},
|
||||
rbx_reflection::DataType::Value(rbx_types::VariantType::ColorSequence)=>{
|
||||
let typed_value:crate::runner::color_sequence::ColorSequence=*value.as_userdata().ok_or_else(||mlua::Error::runtime("Expected ColorSequence"))?.borrow()?;
|
||||
instance.properties.insert(index_str.to_owned(),rbx_types::Variant::ColorSequence(typed_value.into()));
|
||||
instance.properties.insert(index_ustr,rbx_types::Variant::ColorSequence(typed_value.into()));
|
||||
},
|
||||
other=>return Err(mlua::Error::runtime(format!("Unimplemented property type: {other:?}"))),
|
||||
}
|
||||
@@ -480,16 +453,16 @@ static VIRTUAL_PROPERTY_DATABASE:VPD=phf::phf_map!{
|
||||
};
|
||||
|
||||
fn find_virtual_property(
|
||||
properties:&HashMap<String,rbx_types::Variant>,
|
||||
properties:&rbx_dom_weak::UstrMap<rbx_types::Variant>,
|
||||
class:&rbx_reflection::ClassDescriptor,
|
||||
index:&str
|
||||
index:&Ustr,
|
||||
)->Option<rbx_types::Variant>{
|
||||
//Find virtual property
|
||||
let class_virtual_properties=VIRTUAL_PROPERTY_DATABASE.get(&class.name)?;
|
||||
let virtual_property=class_virtual_properties.get(index)?;
|
||||
|
||||
//Get source property
|
||||
let variant=properties.get(virtual_property.property)?;
|
||||
let variant=properties.get(&ustr(virtual_property.property))?;
|
||||
|
||||
//Transform Source property with provided function
|
||||
(virtual_property.pointer)(variant)
|
||||
|
||||
Reference in New Issue
Block a user