Advanced Nodes
You might've noticed, I haven't explained the last call after meta.
local node = Allure:Node(deps) {content} {meta} ()This call finalizes the node and packs everything together.
Before we finalize the node, we have a lot of stuff we can do. That gives us the advanced usage of Nodes.
Usage
You are recommended to create the node, and finalize it as the last line of your modules:
local node = Allure:Node() {} {}
return node()The returned result of such, is a very interesting construction.
I sometimes call it a half-node, or a node workspace if you will.
At this step it has already defined hidden meta, meta, dependencies, etc.
It does not only return the half-node, but also throws back your dependencies:
local node, React, Promise = Allure:Node(
require(path.to.React),
require(path.to.Promise)
) {} {}
return node()In the exact same order.
All of them are kept fully type-safe. Including the node, just look:
local node, React = Allure:Node(require(path.to.React)) {} {}
function node:OnInit()
end
return node()This function, OnInit, has been catched by the type solver, because node is an unsealed table, it's fully typesafe.
The finalization, node() also entirely keeps it typesafe.
Injecting dependencies via :UseDependency
We're starting to go over the utilities given within the half-node. This is not just a table, or your content table with meta, it's a big construction with utilities.
Inject a dependency by simply calling the function:
local node, React = Allure:Node(require(path.to.React)) {} {}
local Promise = node:UseDependency(require(path.to.Promise))
function node:OnInit()
end
return node()This utility function being present is in no way messing up your content table and meta. It just exists there as an addon while you are making the node.
References
node.Meta references the meta, if you've needed the reference:
local node = Allure:Node() {} {
Name = "MyNode"
}
local Promise = node:UseDependency(require(path.to.Promise))
print(node.Meta.Name)
function node:OnInit()
end
return node()Actually, we can already reference Name from Meta normally via
print(node.Name)So this is starting the reference chain:
Content -> MetaWe've also got utilities here:
Content -> Utilities -> Metanode.HiddenMeta is a peculiar sight. This table is also meta, but it does not appear in the end type of the node, and it originally is made by Allure:
{
Dependencies = {...},
Tags = {
Priority = Allure:CountDependencies(...)
}
}When you finalize the node it also becomes a part of the node.
And before that, you can also reference the contents remotely:
print(node.Tags.Priority)So we're continuing our reference chain:
Content -> Utilities -> Meta -> HiddenMetanode.HiddenMeta can be useful when you need a secret to hide from the typesolver, or just modify whatever Allure set up.
Tagging
As you've seen, Tags are within HiddenMeta, so to tag an instance, create a new tag within node.HiddenMeta.Tags.
But we all need shortcuts.
Add or change a tag:
local node = Allure:Node() {} {}
node:Tag("Children", 10)
node:Tag("Instance", script)
node:Tag("SomeTagForRemoval", nil)
return node()Get a tag:
local node = Allure:Node() {} {}
node:Tag("Children", 10)
node:Tag("Instance", script)
print(node:GetTag("Children")) --10
return node()Metatables
Skip this part, if you're unfamiliar with metatables.
You could tell, these utilities and the reference chain is achieved via metatables.
Setting a metatable for our node, to appear after finalization becomes a challenge.
No more: finalization sets the metatable to a specific value, originally nil.
This value can be modified via our utilities, again:
Setting the metatable of the future node:
local node = Allure:Node() {} {}
node:UseMetatable {
__index = rawget,
__newindex = rawset
}
return node()Overriding it in bulk:
local node = Allure:Node() {} {}
node:UseMetatable {
__newindex = rawset
}
node:OverrideMetatable {
__index = {
Calculate = function(self, a, b) end
},
}
return node()Getting it:
local node = Allure:Node() {} {}
node:UseMetatable {
__newindex = rawset
}
local mt = node:GetMetatable()
return node()This metatable is not present before finalization and will be applied only upon then.