@quenty/settings 11.23.2-canary.547.ba47c62.0 → 11.23.3-canary.550.afa1b3b.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 +9 -1
- package/LICENSE.md +1 -1
- package/package.json +31 -31
- package/src/Client/Player/PlayerSettingsClient.lua +38 -13
- package/src/Client/SettingsServiceClient.lua +53 -15
- package/src/Server/Player/PlayerHasSettings.lua +9 -0
- package/src/Server/Player/PlayerSettings.lua +35 -9
- package/src/Shared/Player/PlayerSettingsBase.lua +23 -14
- package/src/Shared/Player/PlayerSettingsConstants.lua +1 -0
- package/src/Shared/Player/PlayerSettingsUtils.lua +9 -8
- package/src/Shared/Setting/SettingProperty.lua +67 -40
- package/src/Shared/SettingsDataService.lua +7 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,7 +3,15 @@
|
|
|
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
|
-
## [11.23.
|
|
6
|
+
## [11.23.3-canary.550.afa1b3b.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/settings@11.23.2...@quenty/settings@11.23.3-canary.550.afa1b3b.0) (2025-04-10)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @quenty/settings
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [11.23.2](https://github.com/Quenty/NevermoreEngine/compare/@quenty/settings@11.23.0...@quenty/settings@11.23.2) (2025-04-07)
|
|
7
15
|
|
|
8
16
|
|
|
9
17
|
### Bug Fixes
|
package/LICENSE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2014-
|
|
3
|
+
Copyright (c) 2014-2025 James Onnen (Quenty)
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/settings",
|
|
3
|
-
"version": "11.23.
|
|
3
|
+
"version": "11.23.3-canary.550.afa1b3b.0",
|
|
4
4
|
"description": "Centralized player settings service",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -25,38 +25,38 @@
|
|
|
25
25
|
"Quenty"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@quenty/attributeutils": "14.17.
|
|
29
|
-
"@quenty/baseobject": "10.8.
|
|
30
|
-
"@quenty/binder": "14.19.
|
|
31
|
-
"@quenty/brio": "14.17.
|
|
32
|
-
"@quenty/cmdrservice": "13.22.
|
|
33
|
-
"@quenty/datastore": "13.20.
|
|
34
|
-
"@quenty/ducktype": "5.8.
|
|
35
|
-
"@quenty/enumutils": "3.4.2
|
|
36
|
-
"@quenty/instanceutils": "13.17.
|
|
37
|
-
"@quenty/jsonutils": "10.10.
|
|
38
|
-
"@quenty/loader": "10.8.
|
|
39
|
-
"@quenty/maid": "3.4.
|
|
40
|
-
"@quenty/observablecollection": "12.20.
|
|
41
|
-
"@quenty/playerbinder": "14.19.
|
|
42
|
-
"@quenty/playerutils": "8.17.
|
|
43
|
-
"@quenty/remotefunctionutils": "10.10.
|
|
44
|
-
"@quenty/remoting": "12.18.
|
|
45
|
-
"@quenty/rx": "13.17.
|
|
46
|
-
"@quenty/rxbinderutils": "14.19.
|
|
47
|
-
"@quenty/rxsignal": "7.17.
|
|
48
|
-
"@quenty/servicebag": "11.11.
|
|
49
|
-
"@quenty/signal": "7.10.
|
|
50
|
-
"@quenty/statestack": "14.18.
|
|
51
|
-
"@quenty/string": "3.3.3
|
|
52
|
-
"@quenty/symbol": "3.4.2
|
|
53
|
-
"@quenty/table": "3.7.
|
|
54
|
-
"@quenty/throttle": "10.9.
|
|
55
|
-
"@quenty/tie": "10.20.
|
|
56
|
-
"@quenty/valueobject": "13.17.
|
|
28
|
+
"@quenty/attributeutils": "14.17.3-canary.550.afa1b3b.0",
|
|
29
|
+
"@quenty/baseobject": "10.8.3-canary.550.afa1b3b.0",
|
|
30
|
+
"@quenty/binder": "14.19.3-canary.550.afa1b3b.0",
|
|
31
|
+
"@quenty/brio": "14.17.3-canary.550.afa1b3b.0",
|
|
32
|
+
"@quenty/cmdrservice": "13.22.3-canary.550.afa1b3b.0",
|
|
33
|
+
"@quenty/datastore": "13.20.3-canary.550.afa1b3b.0",
|
|
34
|
+
"@quenty/ducktype": "5.8.4-canary.550.afa1b3b.0",
|
|
35
|
+
"@quenty/enumutils": "3.4.2",
|
|
36
|
+
"@quenty/instanceutils": "13.17.3-canary.550.afa1b3b.0",
|
|
37
|
+
"@quenty/jsonutils": "10.10.4-canary.550.afa1b3b.0",
|
|
38
|
+
"@quenty/loader": "10.8.3-canary.550.afa1b3b.0",
|
|
39
|
+
"@quenty/maid": "3.4.3-canary.550.afa1b3b.0",
|
|
40
|
+
"@quenty/observablecollection": "12.20.3-canary.550.afa1b3b.0",
|
|
41
|
+
"@quenty/playerbinder": "14.19.3-canary.550.afa1b3b.0",
|
|
42
|
+
"@quenty/playerutils": "8.17.3-canary.550.afa1b3b.0",
|
|
43
|
+
"@quenty/remotefunctionutils": "10.10.4-canary.550.afa1b3b.0",
|
|
44
|
+
"@quenty/remoting": "12.18.3-canary.550.afa1b3b.0",
|
|
45
|
+
"@quenty/rx": "13.17.3-canary.550.afa1b3b.0",
|
|
46
|
+
"@quenty/rxbinderutils": "14.19.3-canary.550.afa1b3b.0",
|
|
47
|
+
"@quenty/rxsignal": "7.17.3-canary.550.afa1b3b.0",
|
|
48
|
+
"@quenty/servicebag": "11.11.4-canary.550.afa1b3b.0",
|
|
49
|
+
"@quenty/signal": "7.10.3-canary.550.afa1b3b.0",
|
|
50
|
+
"@quenty/statestack": "14.18.3-canary.550.afa1b3b.0",
|
|
51
|
+
"@quenty/string": "3.3.3",
|
|
52
|
+
"@quenty/symbol": "3.4.2",
|
|
53
|
+
"@quenty/table": "3.7.4-canary.550.afa1b3b.0",
|
|
54
|
+
"@quenty/throttle": "10.9.3-canary.550.afa1b3b.0",
|
|
55
|
+
"@quenty/tie": "10.20.3-canary.550.afa1b3b.0",
|
|
56
|
+
"@quenty/valueobject": "13.17.3-canary.550.afa1b3b.0"
|
|
57
57
|
},
|
|
58
58
|
"publishConfig": {
|
|
59
59
|
"access": "public"
|
|
60
60
|
},
|
|
61
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "afa1b3b99b862698c3ab46009497bd507150867c"
|
|
62
62
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
A player's current settings. Handles replication back to the server
|
|
3
4
|
when a setting changes. See [PlayerSettingsBase].
|
|
@@ -22,6 +23,8 @@ local Remoting = require("Remoting")
|
|
|
22
23
|
local Symbol = require("Symbol")
|
|
23
24
|
local ThrottledFunction = require("ThrottledFunction")
|
|
24
25
|
local ValueObject = require("ValueObject")
|
|
26
|
+
local _ServiceBag = require("ServiceBag")
|
|
27
|
+
local _Promise = require("Promise")
|
|
25
28
|
|
|
26
29
|
local UNSET_VALUE = Symbol.named("unsetValue")
|
|
27
30
|
|
|
@@ -29,6 +32,18 @@ local PlayerSettingsClient = setmetatable({}, PlayerSettingsBase)
|
|
|
29
32
|
PlayerSettingsClient.ClassName = "PlayerSettingsClient"
|
|
30
33
|
PlayerSettingsClient.__index = PlayerSettingsClient
|
|
31
34
|
|
|
35
|
+
export type PlayerSettingsClient = typeof(setmetatable(
|
|
36
|
+
{} :: {
|
|
37
|
+
_remoting: Remoting.Remoting,
|
|
38
|
+
_pendingReplicationDataInTransit: ValueObject.ValueObject<any>,
|
|
39
|
+
_toReplicate: { [any]: any? }?,
|
|
40
|
+
_toReplicateCallbacks: { [string]: { [any]: any } },
|
|
41
|
+
_currentReplicationRequest: _Promise.Promise<()>?,
|
|
42
|
+
_queueSendSettingsFunc: ThrottledFunction.ThrottledFunction<()>,
|
|
43
|
+
},
|
|
44
|
+
{} :: typeof({ __index = PlayerSettingsClient })
|
|
45
|
+
)) & PlayerSettingsBase.PlayerSettingsBase
|
|
46
|
+
|
|
32
47
|
--[=[
|
|
33
48
|
See [SettingsBindersClient] and [SettingsServiceClient] on how to properly use this class.
|
|
34
49
|
|
|
@@ -36,8 +51,9 @@ PlayerSettingsClient.__index = PlayerSettingsClient
|
|
|
36
51
|
@param serviceBag ServiceBag
|
|
37
52
|
@return PlayerSettingsClient
|
|
38
53
|
]=]
|
|
39
|
-
function PlayerSettingsClient.new(folder, serviceBag)
|
|
40
|
-
local self =
|
|
54
|
+
function PlayerSettingsClient.new(folder: Folder, serviceBag: _ServiceBag.ServiceBag): PlayerSettingsClient
|
|
55
|
+
local self: PlayerSettingsClient =
|
|
56
|
+
setmetatable(PlayerSettingsBase.new(folder, serviceBag) :: any, PlayerSettingsClient)
|
|
41
57
|
|
|
42
58
|
if self:GetPlayer() == Players.LocalPlayer then
|
|
43
59
|
self._remoting = self._maid:Add(Remoting.new(self._obj, "PlayerSettings", Remoting.Realms.CLIENT))
|
|
@@ -69,7 +85,7 @@ end
|
|
|
69
85
|
@param defaultValue T
|
|
70
86
|
@return T
|
|
71
87
|
]=]
|
|
72
|
-
function PlayerSettingsClient
|
|
88
|
+
function PlayerSettingsClient.GetValue<T>(self: PlayerSettingsClient, settingName: string, defaultValue: T): T
|
|
73
89
|
assert(type(settingName) == "string", "Bad settingName")
|
|
74
90
|
|
|
75
91
|
if self._toReplicate and self._toReplicate[settingName] ~= nil then
|
|
@@ -91,7 +107,11 @@ end
|
|
|
91
107
|
@param defaultValue T
|
|
92
108
|
@return Observable<T>
|
|
93
109
|
]=]
|
|
94
|
-
function PlayerSettingsClient
|
|
110
|
+
function PlayerSettingsClient.ObserveValue<T>(
|
|
111
|
+
self: PlayerSettingsClient,
|
|
112
|
+
settingName: string,
|
|
113
|
+
defaultValue: T
|
|
114
|
+
): Observable.Observable<T>
|
|
95
115
|
assert(type(settingName) == "string", "Bad settingName")
|
|
96
116
|
|
|
97
117
|
local baseObservable = getmetatable(PlayerSettingsClient).ObserveValue(self, settingName, defaultValue)
|
|
@@ -149,11 +169,12 @@ function PlayerSettingsClient:ObserveValue(settingName, defaultValue)
|
|
|
149
169
|
maid:GiveTask(baseObservable:Subscribe(function(newValue)
|
|
150
170
|
lastObservedValue = newValue
|
|
151
171
|
update()
|
|
152
|
-
end
|
|
172
|
+
end, sub:GetFailComplete()))
|
|
173
|
+
|
|
153
174
|
update()
|
|
154
175
|
|
|
155
176
|
return maid
|
|
156
|
-
end)
|
|
177
|
+
end) :: any
|
|
157
178
|
end
|
|
158
179
|
|
|
159
180
|
--[=[
|
|
@@ -162,7 +183,7 @@ end
|
|
|
162
183
|
@param settingName string
|
|
163
184
|
@param value T
|
|
164
185
|
]=]
|
|
165
|
-
function PlayerSettingsClient
|
|
186
|
+
function PlayerSettingsClient.SetValue<T>(self: PlayerSettingsClient, settingName: string, value: T): ()
|
|
166
187
|
assert(type(settingName) == "string", "Bad settingName")
|
|
167
188
|
assert(self:GetPlayer() == Players.LocalPlayer, "Cannot set settings of another player")
|
|
168
189
|
assert(DataStoreStringUtils.isValidUTF8(settingName), "Bad settingName")
|
|
@@ -176,12 +197,16 @@ function PlayerSettingsClient:SetValue(settingName, value)
|
|
|
176
197
|
end
|
|
177
198
|
|
|
178
199
|
local queueReplication = false
|
|
179
|
-
|
|
180
|
-
|
|
200
|
+
local toReplicate
|
|
201
|
+
if self._toReplicate then
|
|
202
|
+
toReplicate = self._toReplicate
|
|
203
|
+
else
|
|
204
|
+
toReplicate = {}
|
|
205
|
+
self._toReplicate = toReplicate
|
|
181
206
|
queueReplication = true
|
|
182
207
|
end
|
|
183
208
|
|
|
184
|
-
|
|
209
|
+
toReplicate[settingName] = PlayerSettingsUtils.encodeForNetwork(value)
|
|
185
210
|
|
|
186
211
|
if self._toReplicateCallbacks[settingName] then
|
|
187
212
|
for callback, _ in self._toReplicateCallbacks[settingName] do
|
|
@@ -203,7 +228,7 @@ function PlayerSettingsClient:SetValue(settingName, value)
|
|
|
203
228
|
end
|
|
204
229
|
end
|
|
205
230
|
|
|
206
|
-
function PlayerSettingsClient
|
|
231
|
+
function PlayerSettingsClient._sendSettings(self: PlayerSettingsClient)
|
|
207
232
|
if not self._toReplicate then
|
|
208
233
|
warn("Nothing to save, should not have called this method")
|
|
209
234
|
return
|
|
@@ -228,10 +253,10 @@ function PlayerSettingsClient:_sendSettings()
|
|
|
228
253
|
return promise
|
|
229
254
|
end
|
|
230
255
|
|
|
231
|
-
function PlayerSettingsClient
|
|
256
|
+
function PlayerSettingsClient._promiseReplicateSettings(self: PlayerSettingsClient, settingsMap)
|
|
232
257
|
assert(type(settingsMap) == "table", "Bad settingsMap")
|
|
233
258
|
|
|
234
259
|
return self._remoting.RequestUpdateSettings:PromiseInvokeServer(settingsMap)
|
|
235
260
|
end
|
|
236
261
|
|
|
237
|
-
return Binder.new("PlayerSettings", PlayerSettingsClient)
|
|
262
|
+
return Binder.new("PlayerSettings", PlayerSettingsClient :: any) :: Binder.Binder<PlayerSettingsClient>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Provides access to settings on the client. See [SettingDefinition] which should
|
|
3
4
|
register settings on the server. See [SettingsService] for server component.
|
|
@@ -13,16 +14,30 @@ local Players = game:GetService("Players")
|
|
|
13
14
|
local Maid = require("Maid")
|
|
14
15
|
local SettingsCmdrUtils = require("SettingsCmdrUtils")
|
|
15
16
|
local _ServiceBag = require("ServiceBag")
|
|
17
|
+
local _PlayerSettingsClient = require("PlayerSettingsClient")
|
|
18
|
+
local _Observable = require("Observable")
|
|
19
|
+
local _Brio = require("Brio")
|
|
20
|
+
local _CancelToken = require("CancelToken")
|
|
21
|
+
local _Promise = require("Promise")
|
|
16
22
|
|
|
17
23
|
local SettingsServiceClient = {}
|
|
18
24
|
|
|
25
|
+
export type SettingsServiceClient = typeof(setmetatable(
|
|
26
|
+
{} :: {
|
|
27
|
+
_serviceBag: _ServiceBag.ServiceBag,
|
|
28
|
+
_maid: Maid.Maid,
|
|
29
|
+
_settingsDataService: any,
|
|
30
|
+
},
|
|
31
|
+
{} :: typeof({ __index = SettingsServiceClient })
|
|
32
|
+
))
|
|
33
|
+
|
|
19
34
|
--[=[
|
|
20
35
|
Initializes the setting service. Should be done via ServiceBag.
|
|
21
36
|
|
|
22
37
|
@param serviceBag ServiceBag
|
|
23
38
|
]=]
|
|
24
|
-
function SettingsServiceClient
|
|
25
|
-
assert(not self._serviceBag, "Already initialized")
|
|
39
|
+
function SettingsServiceClient.Init(self: SettingsServiceClient, serviceBag: _ServiceBag.ServiceBag)
|
|
40
|
+
assert(not (self :: any)._serviceBag, "Already initialized")
|
|
26
41
|
self._serviceBag = assert(serviceBag, "No serviceBag")
|
|
27
42
|
self._maid = Maid.new()
|
|
28
43
|
|
|
@@ -36,7 +51,7 @@ function SettingsServiceClient:Init(serviceBag: _ServiceBag.ServiceBag)
|
|
|
36
51
|
self._serviceBag:GetService(require("PlayerSettingsClient"))
|
|
37
52
|
end
|
|
38
53
|
|
|
39
|
-
function SettingsServiceClient
|
|
54
|
+
function SettingsServiceClient.Start(self: SettingsServiceClient)
|
|
40
55
|
self:_setupCmdr()
|
|
41
56
|
end
|
|
42
57
|
|
|
@@ -44,7 +59,9 @@ end
|
|
|
44
59
|
Gets the local player settings
|
|
45
60
|
@return PlayerSettingsClient | nil
|
|
46
61
|
]=]
|
|
47
|
-
function SettingsServiceClient
|
|
62
|
+
function SettingsServiceClient.GetLocalPlayerSettings(
|
|
63
|
+
self: SettingsServiceClient
|
|
64
|
+
): _PlayerSettingsClient.PlayerSettingsClient?
|
|
48
65
|
return self:GetPlayerSettings(Players.LocalPlayer)
|
|
49
66
|
end
|
|
50
67
|
|
|
@@ -53,7 +70,9 @@ end
|
|
|
53
70
|
|
|
54
71
|
@return Observable<Brio<PlayerSettingsClient>>
|
|
55
72
|
]=]
|
|
56
|
-
function SettingsServiceClient
|
|
73
|
+
function SettingsServiceClient.ObserveLocalPlayerSettingsBrio(self: SettingsServiceClient): _Observable.Observable<
|
|
74
|
+
_Brio.Brio<_PlayerSettingsClient.PlayerSettingsClient>
|
|
75
|
+
>
|
|
57
76
|
return self:ObservePlayerSettingsBrio(Players.LocalPlayer)
|
|
58
77
|
end
|
|
59
78
|
|
|
@@ -62,7 +81,9 @@ end
|
|
|
62
81
|
|
|
63
82
|
@return Observable<PlayerSettingsClient | nil>
|
|
64
83
|
]=]
|
|
65
|
-
function SettingsServiceClient
|
|
84
|
+
function SettingsServiceClient.ObserveLocalPlayerSettings(self: SettingsServiceClient): _Observable.Observable<
|
|
85
|
+
_PlayerSettingsClient.PlayerSettingsClient
|
|
86
|
+
>
|
|
66
87
|
return self:ObservePlayerSettings(Players.LocalPlayer)
|
|
67
88
|
end
|
|
68
89
|
|
|
@@ -72,7 +93,10 @@ end
|
|
|
72
93
|
@param cancelToken CancellationToken
|
|
73
94
|
@return Promise<PlayerSettingsClient>
|
|
74
95
|
]=]
|
|
75
|
-
function SettingsServiceClient
|
|
96
|
+
function SettingsServiceClient.PromiseLocalPlayerSettings(
|
|
97
|
+
self: SettingsServiceClient,
|
|
98
|
+
cancelToken: _CancelToken.CancelToken
|
|
99
|
+
): _Promise.Promise<_PlayerSettingsClient.PlayerSettingsClient>
|
|
76
100
|
return self:PromisePlayerSettings(Players.LocalPlayer, cancelToken)
|
|
77
101
|
end
|
|
78
102
|
|
|
@@ -82,7 +106,10 @@ end
|
|
|
82
106
|
@param player Player
|
|
83
107
|
@return Observable<PlayerSettingsClient | nil>
|
|
84
108
|
]=]
|
|
85
|
-
function SettingsServiceClient
|
|
109
|
+
function SettingsServiceClient.ObservePlayerSettings(
|
|
110
|
+
self: SettingsServiceClient,
|
|
111
|
+
player: Player
|
|
112
|
+
): _Observable.Observable<_PlayerSettingsClient.PlayerSettingsClient>
|
|
86
113
|
assert(typeof(player) == "Instance" and player:IsA("Player"), "Bad player")
|
|
87
114
|
|
|
88
115
|
return self._settingsDataService:ObservePlayerSettings(player)
|
|
@@ -94,7 +121,12 @@ end
|
|
|
94
121
|
@param player Player
|
|
95
122
|
@return Observable<Brio<PlayerSettingsClient>>
|
|
96
123
|
]=]
|
|
97
|
-
function SettingsServiceClient
|
|
124
|
+
function SettingsServiceClient.ObservePlayerSettingsBrio(
|
|
125
|
+
self: SettingsServiceClient,
|
|
126
|
+
player: Player
|
|
127
|
+
): _Observable.Observable<
|
|
128
|
+
_Brio.Brio<_PlayerSettingsClient.PlayerSettingsClient>
|
|
129
|
+
>
|
|
98
130
|
assert(typeof(player) == "Instance" and player:IsA("Player"), "Bad player")
|
|
99
131
|
|
|
100
132
|
return self._settingsDataService:ObservePlayerSettingsBrio(player)
|
|
@@ -106,7 +138,10 @@ end
|
|
|
106
138
|
@param player Player
|
|
107
139
|
@return PlayerSettingsClient | nil
|
|
108
140
|
]=]
|
|
109
|
-
function SettingsServiceClient
|
|
141
|
+
function SettingsServiceClient.GetPlayerSettings(
|
|
142
|
+
self: SettingsServiceClient,
|
|
143
|
+
player: Player
|
|
144
|
+
): _PlayerSettingsClient.PlayerSettingsClient?
|
|
110
145
|
assert(typeof(player) == "Instance" and player:IsA("Player"), "Bad player")
|
|
111
146
|
|
|
112
147
|
return self._settingsDataService:GetPlayerSettings(player)
|
|
@@ -119,14 +154,17 @@ end
|
|
|
119
154
|
@param cancelToken CancellationToken
|
|
120
155
|
@return Promise<PlayerSettingsClient>
|
|
121
156
|
]=]
|
|
122
|
-
function SettingsServiceClient
|
|
157
|
+
function SettingsServiceClient.PromisePlayerSettings(
|
|
158
|
+
self: SettingsServiceClient,
|
|
159
|
+
player: Player,
|
|
160
|
+
cancelToken: _CancelToken.CancelToken
|
|
161
|
+
): _Promise.Promise<_PlayerSettingsClient.PlayerSettingsClient>
|
|
123
162
|
assert(typeof(player) == "Instance" and player:IsA("Player"), "Bad player")
|
|
124
163
|
|
|
125
164
|
return self._settingsDataService:PromisePlayerSettings(player, cancelToken)
|
|
126
165
|
end
|
|
127
166
|
|
|
128
|
-
|
|
129
|
-
function SettingsServiceClient:_setupCmdr()
|
|
167
|
+
function SettingsServiceClient._setupCmdr(self: SettingsServiceClient)
|
|
130
168
|
local cmdrServiceClient = self._serviceBag:GetService(require("CmdrServiceClient"))
|
|
131
169
|
|
|
132
170
|
self._maid:GivePromise(cmdrServiceClient:PromiseCmdr()):Then(function(cmdr)
|
|
@@ -134,8 +172,8 @@ function SettingsServiceClient:_setupCmdr()
|
|
|
134
172
|
end)
|
|
135
173
|
end
|
|
136
174
|
|
|
137
|
-
function SettingsServiceClient
|
|
175
|
+
function SettingsServiceClient.Destroy(self: SettingsServiceClient)
|
|
138
176
|
self._maid:DoCleaning()
|
|
139
177
|
end
|
|
140
178
|
|
|
141
|
-
return SettingsServiceClient
|
|
179
|
+
return SettingsServiceClient
|
|
@@ -16,6 +16,15 @@ local PlayerHasSettings = setmetatable({}, BaseObject)
|
|
|
16
16
|
PlayerHasSettings.ClassName = "PlayerHasSettings"
|
|
17
17
|
PlayerHasSettings.__index = PlayerHasSettings
|
|
18
18
|
|
|
19
|
+
export type PlayerHasSettings = typeof(setmetatable(
|
|
20
|
+
{} :: {
|
|
21
|
+
_serviceBag: any,
|
|
22
|
+
_playerSettingsBinder: PlayerSettings.PlayerSettings,
|
|
23
|
+
_playerDataStoreService: PlayerDataStoreService.PlayerDataStoreService,
|
|
24
|
+
},
|
|
25
|
+
{} :: typeof({ __index = PlayerHasSettings })
|
|
26
|
+
)) & BaseObject.BaseObject
|
|
27
|
+
|
|
19
28
|
function PlayerHasSettings.new(player: Player, serviceBag)
|
|
20
29
|
local self = setmetatable(BaseObject.new(player), PlayerHasSettings)
|
|
21
30
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
@class PlayerSettings
|
|
3
4
|
]=]
|
|
@@ -12,13 +13,23 @@ local PlayerSettingsInterface = require("PlayerSettingsInterface")
|
|
|
12
13
|
local PlayerSettingsUtils = require("PlayerSettingsUtils")
|
|
13
14
|
local Remoting = require("Remoting")
|
|
14
15
|
local SettingsDataService = require("SettingsDataService")
|
|
16
|
+
local _ServiceBag = require("ServiceBag")
|
|
15
17
|
|
|
16
18
|
local PlayerSettings = setmetatable({}, PlayerSettingsBase)
|
|
17
19
|
PlayerSettings.ClassName = "PlayerSettings"
|
|
18
20
|
PlayerSettings.__index = PlayerSettings
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
export type PlayerSettings = typeof(setmetatable(
|
|
23
|
+
{} :: {
|
|
24
|
+
_serviceBag: any,
|
|
25
|
+
_remoting: Remoting.Remoting,
|
|
26
|
+
_settingsDataService: SettingsDataService.SettingsDataService,
|
|
27
|
+
},
|
|
28
|
+
{} :: typeof({ __index = PlayerSettings })
|
|
29
|
+
)) & PlayerSettingsBase.PlayerSettingsBase
|
|
30
|
+
|
|
31
|
+
function PlayerSettings.new(folder: Folder, serviceBag: _ServiceBag.ServiceBag)
|
|
32
|
+
local self: PlayerSettings = setmetatable(PlayerSettingsBase.new(folder, serviceBag) :: any, PlayerSettings)
|
|
22
33
|
|
|
23
34
|
self._serviceBag = assert(serviceBag, "No serviceBag")
|
|
24
35
|
self._settingsDataService = self._serviceBag:GetService(SettingsDataService)
|
|
@@ -39,7 +50,7 @@ function PlayerSettings.new(obj, serviceBag)
|
|
|
39
50
|
return self
|
|
40
51
|
end
|
|
41
52
|
|
|
42
|
-
function PlayerSettings
|
|
53
|
+
function PlayerSettings.EnsureInitialized(self: PlayerSettings, settingName: string, defaultValue)
|
|
43
54
|
assert(DataStoreStringUtils.isValidUTF8(settingName), "Bad settingName")
|
|
44
55
|
assert(defaultValue ~= nil, "defaultValue cannot be nil")
|
|
45
56
|
|
|
@@ -62,7 +73,7 @@ function PlayerSettings:EnsureInitialized(settingName, defaultValue)
|
|
|
62
73
|
end
|
|
63
74
|
end
|
|
64
75
|
|
|
65
|
-
function PlayerSettings
|
|
76
|
+
function PlayerSettings._setupRemoting(self: PlayerSettings)
|
|
66
77
|
self._remoting = self._maid:Add(Remoting.new(self._obj, "PlayerSettings", Remoting.Realms.SERVER))
|
|
67
78
|
|
|
68
79
|
self._maid:Add(self._remoting.RequestUpdateSettings:Bind(function(player, settingsMap)
|
|
@@ -72,7 +83,7 @@ function PlayerSettings:_setupRemoting()
|
|
|
72
83
|
end))
|
|
73
84
|
end
|
|
74
85
|
|
|
75
|
-
function PlayerSettings
|
|
86
|
+
function PlayerSettings._setSettingsMap(self: PlayerSettings, settingsMap)
|
|
76
87
|
assert(type(settingsMap) == "table", "Bad settingsMap")
|
|
77
88
|
|
|
78
89
|
for settingName, value in settingsMap do
|
|
@@ -87,14 +98,24 @@ function PlayerSettings:_setSettingsMap(settingsMap)
|
|
|
87
98
|
local attributeName = PlayerSettingsUtils.getAttributeName(settingName)
|
|
88
99
|
|
|
89
100
|
if self._obj:GetAttribute(attributeName) == nil then
|
|
90
|
-
warn(
|
|
101
|
+
warn(
|
|
102
|
+
string.format(
|
|
103
|
+
"[PlayerSettings] - Cannot set setting %q on attribute that is not defined on the server.",
|
|
104
|
+
attributeName
|
|
105
|
+
)
|
|
106
|
+
)
|
|
91
107
|
continue
|
|
92
108
|
end
|
|
93
109
|
|
|
94
110
|
-- Paranoid UTF8 check. Avoid letting this value be set.
|
|
95
111
|
if type(value) == "string" then
|
|
96
112
|
if not DataStoreStringUtils.isValidUTF8(value) then
|
|
97
|
-
warn(
|
|
113
|
+
warn(
|
|
114
|
+
string.format(
|
|
115
|
+
"[PlayerSettings] - Bad UTF8 value setting value for %q. Skipping setting.",
|
|
116
|
+
settingName
|
|
117
|
+
)
|
|
118
|
+
)
|
|
98
119
|
continue
|
|
99
120
|
end
|
|
100
121
|
end
|
|
@@ -105,7 +126,12 @@ function PlayerSettings:_setSettingsMap(settingsMap)
|
|
|
105
126
|
if type(encodedAttribute) == "string" then
|
|
106
127
|
-- Paranoid UTF8 check. Avoid letting this value be set.
|
|
107
128
|
if not DataStoreStringUtils.isValidUTF8(encodedAttribute) then
|
|
108
|
-
warn(
|
|
129
|
+
warn(
|
|
130
|
+
string.format(
|
|
131
|
+
"[PlayerSettings] - Bad UTF8 encodedAttribute value for %q. Skipping setting.",
|
|
132
|
+
settingName
|
|
133
|
+
)
|
|
134
|
+
)
|
|
109
135
|
continue
|
|
110
136
|
end
|
|
111
137
|
|
|
@@ -120,4 +146,4 @@ function PlayerSettings:_setSettingsMap(settingsMap)
|
|
|
120
146
|
end
|
|
121
147
|
end
|
|
122
148
|
|
|
123
|
-
return Binder.new("PlayerSettings", PlayerSettings)
|
|
149
|
+
return Binder.new("PlayerSettings", PlayerSettings :: any) :: Binder.Binder<PlayerSettings>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Base class for player settings.
|
|
3
4
|
|
|
@@ -12,11 +13,20 @@ local RxAttributeUtils = require("RxAttributeUtils")
|
|
|
12
13
|
local SettingDefinition = require("SettingDefinition")
|
|
13
14
|
local Rx = require("Rx")
|
|
14
15
|
local DataStoreStringUtils = require("DataStoreStringUtils")
|
|
16
|
+
local _ServiceBag = require("ServiceBag")
|
|
15
17
|
|
|
16
18
|
local PlayerSettingsBase = setmetatable({}, BaseObject)
|
|
17
19
|
PlayerSettingsBase.ClassName = "PlayerSettingsBase"
|
|
18
20
|
PlayerSettingsBase.__index = PlayerSettingsBase
|
|
19
21
|
|
|
22
|
+
export type PlayerSettingsBase = typeof(setmetatable(
|
|
23
|
+
{} :: {
|
|
24
|
+
_obj: Folder,
|
|
25
|
+
_serviceBag: _ServiceBag.ServiceBag,
|
|
26
|
+
},
|
|
27
|
+
{} :: typeof({ __index = PlayerSettingsBase })
|
|
28
|
+
)) & BaseObject.BaseObject
|
|
29
|
+
|
|
20
30
|
--[=[
|
|
21
31
|
Base class for player settings
|
|
22
32
|
|
|
@@ -24,8 +34,8 @@ PlayerSettingsBase.__index = PlayerSettingsBase
|
|
|
24
34
|
@param serviceBag ServiceBag
|
|
25
35
|
@return PlayerSettingsBase
|
|
26
36
|
]=]
|
|
27
|
-
function PlayerSettingsBase.new(folder, serviceBag)
|
|
28
|
-
local self = setmetatable(BaseObject.new(folder), PlayerSettingsBase)
|
|
37
|
+
function PlayerSettingsBase.new(folder: Folder, serviceBag: _ServiceBag.ServiceBag): PlayerSettingsBase
|
|
38
|
+
local self: PlayerSettingsBase = setmetatable(BaseObject.new(folder) :: any, PlayerSettingsBase)
|
|
29
39
|
|
|
30
40
|
self._serviceBag = assert(serviceBag, "No serviceBag")
|
|
31
41
|
|
|
@@ -36,7 +46,7 @@ end
|
|
|
36
46
|
Gets the player for this setting
|
|
37
47
|
@return Player
|
|
38
48
|
]=]
|
|
39
|
-
function PlayerSettingsBase
|
|
49
|
+
function PlayerSettingsBase.GetPlayer(self: PlayerSettingsBase): Player?
|
|
40
50
|
return self._obj:FindFirstAncestorWhichIsA("Player")
|
|
41
51
|
end
|
|
42
52
|
|
|
@@ -44,7 +54,7 @@ end
|
|
|
44
54
|
Gets the settings folder
|
|
45
55
|
@return Folder
|
|
46
56
|
]=]
|
|
47
|
-
function PlayerSettingsBase
|
|
57
|
+
function PlayerSettingsBase.GetFolder(self: PlayerSettingsBase): Folder
|
|
48
58
|
return self._obj
|
|
49
59
|
end
|
|
50
60
|
|
|
@@ -56,7 +66,7 @@ end
|
|
|
56
66
|
@param defaultValue any
|
|
57
67
|
@return SettingProperty
|
|
58
68
|
]=]
|
|
59
|
-
function PlayerSettingsBase
|
|
69
|
+
function PlayerSettingsBase.GetSettingProperty(self: PlayerSettingsBase, settingName: string, defaultValue)
|
|
60
70
|
assert(type(settingName) == "string", "Bad settingName")
|
|
61
71
|
assert(defaultValue ~= nil, "defaultValue cannot be nil")
|
|
62
72
|
|
|
@@ -72,7 +82,7 @@ end
|
|
|
72
82
|
@param defaultValue any
|
|
73
83
|
@return any
|
|
74
84
|
]=]
|
|
75
|
-
function PlayerSettingsBase
|
|
85
|
+
function PlayerSettingsBase.GetValue(self: PlayerSettingsBase, settingName: string, defaultValue)
|
|
76
86
|
assert(type(settingName) == "string", "Bad settingName")
|
|
77
87
|
assert(defaultValue ~= nil, "defaultValue cannot be nil")
|
|
78
88
|
assert(DataStoreStringUtils.isValidUTF8(settingName), "Bad settingName")
|
|
@@ -96,7 +106,7 @@ end
|
|
|
96
106
|
@param value any
|
|
97
107
|
@return any
|
|
98
108
|
]=]
|
|
99
|
-
function PlayerSettingsBase
|
|
109
|
+
function PlayerSettingsBase.SetValue(self: PlayerSettingsBase, settingName: string, value)
|
|
100
110
|
assert(type(settingName) == "string", "Bad settingName")
|
|
101
111
|
assert(DataStoreStringUtils.isValidUTF8(settingName), "Bad settingName")
|
|
102
112
|
|
|
@@ -112,7 +122,7 @@ end
|
|
|
112
122
|
@param defaultValue any
|
|
113
123
|
@return Observable<any>
|
|
114
124
|
]=]
|
|
115
|
-
function PlayerSettingsBase
|
|
125
|
+
function PlayerSettingsBase.ObserveValue(self: PlayerSettingsBase, settingName: string, defaultValue)
|
|
116
126
|
assert(type(settingName) == "string", "Bad settingName")
|
|
117
127
|
assert(defaultValue ~= nil, "defaultValue cannot be nil")
|
|
118
128
|
assert(DataStoreStringUtils.isValidUTF8(settingName), "Bad settingName")
|
|
@@ -121,10 +131,9 @@ function PlayerSettingsBase:ObserveValue(settingName, defaultValue)
|
|
|
121
131
|
|
|
122
132
|
self:EnsureInitialized(settingName, defaultValue)
|
|
123
133
|
|
|
124
|
-
return RxAttributeUtils.observeAttribute(self._obj, attributeName, defaultValue)
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
})
|
|
134
|
+
return RxAttributeUtils.observeAttribute(self._obj, attributeName, defaultValue):Pipe({
|
|
135
|
+
Rx.map(PlayerSettingsUtils.decodeForAttribute) :: any,
|
|
136
|
+
}) :: any
|
|
128
137
|
end
|
|
129
138
|
|
|
130
139
|
--[=[
|
|
@@ -133,7 +142,7 @@ end
|
|
|
133
142
|
@param settingName string
|
|
134
143
|
@param defaultValue T
|
|
135
144
|
]=]
|
|
136
|
-
function PlayerSettingsBase
|
|
145
|
+
function PlayerSettingsBase.RestoreDefault(self: PlayerSettingsBase, settingName: string, defaultValue)
|
|
137
146
|
assert(type(settingName) == "string", "Bad settingName")
|
|
138
147
|
assert(DataStoreStringUtils.isValidUTF8(settingName), "Bad settingName")
|
|
139
148
|
|
|
@@ -147,7 +156,7 @@ end
|
|
|
147
156
|
@param settingName string
|
|
148
157
|
@param defaultValue any
|
|
149
158
|
]=]
|
|
150
|
-
function PlayerSettingsBase
|
|
159
|
+
function PlayerSettingsBase.EnsureInitialized(_self: PlayerSettingsBase, settingName: string, defaultValue)
|
|
151
160
|
assert(type(settingName) == "string", "Bad settingName")
|
|
152
161
|
assert(defaultValue ~= nil, "defaultValue cannot be nil")
|
|
153
162
|
assert(DataStoreStringUtils.isValidUTF8(settingName), "Bad settingName")
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Utility helpers to work with settings.
|
|
3
4
|
|
|
@@ -18,7 +19,7 @@ local PlayerSettingsUtils = {}
|
|
|
18
19
|
|
|
19
20
|
@return Folder
|
|
20
21
|
]=]
|
|
21
|
-
function PlayerSettingsUtils.create()
|
|
22
|
+
function PlayerSettingsUtils.create(): Folder
|
|
22
23
|
local playerSettings = Instance.new("Folder")
|
|
23
24
|
playerSettings.Name = PlayerSettingsConstants.PLAYER_SETTINGS_NAME
|
|
24
25
|
playerSettings:AddTag("PlayerSettings")
|
|
@@ -32,7 +33,7 @@ end
|
|
|
32
33
|
@param settingName string
|
|
33
34
|
@return string
|
|
34
35
|
]=]
|
|
35
|
-
function PlayerSettingsUtils.getAttributeName(settingName)
|
|
36
|
+
function PlayerSettingsUtils.getAttributeName(settingName: string): string
|
|
36
37
|
assert(type(settingName) == "string", "Bad settingName")
|
|
37
38
|
assert(DataStoreStringUtils.isValidUTF8(settingName), "Bad settingName")
|
|
38
39
|
|
|
@@ -46,7 +47,7 @@ end
|
|
|
46
47
|
@param attributeName string
|
|
47
48
|
@return string
|
|
48
49
|
]=]
|
|
49
|
-
function PlayerSettingsUtils.getSettingName(attributeName)
|
|
50
|
+
function PlayerSettingsUtils.getSettingName(attributeName: string): string
|
|
50
51
|
assert(type(attributeName) == "string", "Bad attributeName")
|
|
51
52
|
|
|
52
53
|
return String.removePrefix(attributeName, PlayerSettingsConstants.SETTING_ATTRIBUTE_PREFIX)
|
|
@@ -58,7 +59,7 @@ end
|
|
|
58
59
|
@param attributeName string
|
|
59
60
|
@return string
|
|
60
61
|
]=]
|
|
61
|
-
function PlayerSettingsUtils.isSettingAttribute(attributeName)
|
|
62
|
+
function PlayerSettingsUtils.isSettingAttribute(attributeName: string): boolean
|
|
62
63
|
assert(type(attributeName) == "string", "Bad attributeName")
|
|
63
64
|
|
|
64
65
|
return String.startsWith(attributeName, PlayerSettingsConstants.SETTING_ATTRIBUTE_PREFIX)
|
|
@@ -70,7 +71,7 @@ end
|
|
|
70
71
|
@param settingValue any
|
|
71
72
|
@return any
|
|
72
73
|
]=]
|
|
73
|
-
function PlayerSettingsUtils.encodeForNetwork(settingValue)
|
|
74
|
+
function PlayerSettingsUtils.encodeForNetwork(settingValue: any): any
|
|
74
75
|
assert(settingValue ~= "<NIL_SETTING_VALUE>", "Cannot have setting as <NIL_SETTING_VALUE>")
|
|
75
76
|
|
|
76
77
|
if settingValue == nil then
|
|
@@ -88,7 +89,7 @@ end
|
|
|
88
89
|
@param settingValue any
|
|
89
90
|
@return any
|
|
90
91
|
]=]
|
|
91
|
-
function PlayerSettingsUtils.decodeForNetwork(settingValue)
|
|
92
|
+
function PlayerSettingsUtils.decodeForNetwork(settingValue: any): any
|
|
92
93
|
if settingValue == "<NIL_SETTING_VALUE>" then
|
|
93
94
|
return nil
|
|
94
95
|
elseif EnumUtils.isEncodedEnum(settingValue) then
|
|
@@ -104,7 +105,7 @@ end
|
|
|
104
105
|
@param settingValue any
|
|
105
106
|
@return any
|
|
106
107
|
]=]
|
|
107
|
-
function PlayerSettingsUtils.decodeForAttribute(settingValue)
|
|
108
|
+
function PlayerSettingsUtils.decodeForAttribute(settingValue: any): any
|
|
108
109
|
if EnumUtils.isEncodedEnum(settingValue) then
|
|
109
110
|
return EnumUtils.decodeFromString(settingValue)
|
|
110
111
|
else
|
|
@@ -118,7 +119,7 @@ end
|
|
|
118
119
|
@param settingValue any
|
|
119
120
|
@return any
|
|
120
121
|
]=]
|
|
121
|
-
function PlayerSettingsUtils.encodeForAttribute(settingValue)
|
|
122
|
+
function PlayerSettingsUtils.encodeForAttribute(settingValue: any): any
|
|
122
123
|
if typeof(settingValue) == "EnumItem" then
|
|
123
124
|
return EnumUtils.encodeAsString(settingValue)
|
|
124
125
|
else
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
@class SettingProperty
|
|
3
4
|
]=]
|
|
@@ -7,11 +8,28 @@ local require = require(script.Parent.loader).load(script)
|
|
|
7
8
|
local SettingsDataService = require("SettingsDataService")
|
|
8
9
|
local Rx = require("Rx")
|
|
9
10
|
local RxSignal = require("RxSignal")
|
|
11
|
+
local _ServiceBag = require("ServiceBag")
|
|
12
|
+
local _Promise = require("Promise")
|
|
13
|
+
local _Observable = require("Observable")
|
|
10
14
|
|
|
11
15
|
local SettingProperty = {}
|
|
12
16
|
SettingProperty.ClassName = "SettingProperty"
|
|
13
17
|
SettingProperty.__index = SettingProperty
|
|
14
18
|
|
|
19
|
+
export type SettingProperty<T> = typeof(setmetatable(
|
|
20
|
+
{} :: {
|
|
21
|
+
Value: T,
|
|
22
|
+
Changed: any,
|
|
23
|
+
DefaultValue: T,
|
|
24
|
+
|
|
25
|
+
_serviceBag: any,
|
|
26
|
+
_bridge: SettingsDataService.SettingsDataService,
|
|
27
|
+
_player: Player,
|
|
28
|
+
_definition: any,
|
|
29
|
+
},
|
|
30
|
+
{} :: typeof({ __index = SettingProperty })
|
|
31
|
+
))
|
|
32
|
+
|
|
15
33
|
--[=[
|
|
16
34
|
Constructs a new SettingProperty.
|
|
17
35
|
|
|
@@ -20,8 +38,8 @@ SettingProperty.__index = SettingProperty
|
|
|
20
38
|
@param definition SettingDefinition
|
|
21
39
|
@return SettingProperty<T>
|
|
22
40
|
]=]
|
|
23
|
-
function SettingProperty.new(serviceBag, player, definition)
|
|
24
|
-
local self = setmetatable({}, SettingProperty)
|
|
41
|
+
function SettingProperty.new<T>(serviceBag: _ServiceBag.ServiceBag, player: Player, definition): SettingProperty<T>
|
|
42
|
+
local self: SettingProperty<T> = setmetatable({} :: any, SettingProperty)
|
|
25
43
|
|
|
26
44
|
self._serviceBag = assert(serviceBag, "No serviceBag")
|
|
27
45
|
self._bridge = self._serviceBag:GetService(SettingsDataService)
|
|
@@ -40,28 +58,31 @@ end
|
|
|
40
58
|
Observes the value of the setting property
|
|
41
59
|
@return Observable<T>
|
|
42
60
|
]=]
|
|
43
|
-
function SettingProperty
|
|
61
|
+
function SettingProperty.Observe<T>(self: SettingProperty<T>): _Observable.Observable<T>
|
|
44
62
|
return self:_observePlayerSettings():Pipe({
|
|
45
63
|
Rx.where(function(settings)
|
|
46
64
|
return settings ~= nil
|
|
47
|
-
end)
|
|
48
|
-
Rx.take(1)
|
|
65
|
+
end),
|
|
66
|
+
Rx.take(1),
|
|
49
67
|
Rx.switchMap(function()
|
|
50
68
|
-- Ensure we're loaded first and then register for real.
|
|
51
69
|
return self:_observePlayerSettings()
|
|
52
|
-
end)
|
|
53
|
-
Rx.switchMap(function(playerSettings)
|
|
70
|
+
end) :: any,
|
|
71
|
+
Rx.switchMap(function(playerSettings): any
|
|
54
72
|
if not playerSettings then
|
|
55
73
|
-- Don't emit until we have a value
|
|
56
74
|
return Rx.of(self._definition:GetDefaultValue())
|
|
57
75
|
else
|
|
58
|
-
return playerSettings:ObserveValue(
|
|
76
|
+
return playerSettings:ObserveValue(
|
|
77
|
+
self._definition:GetSettingName(),
|
|
78
|
+
self._definition:GetDefaultValue()
|
|
79
|
+
)
|
|
59
80
|
end
|
|
60
|
-
end)
|
|
61
|
-
})
|
|
81
|
+
end) :: any,
|
|
82
|
+
}) :: any
|
|
62
83
|
end
|
|
63
84
|
|
|
64
|
-
|
|
85
|
+
(SettingProperty :: any).__index = function(self, index): any
|
|
65
86
|
if index == "Value" then
|
|
66
87
|
local settings = self:_getPlayerSettings()
|
|
67
88
|
if settings then
|
|
@@ -71,20 +92,26 @@ function SettingProperty:__index(index)
|
|
|
71
92
|
end
|
|
72
93
|
elseif index == "Changed" then
|
|
73
94
|
return RxSignal.new(self:Observe():Pipe({
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
95
|
+
-- TODO: Handle scenario where we're loading and .Value changes because of what
|
|
96
|
+
-- we queried.
|
|
97
|
+
Rx.skip(1),
|
|
98
|
+
}))
|
|
78
99
|
elseif index == "DefaultValue" then
|
|
79
100
|
return self._definition:GetDefaultValue()
|
|
80
101
|
elseif SettingProperty[index] then
|
|
81
102
|
return SettingProperty[index]
|
|
82
103
|
else
|
|
83
|
-
error(
|
|
104
|
+
error(
|
|
105
|
+
string.format(
|
|
106
|
+
"%q is not a member of SettingProperty %s",
|
|
107
|
+
tostring(index),
|
|
108
|
+
self._definition:GetSettingName()
|
|
109
|
+
)
|
|
110
|
+
)
|
|
84
111
|
end
|
|
85
112
|
end
|
|
86
113
|
|
|
87
|
-
function SettingProperty
|
|
114
|
+
function SettingProperty.__newindex<T>(self, index, value)
|
|
88
115
|
if index == "Value" then
|
|
89
116
|
self:SetValue(value)
|
|
90
117
|
elseif index == "DefaultValue" or index == "Changed" or SettingProperty[index] then
|
|
@@ -103,12 +130,14 @@ end
|
|
|
103
130
|
|
|
104
131
|
@param value T
|
|
105
132
|
]=]
|
|
106
|
-
function SettingProperty
|
|
133
|
+
function SettingProperty.SetValue<T>(self: SettingProperty<T>, value: T)
|
|
107
134
|
local settings = self:_getPlayerSettings()
|
|
108
135
|
if settings then
|
|
109
136
|
settings:SetValue(self._definition:GetSettingName(), value)
|
|
110
137
|
else
|
|
111
|
-
warn(
|
|
138
|
+
warn(
|
|
139
|
+
"[SettingProperty.SetValue] - Cannot set setting value. Use :PromiseSetValue() to ensure value is set after load."
|
|
140
|
+
)
|
|
112
141
|
end
|
|
113
142
|
end
|
|
114
143
|
|
|
@@ -117,11 +146,10 @@ end
|
|
|
117
146
|
|
|
118
147
|
@return Promise<T>
|
|
119
148
|
]=]
|
|
120
|
-
function SettingProperty
|
|
121
|
-
return self:_promisePlayerSettings()
|
|
122
|
-
:
|
|
123
|
-
|
|
124
|
-
end)
|
|
149
|
+
function SettingProperty.PromiseValue<T>(self: SettingProperty<T>): _Promise.Promise<T>
|
|
150
|
+
return self:_promisePlayerSettings():Then(function(playerSettings)
|
|
151
|
+
return playerSettings:GetValue(self._definition:GetSettingName(), self._definition:GetDefaultValue())
|
|
152
|
+
end)
|
|
125
153
|
end
|
|
126
154
|
|
|
127
155
|
--[=[
|
|
@@ -130,22 +158,23 @@ end
|
|
|
130
158
|
@param value T
|
|
131
159
|
@return Promise
|
|
132
160
|
]=]
|
|
133
|
-
function SettingProperty
|
|
134
|
-
return self:_promisePlayerSettings()
|
|
135
|
-
:
|
|
136
|
-
|
|
137
|
-
end)
|
|
161
|
+
function SettingProperty.PromiseSetValue<T>(self: SettingProperty<T>, value: T): _Promise.Promise<()>
|
|
162
|
+
return self:_promisePlayerSettings():Then(function(playerSettings)
|
|
163
|
+
playerSettings:SetValue(self._definition:GetSettingName(), value)
|
|
164
|
+
end)
|
|
138
165
|
end
|
|
139
166
|
|
|
140
167
|
--[=[
|
|
141
168
|
Restores the setting to the default value
|
|
142
169
|
]=]
|
|
143
|
-
function SettingProperty
|
|
170
|
+
function SettingProperty.RestoreDefault<T>(self: SettingProperty<T>): ()
|
|
144
171
|
local settings = self:_getPlayerSettings()
|
|
145
172
|
if settings then
|
|
146
173
|
settings:RestoreDefault(self._definition:GetSettingName(), self._definition:GetDefaultValue())
|
|
147
174
|
else
|
|
148
|
-
warn(
|
|
175
|
+
warn(
|
|
176
|
+
"[SettingProperty.RestoreDefault] - Cannot set setting value. Use :PromiseRestoreDefault() to ensure value is set after load."
|
|
177
|
+
)
|
|
149
178
|
end
|
|
150
179
|
end
|
|
151
180
|
|
|
@@ -156,23 +185,21 @@ end
|
|
|
156
185
|
|
|
157
186
|
@return Promise
|
|
158
187
|
]=]
|
|
159
|
-
function SettingProperty
|
|
160
|
-
return self:_promisePlayerSettings()
|
|
161
|
-
:
|
|
162
|
-
|
|
163
|
-
end)
|
|
188
|
+
function SettingProperty.PromiseRestoreDefault<T>(self: SettingProperty<T>): _Promise.Promise<()>
|
|
189
|
+
return self:_promisePlayerSettings():Then(function(playerSettings)
|
|
190
|
+
playerSettings:RestoreDefault(self._definition:GetSettingName(), self._definition:GetDefaultValue())
|
|
191
|
+
end)
|
|
164
192
|
end
|
|
165
193
|
|
|
166
|
-
|
|
167
|
-
function SettingProperty:_observePlayerSettings()
|
|
194
|
+
function SettingProperty._observePlayerSettings<T>(self: SettingProperty<T>)
|
|
168
195
|
return self._bridge:ObservePlayerSettings(self._player)
|
|
169
196
|
end
|
|
170
197
|
|
|
171
|
-
function SettingProperty
|
|
198
|
+
function SettingProperty._getPlayerSettings<T>(self: SettingProperty<T>)
|
|
172
199
|
return self._bridge:GetPlayerSettings(self._player)
|
|
173
200
|
end
|
|
174
201
|
|
|
175
|
-
function SettingProperty
|
|
202
|
+
function SettingProperty._promisePlayerSettings<T>(self: SettingProperty<T>)
|
|
176
203
|
return self._bridge:PromisePlayerSettings(self._player)
|
|
177
204
|
end
|
|
178
205
|
|
|
@@ -19,6 +19,13 @@ local _ServiceBag = require("ServiceBag")
|
|
|
19
19
|
|
|
20
20
|
local SettingsDataService = {}
|
|
21
21
|
|
|
22
|
+
export type SettingsDataService = typeof(setmetatable(
|
|
23
|
+
{} :: {
|
|
24
|
+
_maid: Maid.Maid,
|
|
25
|
+
},
|
|
26
|
+
{} :: typeof({ __index = SettingsDataService })
|
|
27
|
+
))
|
|
28
|
+
|
|
22
29
|
--[=[
|
|
23
30
|
Initializes the shared registry service. Should be done via [ServiceBag].
|
|
24
31
|
|