From e0ba2579d9b2fda8ccbbf8b759ff3034170acdc8 Mon Sep 17 00:00:00 2001 From: Filip Tibell Date: Sat, 20 May 2023 09:49:55 +0200 Subject: [PATCH] Replace CollectionService implementation with native instance tag APIs --- CHANGELOG.md | 14 ++++ docs/pages/roblox/Api-Status.md | 13 ++-- .../src/instance/collection_service.rs | 72 ------------------- packages/lib-roblox/src/instance/mod.rs | 20 +++++- tests/roblox/instance/tags.luau | 35 +++++---- 5 files changed, 52 insertions(+), 102 deletions(-) delete mode 100644 packages/lib-roblox/src/instance/collection_service.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a5628e..a0fc0df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 assert(decompressed == INPUT) ``` +- Added several new instance methods in the `roblox` builtin library: + - [`Instance:AddTag`](https://create.roblox.com/docs/reference/engine/classes/Instance#AddTag) + - [`Instance:GetTags`](https://create.roblox.com/docs/reference/engine/classes/Instance#GetTags) + - [`Instance:HasTag`](https://create.roblox.com/docs/reference/engine/classes/Instance#HasTag) + - [`Instance:RemoveTag`](https://create.roblox.com/docs/reference/engine/classes/Instance#RemoveTag) + +### Removed + +- Removed `CollectionService` specific methods from the `roblox` builtin library: + - [`CollectionService:AddTag`](https://create.roblox.com/docs/reference/engine/classes/CollectionService#AddTag) + - [`CollectionService:GetTags`](https://create.roblox.com/docs/reference/engine/classes/CollectionService#GetTags) + - [`CollectionService:HasTag`](https://create.roblox.com/docs/reference/engine/classes/CollectionService#HasTag) + - [`CollectionService:RemoveTag`](https://create.roblox.com/docs/reference/engine/classes/CollectionService#RemoveTag) + ### Changed - Both `stdio.write` and `stdio.ewrite` now support writing arbitrary bytes, instead of only valid UTF-8. diff --git a/docs/pages/roblox/Api-Status.md b/docs/pages/roblox/Api-Status.md index 2cc7211..2ef8068 100644 --- a/docs/pages/roblox/Api-Status.md +++ b/docs/pages/roblox/Api-Status.md @@ -15,6 +15,7 @@ However, if a recently added datatype is missing, and it can be used as an insta Currently implemented APIs: - [`new`](https://create.roblox.com/docs/reference/engine/datatypes/Instance#new) - note that this does not include the second `parent` argument +- [`AddTag`](https://create.roblox.com/docs/reference/engine/classes/CollectionService#AddTag) - [`Clone`](https://create.roblox.com/docs/reference/engine/classes/Instance#Clone) - [`Destroy`](https://create.roblox.com/docs/reference/engine/classes/Instance#Destroy) - [`ClearAllChildren`](https://create.roblox.com/docs/reference/engine/classes/Instance#ClearAllChildren) @@ -30,9 +31,12 @@ Currently implemented APIs: - [`GetChildren`](https://create.roblox.com/docs/reference/engine/classes/Instance#GetChildren) - [`GetDescendants`](https://create.roblox.com/docs/reference/engine/classes/Instance#GetDescendants) - [`GetFullName`](https://create.roblox.com/docs/reference/engine/classes/Instance#GetFullName) +- [`GetTags`](https://create.roblox.com/docs/reference/engine/classes/CollectionService#GetTags) +- [`HasTag`](https://create.roblox.com/docs/reference/engine/classes/CollectionService#HasTag) - [`IsA`](https://create.roblox.com/docs/reference/engine/classes/Instance#IsA) - [`IsAncestorOf`](https://create.roblox.com/docs/reference/engine/classes/Instance#IsAncestorOf) - [`IsDescendantOf`](https://create.roblox.com/docs/reference/engine/classes/Instance#IsDescendantOf) +- [`RemoveTag`](https://create.roblox.com/docs/reference/engine/classes/CollectionService#RemoveTag) - [`SetAttribute`](https://create.roblox.com/docs/reference/engine/classes/Instance#SetAttribute) ### `DataModel` @@ -42,15 +46,6 @@ Currently implemented APIs: - [`GetService`](https://create.roblox.com/docs/reference/engine/classes/ServiceProvider#GetService) - [`FindService`](https://create.roblox.com/docs/reference/engine/classes/ServiceProvider#FindService) -### `CollectionService` - -Currently implemented APIs: - -- [`AddTag`](https://create.roblox.com/docs/reference/engine/classes/CollectionService#AddTag) -- [`GetTags`](https://create.roblox.com/docs/reference/engine/classes/CollectionService#GetTags) -- [`HasTag`](https://create.roblox.com/docs/reference/engine/classes/CollectionService#HasTag) -- [`RemoveTag`](https://create.roblox.com/docs/reference/engine/classes/CollectionService#RemoveTag) - ## Datatypes Currently implemented datatypes: diff --git a/packages/lib-roblox/src/instance/collection_service.rs b/packages/lib-roblox/src/instance/collection_service.rs deleted file mode 100644 index 74066bb..0000000 --- a/packages/lib-roblox/src/instance/collection_service.rs +++ /dev/null @@ -1,72 +0,0 @@ -use mlua::prelude::*; - -use crate::shared::classes::add_class_restricted_method; - -use super::Instance; - -pub const CLASS_NAME: &str = "CollectionService"; - -pub fn add_methods<'lua, M: LuaUserDataMethods<'lua, Instance>>(m: &mut M) { - add_class_restricted_method(m, CLASS_NAME, "AddTag", collection_service_add_tag); - add_class_restricted_method(m, CLASS_NAME, "GetTags", collection_service_get_tags); - add_class_restricted_method(m, CLASS_NAME, "HasTag", collection_service_has_tag); - add_class_restricted_method(m, CLASS_NAME, "RemoveTag", collection_service_remove_tag); -} - -/** - Adds a tag to the instance. - - ### See Also - * [`AddTag`](https://create.roblox.com/docs/reference/engine/classes/CollectionService#AddTag) - on the Roblox Developer Hub -*/ -fn collection_service_add_tag( - _: &Lua, - _: &Instance, - (object, tag_name): (Instance, String), -) -> LuaResult<()> { - object.add_tag(tag_name); - Ok(()) -} - -/** - Gets all current tags for the instance. - - ### See Also - * [`GetTags`](https://create.roblox.com/docs/reference/engine/classes/CollectionService#GetTags) - on the Roblox Developer Hub -*/ -fn collection_service_get_tags(_: &Lua, _: &Instance, object: Instance) -> LuaResult> { - Ok(object.get_tags()) -} - -/** - Checks if the instance has a specific tag. - - ### See Also - * [`HasTag`](https://create.roblox.com/docs/reference/engine/classes/CollectionService#HasTag) - on the Roblox Developer Hub -*/ -fn collection_service_has_tag( - _: &Lua, - _: &Instance, - (object, tag_name): (Instance, String), -) -> LuaResult { - Ok(object.has_tag(tag_name)) -} - -/** - Removes a tag from the instance. - - ### See Also - * [`RemoveTag`](https://create.roblox.com/docs/reference/engine/classes/CollectionService#RemoveTag) - on the Roblox Developer Hub -*/ -fn collection_service_remove_tag( - _: &Lua, - _: &Instance, - (object, tag_name): (Instance, String), -) -> LuaResult<()> { - object.remove_tag(tag_name); - Ok(()) -} diff --git a/packages/lib-roblox/src/instance/mod.rs b/packages/lib-roblox/src/instance/mod.rs index ab62bb5..aeea352 100644 --- a/packages/lib-roblox/src/instance/mod.rs +++ b/packages/lib-roblox/src/instance/mod.rs @@ -24,7 +24,6 @@ use crate::{ shared::instance::{class_exists, class_is_a, find_property_info}, }; -pub(crate) mod collection_service; pub(crate) mod data_model; pub(crate) mod workspace; @@ -1130,10 +1129,27 @@ impl LuaUserData for Instance { } }, ); + methods.add_method("GetTags", |_, this, ()| { + this.ensure_not_destroyed()?; + Ok(this.get_tags()) + }); + methods.add_method("HasTag", |_, this, tag: String| { + this.ensure_not_destroyed()?; + Ok(this.has_tag(tag)) + }); + methods.add_method("AddTag", |_, this, tag: String| { + this.ensure_not_destroyed()?; + this.add_tag(tag); + Ok(()) + }); + methods.add_method("RemoveTag", |_, this, tag: String| { + this.ensure_not_destroyed()?; + this.remove_tag(tag); + Ok(()) + }); // Here we add inheritance-like behavior for instances by creating // methods that are restricted to specific classnames / base classes data_model::add_methods(methods); - collection_service::add_methods(methods); } } diff --git a/tests/roblox/instance/tags.luau b/tests/roblox/instance/tags.luau index 64668df..da1c6d3 100644 --- a/tests/roblox/instance/tags.luau +++ b/tests/roblox/instance/tags.luau @@ -1,35 +1,32 @@ local roblox = require("@lune/roblox") :: any local Instance = roblox.Instance -local game = Instance.new("DataModel") -local cs = game:GetService("CollectionService") - local model = Instance.new("Model") local part = Instance.new("Part") part.Parent = model local TAG_NAME = "InstanceTagName" -assert(cs:HasTag(model, TAG_NAME) == false) -assert(cs:HasTag(part, TAG_NAME) == false) +assert(model:HasTag(TAG_NAME) == false) +assert(part:HasTag(TAG_NAME) == false) -cs:AddTag(part, TAG_NAME) +part:AddTag(TAG_NAME) -assert(cs:HasTag(model, TAG_NAME) == false) -assert(cs:HasTag(part, TAG_NAME) == true) +assert(model:HasTag(TAG_NAME) == false) +assert(part:HasTag(TAG_NAME) == true) -cs:RemoveTag(part, TAG_NAME) +part:RemoveTag(TAG_NAME) -assert(cs:HasTag(model, TAG_NAME) == false) -assert(cs:HasTag(part, TAG_NAME) == false) +assert(model:HasTag(TAG_NAME) == false) +assert(part:HasTag(TAG_NAME) == false) -assert(#cs:GetTags(model) == 0) -assert(#cs:GetTags(part) == 0) +assert(#model:GetTags() == 0) +assert(#part:GetTags() == 0) -cs:AddTag(model, TAG_NAME) -cs:AddTag(part, TAG_NAME) +model:AddTag(TAG_NAME) +part:AddTag(TAG_NAME) -assert(#cs:GetTags(model) == 1) -assert(#cs:GetTags(part) == 1) -assert(cs:GetTags(model)[1] == TAG_NAME) -assert(cs:GetTags(part)[1] == TAG_NAME) +assert(#model:GetTags() == 1) +assert(#part:GetTags() == 1) +assert(model:GetTags()[1] == TAG_NAME) +assert(part:GetTags()[1] == TAG_NAME)