From 6ef353362942707565e8e52fd168d0ad4643a61c Mon Sep 17 00:00:00 2001 From: jeparlefrancais Date: Tue, 11 May 2021 00:16:50 -0400 Subject: [PATCH 1/4] add Instance:IsA() --- src/roblox_api/instance.rs | 40 ++++++++++++++++++++++++++++++++++++++ test-scripts/is-a.lua | 15 ++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 test-scripts/is-a.lua diff --git a/src/roblox_api/instance.rs b/src/roblox_api/instance.rs index 855e411..dbb160c 100644 --- a/src/roblox_api/instance.rs +++ b/src/roblox_api/instance.rs @@ -235,6 +235,43 @@ impl LuaInstance { } } + fn is_a(&self, class_name: &str) -> rlua::Result { + let tree = self.tree.lock().unwrap(); + + let instance = tree + .get_by_ref(self.id) + .ok_or_else(|| rlua::Error::external("Cannot call IsA() on a destroyed instance"))?; + + if class_name == "Instance" || instance.class == class_name { + return Ok(true); + } + + let database = rbx_reflection_database::get(); + let mut descriptor = database + .classes + .get(instance.class.as_str()) + .ok_or_else(|| { + rlua::Error::external(format!( + "Unable to obtain class {} from reflection database", + &instance.class + )) + })?; + + while let Some(super_class_name) = &descriptor.superclass { + if class_name == super_class_name { + return Ok(true); + } + descriptor = database.classes.get(super_class_name).ok_or_else(|| { + rlua::Error::external(format!( + "Unable to obtain class {} from reflection database", + &instance.class + )) + })?; + } + + Ok(false) + } + fn get_class_name<'lua>( &self, context: rlua::Context<'lua>, @@ -395,6 +432,9 @@ impl UserData for LuaInstance { this.find_first_child_of_class(&class) }); + methods.add_method("IsA", |_context, this, class_name: String| { + this.is_a(&class_name) + }); methods.add_method("GetFullName", |_context, this, _args: ()| { this.get_full_name() }); diff --git a/test-scripts/is-a.lua b/test-scripts/is-a.lua new file mode 100644 index 0000000..306d3ba --- /dev/null +++ b/test-scripts/is-a.lua @@ -0,0 +1,15 @@ +local folder = Instance.new("Folder") + +-- assert(folder:IsA("Folder")) +-- assert(folder:IsA("Instance")) +-- assert(not folder:IsA("BasePart")) + +local spawnLocation = Instance.new("SpawnLocation") + +assert(spawnLocation:IsA("SpawnLocation")) +assert(spawnLocation:IsA("Part")) +assert(spawnLocation:IsA("FormFactorPart")) +assert(spawnLocation:IsA("BasePart")) +assert(spawnLocation:IsA("PVInstance")) +assert(spawnLocation:IsA("Instance")) +assert(not spawnLocation:IsA("Folder")) From 46479616c1ca6834be9c8912f6220237e6020872 Mon Sep 17 00:00:00 2001 From: jeparlefrancais Date: Tue, 11 May 2021 00:18:18 -0400 Subject: [PATCH 2/4] add entry to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c522394..7e1a7c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased Changes +* Added Instance:IsA() ([#52](https://github.com/rojo-rbx/remodel/pull/52)) * Added Instance:GetFullName() ([#49](https://github.com/rojo-rbx/remodel/pull/49)) * Added `Instance:FindFirstChildOfClass()` ([#50](https://github.com/rojo-rbx/remodel/pull/50)) * Added support for CFrame ([#48](https://github.com/rojo-rbx/remodel/pull/48)) From 9fac8294696ee4b7906bab84ebf8e0eb9f352ae5 Mon Sep 17 00:00:00 2001 From: jeparlefrancais Date: Tue, 11 May 2021 00:18:40 -0400 Subject: [PATCH 3/4] uncomment test code --- test-scripts/is-a.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test-scripts/is-a.lua b/test-scripts/is-a.lua index 306d3ba..6f37749 100644 --- a/test-scripts/is-a.lua +++ b/test-scripts/is-a.lua @@ -1,8 +1,8 @@ local folder = Instance.new("Folder") --- assert(folder:IsA("Folder")) --- assert(folder:IsA("Instance")) --- assert(not folder:IsA("BasePart")) +assert(folder:IsA("Folder")) +assert(folder:IsA("Instance")) +assert(not folder:IsA("BasePart")) local spawnLocation = Instance.new("SpawnLocation") From 2ce0b22ca74b6891ca5eda2eb4461c303b01781b Mon Sep 17 00:00:00 2001 From: jeparlefrancais Date: Tue, 3 Aug 2021 23:55:39 -0400 Subject: [PATCH 4/4] refactor loop --- src/roblox_api/instance.rs | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/roblox_api/instance.rs b/src/roblox_api/instance.rs index dbb160c..a2c20b4 100644 --- a/src/roblox_api/instance.rs +++ b/src/roblox_api/instance.rs @@ -247,29 +247,26 @@ impl LuaInstance { } let database = rbx_reflection_database::get(); - let mut descriptor = database - .classes - .get(instance.class.as_str()) - .ok_or_else(|| { - rlua::Error::external(format!( - "Unable to obtain class {} from reflection database", - &instance.class - )) - })?; + let mut superclass_name = instance.class.as_str(); - while let Some(super_class_name) = &descriptor.superclass { - if class_name == super_class_name { - return Ok(true); + loop { + if class_name == superclass_name { + break Ok(true); } - descriptor = database.classes.get(super_class_name).ok_or_else(|| { + + let descriptor = database.classes.get(superclass_name).ok_or_else(|| { rlua::Error::external(format!( "Unable to obtain class {} from reflection database", - &instance.class + &superclass_name )) })?; - } - Ok(false) + if let Some(super_class) = &descriptor.superclass { + superclass_name = super_class; + } else { + break Ok(false); + } + } } fn get_class_name<'lua>(