Text size cache in chat corescript doesn't work

tl;dr the part of the chat corescript that tries to cache text sizes doesn’t work because a UDim2 is being used as an index in the cache table

In the process of making my own custom chat (with channels and whatnot) I discovered that ROBLOX used a text size cache so that subsequent calls to find the size of text didn’t need to go through all the effort they normally would and could just return the already-calculated value. I thought it was a wonderful idea and went to add a size cache to mine. After I was done, I (thankfully) decided to test the cache to see if it worked, even though my code ran fine with the change. When I started printing out whether or not text was cached, I got false every time.

The GetStringTextBounds function in the chat corescript accepts these parameters: text, font, fontSize, and sizeBounds (UDim2 value) (i.e. you can max out the width at 50 and have it wrap downwards), and the size cache is set up like so: SizeCache > Text > Font > SizeBounds > FontSize > CachedValue

Here's a visual representation of it: [code] sizeCache = { ["Sample Text"] = { [Enum.Font.SourceSansBold] = { [UDim2.new(x0,x1,y0,y1)] = { [Enum.FontSize.Size17] = Vector2.new(boundsX, boundsY); }; }; ... [Enum.Font.Legacy] = { ... }; }; ... ["Sample Text2"] = { ... }; } [/code]

The mistake I and whoever wrote that bit in the chat corescript made was that we tried to use a UDim2 value as an index. While UDim2.new(0,9,0,9) == UDim2.new(0,9,0,9) will return true, if you set the index of a table to UDim2.new(0,9,0,9) and then try to print table[UDim2.new(0,9,0,9)], the result is “nil”. I assume this happens for the same reason why == on two string objects with the same text will return false in Java/C, and that each call to UDim2.new creates a new object. The only reason equating them returns true (I assume) is because the == on those objects is overwritten with a function that returns true if the values are the same, and when you go to look up that value in the table/dictionary, it’s looking for the object of the UDim2 that was just created instead of the value.

How would this be circumvented? I guess make sizeBounds the final index in the cache and when it comes time to retrieve the value, instead of trying to directly access it, loop through the parent table and find a UDim2 index whose value is the same as what you’re trying to look up.
Edit: Sharksie had a better solution – store the index of sizeBounds as tostring(sizeBounds) since you can look up strings directly.

Another, but separate, issue is caching the value based on a UDim2 value. If you cache the value at size UDim2.new(1,0,0,36) and the user resizes their window horizontally, the width of UDim2.new(1,0,0,36) is not the same as it was before, and the cached value is now incorrect. Luckily, all uses of the GetStringTextBounds function in the corescript refrain from using scale and use only offset, converting scale to offset when necessary, so the cached values will always be correct currently since scale isn’t being used. However, if someone goes to work on the chat corescript in the future and isn’t aware of this, they may try caching a size using scale instead of just offset. The GetStringTextBounds function should either take a Vector2 to prevent that mistake from being made, or convert the UDim2 to a Vector2 inside the function before using that value to cache the size (would save whoever the trouble of manually converting UDim2s to Vector2s each time they wanted to use the function).

“Why u no use github?”
The chat bubbles are currently done C side but are being converted into a Lua corescript soon, and I’m not sure if the chat corescript is being updated alongside it. From what I heard, submitting pull requests when a corescript is being actively updated is generally frowned upon. On top of that, someone may post a better solution to the sizeBounds caching here than I was able to come up with.

A bit the same as everytime you index game.Changed, you get another object.
(But, as with your UDim2s, the __eq field makes the == return true)
The only times this is a real issue, is indeed when you use it as a table index.
(Can’t imagine you would use rawget in your code for testing these stuff)

Basicly, the corescript still has lots of issues that has to be fixed before release…

This is in the chat window/bar corescript that’s already released

Even worse…