Skip to content

Instantly share code, notes, and snippets.

@cxmeel
Created September 4, 2018 19:57
Show Gist options
  • Save cxmeel/42aee3a7bd17fc2bf7dd750e9c4d170c to your computer and use it in GitHub Desktop.
Save cxmeel/42aee3a7bd17fc2bf7dd750e9c4d170c to your computer and use it in GitHub Desktop.
Extends game tree-traversal methods.
--[[
clockworksquirrel.extend-tree
Extends game tree-traversal methods.
Available methods -
Miscellaneous:
<boolean> HasProperty, <variant> Value :HasProperty(<Instance> Object, <string> Property)
Returns true if an Instance has the specified property, along with the value
of the property.
Ancestors:
<table> Ancestors :GetAncestors(<Instance> Object)
Returns a table containing the Instance's ancestors.
<table> Ancestors :GetAncestorsWhose(<Instance> Object, <Dictionary (Of <string> Property, <variant> Value)> Properties)
Returns a table of ancestors which match the given properties and values.
<Instance> Ancestor :FindFirstAncestorWhose(<Instance> Object, <Dictionary (Of <string> Property, <variant> Value)> Properties)
Returns the first ancestor which matches the given properties and values.
<table> Ancestors :GetAncestorsWhichAre(<Instance> Object, <string> ClassName)
Returns a table of ancestors which match the given class (checked via Instance::IsA)
Children:
<Instance> Child :FindFirstChildWhose(<Instance> Object, <Dictionary (Of <string> Property, <variant> Value)> Properties)
Returns the first child which matches the given properties and values.
<table> Children :GetChildrenWhose(<Instance> Object, <Dictionary (Of <string> Property, <variant> Value)> Properties)
Returns a table of children which match the given properties and values.
<table> Children :GetChildrenWhichAre(<Instance> Object, <string> ClassName)
Returns a table of children which match the given class (checked via Instance::IsA)
<void> :ClearAllChildrenWhichAre(<Instance> Object, <string> ClassName)
Calls Instance::Destroy on all children which match the given class (checked via Instance::IsA)
Descendants:
<table> Descendants :GetDescendantsWhose(<Instance> Object, <Dictionary (Of <string> Property, <variant> Value)> Properties)
Returns a table of descendants which match the given properties and values.
<table> Descendants :GetDescendantsWhichAre(<Instance> Object, <string> ClassName)
Returns a table of descendants which match the given class (check via Instance::IsA)
<void> :ClearAllDescendantsWhichAre(<Instance> Object, <string> ClassName)
Calls Instance::Destroy on all descendants which match the given class (checked via Instance::IsA)
--]]
local Module = {}
Module.__index = Module
local function TypeCheck(TypeOf, Object)
return assert(typeof(Object) == TypeOf)
end
function Module:HasProperty(Object, Property)
TypeCheck('Instance', Object)
return pcall(function() return Object[Property] end)
end
function Module:GetAncestors(Object)
TypeCheck('Instance', Object)
local AncesTree, CurrentParent = {}, Object.Parent
repeat
AncesTree[#AncesTree + 1] = CurrentParent
CurrentParent = CurrentParent.Parent
until CurrentParent == nil
return AncesTree
end
function Module:GetAncestorsWhichAre(Object, IsA)
TypeCheck('Instance', Object); TypeCheck('string', IsA)
local Ancestors = {}
for _, Ancestor in next, Module:GetAncestors(Object) do
if (Ancestor:IsA(IsA)) then
Ancestors[#Ancestors + 1] = Ancestor
end
end
return Ancestors
end
function Module:GetAncestorsWhose(Object, Properties)
TypeCheck('Instance', Object); TypeCheck('table', Properties)
local Ancestors = {}
for _, Ancestor in next, Object:GetChildren() do
local MatchedProperties, ValidProperties = 0, 0
for Property, PropValue in next, Properties do
local HasProperty, Value = Module:HasProperty(Ancestor, Property)
if (HasProperty and Value == Value) then
MatchedProperties = MatchedProperties + 1
ValidProperties = ValidProperties + 1
end
end
if (MatchedProperties == ValidProperties) then
Ancestors[#Ancestors + 1] = Ancestor
end
end
return Ancestors
end
function Module:FindFirstAncestorWhose(Object, Properties)
TypeCheck('Instance', Object)
local Ancestors = Module:GetAncestors(Object)
for _, Ancestor in next, Ancestors do
local MatchedProperties, ValidProperties = 0, 0
for Property, PropValue in next, Properties do
local HasProperty, Value = Module:HasProperty(Ancestor, Property)
if (HasProperty and Value == Value) then
MatchedProperties = MatchedProperties + 1
ValidProperties = ValidProperties + 1
end
end
if (MatchedProperties == ValidProperties) then
return Ancestor
end
end
end
function Module:FindFirstChildWhose(Object, Properties)
TypeCheck('Instance', Object); TypeCheck('table', Properties)
for _, Child in next, Object:GetChildren() do
local MatchedProperties, ValidProperties = 0, 0
for Property, PropValue in next, Properties do
local HasProperty, Value = Module:HasProperty(Child, Property)
if (HasProperty and Value == Value) then
MatchedProperties = MatchedProperties + 1
ValidProperties = ValidProperties + 1
end
end
if (MatchedProperties == ValidProperties) then
return Child
end
end
end
function Module:ClearAllChildrenWhichAre(Object, Class)
TypeCheck('Instance', Object); TypeCheck('string', Class)
for _, Child in next, Module:GetChildrenWhichAre(Object, Class) do
Child:Destroy()
end
end
function Module:GetChildrenWhose(Object, Properties)
TypeCheck('Instance', Object); TypeCheck('table', Properties)
local Children = {}
for _, Child in next, Object:GetChildren() do
local MatchedProperties, ValidProperties = 0, 0
for Property, PropValue in next, Properties do
local HasProperty, Value = Module:HasProperty(Child, Property)
if (HasProperty and Value == Value) then
MatchedProperties = MatchedProperties + 1
ValidProperties = ValidProperties + 1
end
end
if (MatchedProperties == ValidProperties) then
Children[#Children + 1] = Child
end
end
return Children
end
function Module:GetChildrenWhichAre(Object, IsA)
TypeCheck('Instance', Object); TypeCheck('string', IsA)
local Children = {}
for _, Child in next, Object:GetChildren() do
if (Child:IsA(IsA)) then
Children[#Children + 1] = Child
end
end
return Children
end
function Module:ClearAllDescendantsWhichAre(Object, Class)
TypeCheck('Instance', Object); TypeCheck('string', Class)
for _, Descendant in next, Module:GetDescendantsWhichAre(Object, Class) do
Descendant:Destroy()
end
end
function Module:GetDescendantsWhose(Object, Properties)
TypeCheck('Instance', Object); TypeCheck('table', Properties)
local Descendants = {}
for _, Descendant in next, Object:GetChildren() do
local MatchedProperties, ValidProperties = 0, 0
for Property, PropValue in next, Properties do
local HasProperty, Value = Module:HasProperty(Descendant, Property)
if (HasProperty and Value == Value) then
MatchedProperties = MatchedProperties + 1
ValidProperties = ValidProperties + 1
end
end
if (MatchedProperties == ValidProperties) then
Descendants[#Descendants + 1] = Descendant
end
end
return Descendants
end
function Module:GetDescendantsWhichAre(Object, IsA)
TypeCheck('Instance', Object); TypeCheck('string', IsA)
local Descendants = {}
for _, Descendant in next, Object:GetDescendants() do
if (Descendant:IsA(IsA)) then
Descendant[#Descendant + 1] = Descendant
end
end
return Descendants
end
return Module
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment