General Use Cases:
Use this when you want to make any number of keys point to a singular value.
How It Works:
Key Linker Source Code HERE
Source Code
local HttpService = game:GetService("HttpService")
type Key = string | number | instance
type RawKey = string --GUUID
--Private
local function GarbageColectRefrences(self, RawKey)
if self.LinkedRefrences[RawKey] then
for i = #self.LinkedRefrences[RawKey], 1, -1 do
local Key = self.LinkedRefrences[RawKey][i]
self.LinkedRefrences[Key] = nil
table.remove(self.LinkedRefrences[RawKey], i)
end
end
end
local KeyLinker = {}
KeyLinker.__index = function(self, Key)
local RawKey = self.LinkedRefrences[Key]
return (KeyLinker[Key]) or (RawKey and self[RawKey])
end
KeyLinker.__newindex = function(self, Key, Value)
local LinkedRefrences = self.LinkedRefrences
--Cannot set nil value to nil
local OldRawKey = LinkedRefrences[Key]
if (not OldRawKey) and (not Value) then
return
end
if OldRawKey then
rawset(self, OldRawKey, Value)
--Delete it
if not Value then
GarbageColectRefrences(self, OldRawKey)
rawset(self, "Size", math.max(self.Size - 1, 0))
end
return
end
local RawKey = HttpService:GenerateGUID(false)
LinkedRefrences[RawKey] = {Key}
LinkedRefrences[Key] = RawKey
rawset(self, "Size", self.Size + 1)
rawset(self, RawKey, Value)
end
function KeyLinker.new()
return setmetatable({
LinkedRefrences = {} :: {[Key]: RawKey, [RawKey]: {Key}},
Size = 0
}, KeyLinker)
end
function KeyLinker:LinkRefrence(KeyToLinkTo: Key, NewKeys: {Key}) --use to remove refrence aswell
local LinkedRefrences = self.LinkedRefrences
local RawKey = LinkedRefrences[KeyToLinkTo]
if RawKey then
for _, NewKey: Key in NewKeys do
if not LinkedRefrences[NewKey] and LinkedRefrences[NewKey] ~= RawKey then
self:UnlinkRefrence(NewKey)
LinkedRefrences[NewKey] = RawKey
table.insert(LinkedRefrences[RawKey], NewKey)
end
end
else
warn(KeyToLinkTo, " is not a valid member of the DataBase")
end
end
function KeyLinker:UnlinkRefrence(Key: Key)
local LinkedRefrences = self.LinkedRefrences
local RawKey = LinkedRefrences[Key]
if RawKey then
local Pos = table.find(LinkedRefrences[RawKey], Key)
if Pos and Pos == 1 then --If its the only key
self[Key] = nil
else
if Pos then
table.remove(LinkedRefrences[RawKey], Pos)
end
LinkedRefrences[Key] = nil
end
end
end
return KeyLinker
KeyLinker Methods
--Allows new keys to point to the same value as an original key
LinkRefrence(OriginalKey: any, NewKeys: {[any]: any}): ()
--Removes any link the given Key had to any value
UnlinkRefrence(KeyToUnlink: any): ()
How to use and Tutorials:
Tutorial & Example 1 | Creating Key Links
In this example, I will show you how to add multiple keys to point to a single value.
So in this example, we are making a database where you want to assign both ProductID and ProductName to a single ProductData value.
Lets assume the product name is: "LightBulbs: and the product ID is: “0x234”.
local KeyLinker = require(game:GetService("ReplicatedStorage").SharedRefrences
local ProductData = KeyLinker.new()
ProductData.LightBulbs = {
["Price"] = 100
}
ProductData:LinkRefrence("LightBulbs", {"0x234"})
print(ProductData["0x234"].Price) --100
--Lets change the price of this product through the product ID
ProductData["0x234"].Price = 50
print(ProductData.LightBulbs.Price) --50
--Lets change the value of 0x234 to a string
ProductData["0x234"] = "Not Available"
print(ProductData.LightBulbs) --"Not Available"
We have linked both the ProductName “LightBulbs” to the ProductID “0x234”. As you can see, changing the value of the Key: “0x234” also changes the value of the key: “LightBulbs”. This is because they are linked.
Tutorial & Example 2 | Removing Key Links
In this tutorial I will show you how to remove a key link. The key link that is removed will then be able to be used for other links.
Lets say we have a database of roblox players.
DataBase:
Key | Player One | Player Two |
---|---|---|
UserID : | 10 | 20 |
UserName : | ChillGuy123 | SoloIsTheName321 |
DisplayName: | Chillest One | Solo Cord |
First lets create this database:
local PlayerDatabase = KeyLinker.new()
PlayerDatabase[10] = {
Username = "ChillGuy123",
DisplayName = "Chillest One",
UserId = 10
}
PlayerDatabase[20] = {
Username = "SoloIsTheName321",
DisplayName = "Solo Cord",
UserId = 20
}
--Link keys so I can access player data via Username, Displayname, or UserId
PlayerDatabase:LinkRefrence(10, {"ChillGuy123", "Chillest One"})
PlayerDatabase:LinkRefrence(20, {"Solo Cord", "SoloIsTheName321"})
Now, what if SoloIsTheName321 wants to change his username to SoloSoCool123
--Change SoloIsTheName321's username in the PlayerDataBase
PlayerDatabase[20].Username = "SoloSoCool123"
--Now can refrence data with: PlayerDatabase.SoloSoCool123
PlayerDatabase:LinkRefrence(20, {"SoloSoCool123"})
But the problem with this is that SoloIsTheName321 still points to SoloSoCool123 player data. Any assignment of PlayerDatabase.SoloIsTheName321 will still affect the database for SoloCord player data.
Solution: We need to Unlink this key from the database.
--Change SoloIsTheName321's username in the PlayerDataBase
PlayerDatabase[20].Username = "SoloSoCool123"
--Now can refrence data with: PlayerDatabase.SoloSoCool123
PlayerDatabase:LinkRefrence(20, {"SoloSoCool123"})
PlayerDatabase:UnlinkRefrence(20, {"SoloIsTheName321"})
Now SoloIsTheName321 will no longer point to any value and can now safely be used for new usernames.
FAQ
Question: What if I create a new key link that has the same name as another key link
Answer: The exsisting key link will automatically unlink from it’s original value.
Demonstration
local ProductDataBase = KeyLinker.new()
ProductDataBase["Apple"] = {
ProductName = "Apple",
ProductID = "Secret_AppleID",
Price = 15,
}
ProductDataBase["Orange"] = {
ProductName = "Orange",
ProductID = "Secret_OrangeID",
Price = 12,
}
ProductDataBase:LinkRefrence("Apple", {"Secret_AppleID"})
--Secret_AppleID will automatically be unlinked from the Apple key to avoid any issues
ProductDataBase:LinkRefrence("Orange", {"Secret_AppleID", "Secret_OrangeID"})
print(ProductDataBase["Secret_AppleID"]) --points to orange data
Question: How to get rid keys/values (Garbage Collecting)
Answer: By simply setting any linked key value to nil, each key link will be removed and the value will be set to nil.
Demonstration
local PlayerDatabase = KeyLinker.new()
PlayerDatabase[10] = {
Username = "ChillGuy123",
DisplayName = "Chillest One",
UserId = 10
}
--Link keys so I can access player data via Username, Displayname, or UserId
PlayerDatabase:LinkRefrence(10, {"ChillGuy123", "Chillest One"})
print(PlayerDatabase["ChillGuy123"]) --prints his data
--Lets delete ChillGuy123 from the database
PlayerDatabase["ChillGuy123"] = nil
print(PlayerDatabase[10]) --nil
print(PlayerDatabase["ChillGuy123"]) --nil
print(PlayerDatabase["Chillest One"]) --nil
Question: What if you remove all key links from a value
Answer: The value will simply be garbage collected
Issue to note
Unfortunatly I do not know how to allow autofill to work with this system. Please help me to find a way to resolve this. As of now this is the only issue.
Let me know what you think (this is my first ever community resource)
Would you use keylinker in your future projects?
- Yes
- Im Considering
- No because I don’t need it
- No because there are better alternatives
0 voters
The code for the module is at the top of this post