@quenty/textserviceutils 7.8.0 → 7.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [7.9.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/textserviceutils@7.8.0...@quenty/textserviceutils@7.9.0) (2023-01-17)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * Fix issue where TextServiceUtils.promiseTextBounds(params) may stack overflow while processing text bounds workaround ([2c887fc](https://github.com/Quenty/NevermoreEngine/commit/2c887fce4b5a4b4a19ad2f68c84c591778b0e349))
12
+
13
+
14
+
15
+
16
+
6
17
  # [7.8.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/textserviceutils@7.7.0...@quenty/textserviceutils@7.8.0) (2023-01-11)
7
18
 
8
19
  **Note:** Version bump only for package @quenty/textserviceutils
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quenty/textserviceutils",
3
- "version": "7.8.0",
3
+ "version": "7.9.0",
4
4
  "description": "Holds utilities involving the Roblox TextService and text fitting to size.",
5
5
  "keywords": [
6
6
  "Roblox",
@@ -35,5 +35,5 @@
35
35
  "@quenty/promise": "^6.0.1",
36
36
  "@quenty/rx": "^7.4.0"
37
37
  },
38
- "gitHead": "db2db00ab4e24a3eab0449b77a00bee6d91f2755"
38
+ "gitHead": "a89a3f27cad25767cd645b91cdc2a2881afeecd5"
39
39
  }
@@ -34,7 +34,62 @@ function TextServiceUtils.getSizeForLabel(textLabel, text, maxWidth)
34
34
  return TextService:GetTextSize(text, textLabel.TextSize, textLabel.Font, Vector2.new(maxWidth, 1e6))
35
35
  end
36
36
 
37
- local lastPromise = nil
37
+ local queue = {}
38
+ local queueRunning = false
39
+
40
+ local function startQueueProcess()
41
+ if queueRunning then
42
+ return
43
+ end
44
+
45
+ queueRunning = true
46
+
47
+ task.spawn(function()
48
+ while #queue > 0 do
49
+ local data = table.remove(queue)
50
+ local startTime = os.clock()
51
+
52
+ local result = TextServiceUtils._promiseTextBounds(data.params)
53
+ local promiseTimeoutOrDone = Promise.new()
54
+
55
+ result:Then(function(v2)
56
+ task.spawn(function()
57
+ data.promise:Resolve(v2)
58
+ end)
59
+
60
+ promiseTimeoutOrDone:Resolve()
61
+ end)
62
+
63
+ local pendingTask = task.delay(5, function()
64
+ if data.promise:IsPending() then
65
+ warn("[TextServiceUtils] - Timed out promise while processing queue")
66
+ promiseTimeoutOrDone:Reject()
67
+ end
68
+ end)
69
+
70
+ local ok = promiseTimeoutOrDone:Yield()
71
+
72
+ -- Cancel our delayed task
73
+ task.cancel(pendingTask)
74
+
75
+ if not ok then
76
+ warn("[TextServiceUtils] - Requeuing entry")
77
+ table.insert(queue, data)
78
+
79
+ local timeElapsed = os.clock() - startTime
80
+ local remainingTime = 0.05 - timeElapsed
81
+
82
+ -- Yield incase we requeue very quickly
83
+ if remainingTime > 0 then
84
+ task.wait(remainingTime)
85
+ end
86
+ end
87
+
88
+ end
89
+
90
+ queueRunning = false
91
+ end)
92
+ end
38
93
 
39
94
  --[=[
40
95
  Promises the text bounds for the given parameters
@@ -47,39 +102,14 @@ function TextServiceUtils.promiseTextBounds(params)
47
102
 
48
103
  -- https://devforum.roblox.com/t/calling-textservicegettextboundsasync-multiple-times-leads-to-requests-never-completing-thread-leaks/2083178
49
104
  -- This is a hack to work around a Roblox bug.
50
- local promise
51
- if lastPromise then
52
- promise = lastPromise:Finally(function()
53
- return Promise.defer(function(resolve, reject)
54
- resolve(TextServiceUtils._promiseTextBounds(params))
55
-
56
- -- We don't want everything breaking
57
- task.delay(5, function()
58
- reject("Timed out")
59
- end)
60
- end)
61
- end)
62
- else
63
- promise = TextServiceUtils._promiseTextBounds(params)
64
105
 
65
- -- We don't want everything breaking
66
- task.delay(5, function()
67
- promise:Reject("Timed out")
68
- end)
69
- end
70
-
71
-
72
- -- Store this so we act as a queue :)
73
- lastPromise = promise
106
+ local promise = Promise.new()
107
+ table.insert(queue, {
108
+ params = params;
109
+ promise = promise;
110
+ })
74
111
 
75
- -- Clean up
76
- promise:Finally(function()
77
- task.defer(function()
78
- if lastPromise == promise then
79
- lastPromise = nil
80
- end
81
- end)
82
- end)
112
+ startQueueProcess();
83
113
 
84
114
  return promise
85
115
  end
@@ -156,7 +186,7 @@ function TextServiceUtils.observeSizeForLabelProps(props)
156
186
  local params = Instance.new("GetTextBoundsParams")
157
187
  params.Text = state.Text
158
188
  params.Size = state.TextSize
159
- params.Font = state.Font
189
+ params.Font = state.FontFace
160
190
  params.Width = state.MaxSize.x
161
191
 
162
192
  return Rx.fromPromise(TextServiceUtils.promiseTextBounds(params))
@@ -164,6 +194,9 @@ function TextServiceUtils.observeSizeForLabelProps(props)
164
194
  local size = TextService:GetTextSize(state.Text, state.TextSize, state.Font, state.MaxSize)
165
195
 
166
196
  return Rx.of(Vector2.new(size.x, state.LineHeight*size.y))
197
+ else
198
+ warn("[TextServiceUtils.observeSizeForLabelProps] - Got neither FontFace or Font")
199
+ return Rx.of(Vector2.new(0, 0))
167
200
  end
168
201
  end)
169
202
  })