@quenty/settings 11.7.0 → 11.8.1-canary.496.cb49bdf.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,26 @@
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.8.1-canary.496.cb49bdf.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/settings@11.8.0...@quenty/settings@11.8.1-canary.496.cb49bdf.0) (2024-09-20)
7
+
8
+ **Note:** Version bump only for package @quenty/settings
9
+
10
+
11
+
12
+
13
+
14
+ # [11.8.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/settings@11.7.0...@quenty/settings@11.8.0) (2024-09-12)
15
+
16
+
17
+ ### Features
18
+
19
+ * Simplified settings manager usage ([71fdb58](https://github.com/Quenty/NevermoreEngine/commit/71fdb5870c07e8b73b36bd4b938c4fcca914ba1b))
20
+ * Unedited all changes ([60e64e3](https://github.com/Quenty/NevermoreEngine/commit/60e64e3efce17c10c4b8965871187d231b338dd4))
21
+
22
+
23
+
24
+
25
+
6
26
  # [11.7.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/settings@11.6.1...@quenty/settings@11.7.0) (2024-08-09)
7
27
 
8
28
  **Note:** Version bump only for package @quenty/settings
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quenty/settings",
3
- "version": "11.7.0",
3
+ "version": "11.8.1-canary.496.cb49bdf.0",
4
4
  "description": "Centralized player settings service",
5
5
  "keywords": [
6
6
  "Roblox",
@@ -25,33 +25,35 @@
25
25
  "Quenty"
26
26
  ],
27
27
  "dependencies": {
28
- "@quenty/attributeutils": "^14.4.0",
29
- "@quenty/baseobject": "^10.3.0",
30
- "@quenty/binder": "^14.5.0",
31
- "@quenty/cmdrservice": "^13.6.0",
32
- "@quenty/datastore": "^13.6.0",
33
- "@quenty/enumutils": "^3.2.0",
34
- "@quenty/jsonutils": "^10.3.0",
35
- "@quenty/loader": "^10.3.0",
36
- "@quenty/maid": "^3.2.0",
37
- "@quenty/observablecollection": "^12.4.0",
38
- "@quenty/playerbinder": "^14.5.0",
39
- "@quenty/playerutils": "^8.4.0",
40
- "@quenty/remotefunctionutils": "^10.3.0",
41
- "@quenty/remoting": "^12.5.0",
42
- "@quenty/rx": "^13.4.0",
43
- "@quenty/rxbinderutils": "^14.5.0",
44
- "@quenty/servicebag": "^11.4.0",
45
- "@quenty/signal": "^7.3.0",
46
- "@quenty/statestack": "^14.5.0",
47
- "@quenty/string": "^3.2.0",
48
- "@quenty/symbol": "^3.1.0",
49
- "@quenty/table": "^3.5.0",
50
- "@quenty/throttle": "^10.4.0",
51
- "@quenty/valueobject": "^13.4.0"
28
+ "@quenty/attributeutils": "14.5.0",
29
+ "@quenty/baseobject": "10.4.0",
30
+ "@quenty/binder": "14.6.0",
31
+ "@quenty/cmdrservice": "13.7.1-canary.496.cb49bdf.0",
32
+ "@quenty/datastore": "13.7.1-canary.496.cb49bdf.0",
33
+ "@quenty/ducktype": "5.4.0",
34
+ "@quenty/enumutils": "3.2.0",
35
+ "@quenty/jsonutils": "10.4.0",
36
+ "@quenty/loader": "10.4.0",
37
+ "@quenty/maid": "3.3.0",
38
+ "@quenty/observablecollection": "12.5.1-canary.496.cb49bdf.0",
39
+ "@quenty/playerbinder": "14.6.0",
40
+ "@quenty/playerutils": "8.5.0",
41
+ "@quenty/remotefunctionutils": "10.4.0",
42
+ "@quenty/remoting": "12.6.0",
43
+ "@quenty/rx": "13.5.0",
44
+ "@quenty/rxbinderutils": "14.6.0",
45
+ "@quenty/servicebag": "11.5.1-canary.496.cb49bdf.0",
46
+ "@quenty/signal": "7.4.0",
47
+ "@quenty/statestack": "14.6.0",
48
+ "@quenty/string": "3.2.0",
49
+ "@quenty/symbol": "3.1.0",
50
+ "@quenty/table": "3.5.0",
51
+ "@quenty/throttle": "10.5.0",
52
+ "@quenty/tie": "10.7.0",
53
+ "@quenty/valueobject": "13.5.0"
52
54
  },
53
55
  "publishConfig": {
54
56
  "access": "public"
55
57
  },
56
- "gitHead": "ba466bdbc05c42fb607cf5e228c16339201d21d7"
58
+ "gitHead": "cb49bdf8d79aac6e6901901c914271148df358b2"
57
59
  }
@@ -10,13 +10,15 @@ local require = require(script.Parent.loader).load(script)
10
10
 
11
11
  local Players = game:GetService("Players")
12
12
 
13
+ local Binder = require("Binder")
13
14
  local DataStoreStringUtils = require("DataStoreStringUtils")
14
15
  local Maid = require("Maid")
15
16
  local Observable = require("Observable")
16
17
  local PlayerSettingsBase = require("PlayerSettingsBase")
17
18
  local PlayerSettingsConstants = require("PlayerSettingsConstants")
19
+ local PlayerSettingsInterface = require("PlayerSettingsInterface")
18
20
  local PlayerSettingsUtils = require("PlayerSettingsUtils")
19
- local RemoteFunctionUtils = require("RemoteFunctionUtils")
21
+ local Remoting = require("Remoting")
20
22
  local Symbol = require("Symbol")
21
23
  local ThrottledFunction = require("ThrottledFunction")
22
24
  local ValueObject = require("ValueObject")
@@ -27,8 +29,6 @@ local PlayerSettingsClient = setmetatable({}, PlayerSettingsBase)
27
29
  PlayerSettingsClient.ClassName = "PlayerSettingsClient"
28
30
  PlayerSettingsClient.__index = PlayerSettingsClient
29
31
 
30
- require("PromiseRemoteFunctionMixin"):Add(PlayerSettingsClient, PlayerSettingsConstants.REMOTE_FUNCTION_NAME)
31
-
32
32
  --[=[
33
33
  See [SettingsBindersClient] and [SettingsServiceClient] on how to properly use this class.
34
34
 
@@ -40,21 +40,23 @@ function PlayerSettingsClient.new(folder, serviceBag)
40
40
  local self = setmetatable(PlayerSettingsBase.new(folder, serviceBag), PlayerSettingsClient)
41
41
 
42
42
  if self:GetPlayer() == Players.LocalPlayer then
43
+ self._remoting = self._maid:Add(Remoting.new(self._obj, "PlayerSettings", Remoting.Realms.CLIENT))
44
+
43
45
  self._toReplicate = nil
44
46
  self._toReplicateCallbacks = {}
45
47
 
46
48
  -- We only want to keep this data here until we're
47
49
  -- actually done sending and the server acknowledges this is the state that
48
50
  -- we have. Otherwise we accept the server as the state of truth
49
- self._pendingReplicationDataInTransit = ValueObject.new(nil)
50
- self._maid:GiveTask(self._pendingReplicationDataInTransit)
51
+ self._pendingReplicationDataInTransit = self._maid:Add(ValueObject.new(nil))
51
52
 
52
53
  -- We need to avoid sending these quickly because otherwise
53
54
  -- sliding a slider can lag out stuff.
54
- self._queueSendSettingsFunc = ThrottledFunction.new(0.3, function()
55
+ self._queueSendSettingsFunc = self._maid:Add(ThrottledFunction.new(0.3, function()
55
56
  self:_sendSettings()
56
- end, { leading = true, trailing = true })
57
- self._maid:GiveTask(self._queueSendSettingsFunc)
57
+ end, { leading = true, trailing = true }))
58
+
59
+ self._maid:GiveTask(PlayerSettingsInterface.Client:Implement(self._obj, self))
58
60
  end
59
61
 
60
62
  return self
@@ -229,14 +231,7 @@ end
229
231
  function PlayerSettingsClient:_promiseReplicateSettings(settingsMap)
230
232
  assert(type(settingsMap) == "table", "Bad settingsMap")
231
233
 
232
- return self:PromiseRemoteFunction()
233
- :Then(function(remoteFunction)
234
- return self._maid:GivePromise(RemoteFunctionUtils.promiseInvokeServer(
235
- remoteFunction,
236
- PlayerSettingsConstants.REQUEST_UPDATE_SETTINGS,
237
- settingsMap))
238
- end)
234
+ return self._remoting.RequestUpdateSettings:PromiseInvokeServer(settingsMap)
239
235
  end
240
236
 
241
-
242
- return PlayerSettingsClient
237
+ return Binder.new("PlayerSettings", PlayerSettingsClient)
@@ -32,7 +32,7 @@ function SettingsServiceClient:Init(serviceBag)
32
32
 
33
33
  -- Internal
34
34
  self._serviceBag:GetService(require("SettingRegistryServiceShared")):RegisterSettingService(self)
35
- self._binders = self._serviceBag:GetService(require("SettingsBindersClient"))
35
+ self._playerSettingsBinder = self._serviceBag:GetService(require("PlayerSettingsClient"))
36
36
  end
37
37
 
38
38
  function SettingsServiceClient:Start()
@@ -84,7 +84,7 @@ end
84
84
  function SettingsServiceClient:ObservePlayerSettings(player)
85
85
  assert(typeof(player) == "Instance" and player:IsA("Player"), "Bad player")
86
86
 
87
- return PlayerSettingsUtils.observePlayerSettings(self._binders.PlayerSettings, player)
87
+ return PlayerSettingsUtils.observePlayerSettings(self._playerSettingsBinder, player)
88
88
  end
89
89
 
90
90
  --[=[
@@ -96,7 +96,7 @@ end
96
96
  function SettingsServiceClient:ObservePlayerSettingsBrio(player)
97
97
  assert(typeof(player) == "Instance" and player:IsA("Player"), "Bad player")
98
98
 
99
- return PlayerSettingsUtils.observePlayerSettingsBrio(self._binders.PlayerSettings, player)
99
+ return PlayerSettingsUtils.observePlayerSettingsBrio(self._playerSettingsBinder, player)
100
100
  end
101
101
 
102
102
  --[=[
@@ -108,7 +108,7 @@ end
108
108
  function SettingsServiceClient:GetPlayerSettings(player)
109
109
  assert(typeof(player) == "Instance" and player:IsA("Player"), "Bad player")
110
110
 
111
- return PlayerSettingsUtils.getPlayerSettings(self._binders.PlayerSettings, player)
111
+ return PlayerSettingsUtils.getPlayerSettings(self._playerSettingsBinder, player)
112
112
  end
113
113
 
114
114
  --[=[
@@ -6,10 +6,11 @@ local require = require(script.Parent.loader).load(script)
6
6
 
7
7
  local BaseObject = require("BaseObject")
8
8
  local PlayerSettingsUtils = require("PlayerSettingsUtils")
9
- local SettingsBindersServer = require("SettingsBindersServer")
9
+ local PlayerSettings = require("PlayerSettings")
10
10
  local PlayerDataStoreService = require("PlayerDataStoreService")
11
11
  local DataStoreStringUtils = require("DataStoreStringUtils")
12
12
  local PlayerSettingsConstants = require("PlayerSettingsConstants")
13
+ local PlayerBinder = require("PlayerBinder")
13
14
 
14
15
  local PlayerHasSettings = setmetatable({}, BaseObject)
15
16
  PlayerHasSettings.ClassName = "PlayerHasSettings"
@@ -19,7 +20,7 @@ function PlayerHasSettings.new(player, serviceBag)
19
20
  local self = setmetatable(BaseObject.new(player), PlayerHasSettings)
20
21
 
21
22
  self._serviceBag = assert(serviceBag, "No serviceBag")
22
- self._settingsBindersServer = self._serviceBag:GetService(SettingsBindersServer)
23
+ self._playerSettingsBinder = self._serviceBag:GetService(PlayerSettings)
23
24
  self._playerDataStoreService = self._serviceBag:GetService(PlayerDataStoreService)
24
25
 
25
26
  self:_promiseLoadSettings()
@@ -28,8 +29,7 @@ function PlayerHasSettings.new(player, serviceBag)
28
29
  end
29
30
 
30
31
  function PlayerHasSettings:_promiseLoadSettings()
31
- self._settings = PlayerSettingsUtils.create(self._settingsBindersServer.PlayerSettings)
32
- self._maid:GiveTask(self._settings)
32
+ self._settings = self._maid:Add(PlayerSettingsUtils.create())
33
33
 
34
34
  self._maid:GivePromise(self._playerDataStoreService:PromiseDataStore(self._obj))
35
35
  :Then(function(dataStore)
@@ -51,7 +51,7 @@ function PlayerHasSettings:_promiseLoadSettings()
51
51
  end)
52
52
  end)
53
53
  :Catch(function(err)
54
- warn(("[PlayerHasSettings] - Failed to load settings for player. %s"):format(tostring(err)))
54
+ warn(string.format("[PlayerHasSettings] - Failed to load settings for player. %s", tostring(err)))
55
55
  end)
56
56
  :Finally(function()
57
57
  -- Parent anyway...
@@ -84,4 +84,4 @@ function PlayerHasSettings:_handleAttributeChanged(subStore, attributeName)
84
84
  subStore:Store(settingName, newValue)
85
85
  end
86
86
 
87
- return PlayerHasSettings
87
+ return PlayerBinder.new("PlayerHasSettings", PlayerHasSettings)
@@ -4,11 +4,14 @@
4
4
 
5
5
  local require = require(script.Parent.loader).load(script)
6
6
 
7
+ local Binder = require("Binder")
8
+ local DataStoreStringUtils = require("DataStoreStringUtils")
7
9
  local PlayerSettingsBase = require("PlayerSettingsBase")
8
10
  local PlayerSettingsConstants = require("PlayerSettingsConstants")
11
+ local PlayerSettingsInterface = require("PlayerSettingsInterface")
9
12
  local PlayerSettingsUtils = require("PlayerSettingsUtils")
13
+ local Remoting = require("Remoting")
10
14
  local SettingRegistryServiceShared = require("SettingRegistryServiceShared")
11
- local DataStoreStringUtils = require("DataStoreStringUtils")
12
15
 
13
16
  local PlayerSettings = setmetatable({}, PlayerSettingsBase)
14
17
  PlayerSettings.ClassName = "PlayerSettings"
@@ -20,15 +23,7 @@ function PlayerSettings.new(obj, serviceBag)
20
23
  self._serviceBag = assert(serviceBag, "No serviceBag")
21
24
  self._settingRegistryServiceShared = self._serviceBag:GetService(SettingRegistryServiceShared)
22
25
 
23
- self._remoteFunction = Instance.new("RemoteFunction")
24
- self._remoteFunction.Name = PlayerSettingsConstants.REMOTE_FUNCTION_NAME
25
- self._remoteFunction.Archivable = false
26
- self._remoteFunction.Parent = self._obj
27
- self._maid:GiveTask(self._remoteFunction)
28
-
29
- self._remoteFunction.OnServerInvoke = function(...)
30
- return self:_handleServerInvoke(...)
31
- end
26
+ self:_setupRemoting()
32
27
 
33
28
  self._maid:GiveTask(self._settingRegistryServiceShared:ObserveRegisteredDefinitionsBrio():Subscribe(function(brio)
34
29
  if brio:IsDead() then
@@ -39,6 +34,8 @@ function PlayerSettings.new(obj, serviceBag)
39
34
  self:EnsureInitialized(value:GetSettingName(), value:GetDefaultValue())
40
35
  end))
41
36
 
37
+ self._maid:GiveTask(PlayerSettingsInterface.Server:Implement(self._obj, self))
38
+
42
39
  return self
43
40
  end
44
41
 
@@ -65,17 +62,17 @@ function PlayerSettings:EnsureInitialized(settingName, defaultValue)
65
62
  end
66
63
  end
67
64
 
68
- function PlayerSettings:_handleServerInvoke(player, request, ...)
69
- assert(self:GetPlayer() == player, "Bad player")
65
+ function PlayerSettings:_setupRemoting()
66
+ self._remoting = self._maid:Add(Remoting.new(self._obj, "PlayerSettings", Remoting.Realms.SERVER))
70
67
 
71
- if request == PlayerSettingsConstants.REQUEST_UPDATE_SETTINGS then
72
- return self:_setSettings(...)
73
- else
74
- error(("Unknown request %q"):format(tostring(request)))
75
- end
68
+ self._maid:Add(self._remoting.RequestUpdateSettings:Bind(function(player, settingsMap)
69
+ assert(self:GetPlayer() == player, "Bad player")
70
+
71
+ return self:_setSettingsMap(settingsMap)
72
+ end))
76
73
  end
77
74
 
78
- function PlayerSettings:_setSettings(settingsMap)
75
+ function PlayerSettings:_setSettingsMap(settingsMap)
79
76
  assert(type(settingsMap) == "table", "Bad settingsMap")
80
77
 
81
78
  for settingName, value in pairs(settingsMap) do
@@ -123,4 +120,4 @@ function PlayerSettings:_setSettings(settingsMap)
123
120
  end
124
121
  end
125
122
 
126
- return PlayerSettings
123
+ return Binder.new("PlayerSettings", PlayerSettings)
@@ -22,26 +22,28 @@ function SettingsService:Init(serviceBag)
22
22
 
23
23
 
24
24
  -- Internal
25
- self._binders = self._serviceBag:GetService(require("SettingsBindersServer"))
25
+ self._playerSettingsBinder = self._serviceBag:GetService(require("PlayerSettings"))
26
+ self._serviceBag:GetService(require("PlayerHasSettings"))
27
+
26
28
  self._serviceBag:GetService(require("SettingRegistryServiceShared")):RegisterSettingService(self)
27
29
  end
28
30
 
29
31
  function SettingsService:ObservePlayerSettingsBrio(player)
30
32
  assert(typeof(player) == "Instance" and player:IsA("Player"), "Bad player")
31
33
 
32
- return PlayerSettingsUtils.observePlayerSettingsBrio(self._binders.PlayerSettings, player)
34
+ return PlayerSettingsUtils.observePlayerSettingsBrio(self._playerSettingsBinder, player)
33
35
  end
34
36
 
35
37
  function SettingsService:ObservePlayerSettings(player)
36
38
  assert(typeof(player) == "Instance" and player:IsA("Player"), "Bad player")
37
39
 
38
- return PlayerSettingsUtils.observePlayerSettings(self._binders.PlayerSettings, player)
40
+ return PlayerSettingsUtils.observePlayerSettings(self._playerSettingsBinder, player)
39
41
  end
40
42
 
41
43
  function SettingsService:GetPlayerSettings(player)
42
44
  assert(typeof(player) == "Instance" and player:IsA("Player"), "Bad player")
43
45
 
44
- return PlayerSettingsUtils.getPlayerSettings(self._binders.PlayerSettings, player)
46
+ return PlayerSettingsUtils.getPlayerSettings(self._playerSettingsBinder, player)
45
47
  end
46
48
 
47
49
  function SettingsService:PromisePlayerSettings(player, cancelToken)
@@ -0,0 +1,16 @@
1
+ --[=[
2
+ @class PlayerSettingsInterface
3
+ ]=]
4
+
5
+ local require = require(script.Parent.loader).load(script)
6
+
7
+ local TieDefinition = require("TieDefinition")
8
+
9
+ return TieDefinition.new("PlayerSettings", {
10
+ GetSettingProperty = TieDefinition.Types.METHOD;
11
+ GetValue = TieDefinition.Types.METHOD;
12
+ SetValue = TieDefinition.Types.METHOD;
13
+ ObserveValue = TieDefinition.Types.METHOD;
14
+ RestoreDefault = TieDefinition.Types.METHOD;
15
+ EnsureInitialized = TieDefinition.Types.METHOD;
16
+ })
@@ -20,16 +20,12 @@ local PlayerSettingsUtils = {}
20
20
  --[=[
21
21
  Creates a new player settings
22
22
 
23
- @param binder Binder<PlayerSettings>
24
23
  @return Folder
25
24
  ]=]
26
- function PlayerSettingsUtils.create(binder)
27
- assert(Binder.isBinder(binder), "No binder")
28
-
25
+ function PlayerSettingsUtils.create()
29
26
  local playerSettings = Instance.new("Folder")
30
27
  playerSettings.Name = PlayerSettingsConstants.PLAYER_SETTINGS_NAME
31
-
32
- binder:Bind(playerSettings)
28
+ playerSettings:AddTag("PlayerSettings")
33
29
 
34
30
  return playerSettings
35
31
  end
@@ -10,8 +10,8 @@
10
10
  local SettingDefinition = require("SettingDefinition")
11
11
 
12
12
  return require("SettingDefinitionProvider").new({
13
- SettingDefinition.new("LastTimeUpdateSeen", 0);
14
- SettingDefinition.new("LastTimeShopSeen", 0);
13
+ LastTimeUpdateSeen = 0;
14
+ LastTimeShopSeen = 0;
15
15
  })
16
16
  ```
17
17
 
@@ -22,8 +22,11 @@ local require = require(script.Parent.loader).load(script)
22
22
 
23
23
  local Players = game:GetService("Players")
24
24
 
25
+ local SettingRegistryServiceShared = require("SettingRegistryServiceShared")
25
26
  local SettingProperty = require("SettingProperty")
26
27
  local ServiceBag = require("ServiceBag")
28
+ local DuckTypeUtils = require("DuckTypeUtils")
29
+ local Maid = require("Maid")
27
30
 
28
31
  local SettingDefinition = {}
29
32
  SettingDefinition.ClassName = "SettingDefinition"
@@ -38,19 +41,111 @@ SettingDefinition.__index = SettingDefinition
38
41
  @return SettingDefinition<T>
39
42
  ]=]
40
43
  function SettingDefinition.new(settingName, defaultValue)
41
- local self = setmetatable({}, SettingDefinition)
42
-
43
44
  assert(type(settingName) == "string", "Bad settingName")
44
45
  assert(defaultValue ~= nil, "DefaultValue cannot be nil")
45
46
 
47
+ local self = setmetatable({}, SettingDefinition)
48
+
46
49
  self._settingName = settingName
47
50
  self._defaultValue = defaultValue
48
51
 
49
- self.ServiceName = self._settingName
52
+ self.ServiceName = self._settingName .. "SettingDefinition"
50
53
 
51
54
  return self
52
55
  end
53
56
 
57
+ --[=[
58
+ Initializes the setting definition from a service bag.
59
+
60
+ @param serviceBag ServiceBag
61
+ ]=]
62
+ function SettingDefinition:Init(serviceBag)
63
+ assert(serviceBag, "No serviceBag")
64
+ assert(not self._maid, "Already initialized")
65
+
66
+ self._maid = Maid.new()
67
+ self._serviceBag = assert(serviceBag, "No serviceBag")
68
+
69
+ local settingRegistryServiceShared = self._serviceBag:GetService(SettingRegistryServiceShared)
70
+ self._maid:GiveTask(settingRegistryServiceShared:RegisterSettingDefinition(self))
71
+ end
72
+
73
+ --[=[
74
+ Gets the value for the given player
75
+
76
+ @param player Player
77
+ @return T
78
+ ]=]
79
+ function SettingDefinition:Get(player)
80
+ assert(typeof(player) == "Instance" and player:IsA("Player") or player == nil, "Bad player")
81
+ assert(self._serviceBag, "Retrieve from serviceBag")
82
+
83
+ return self:GetSettingProperty(self._serviceBag, player):GetValue()
84
+ end
85
+
86
+ --[=[
87
+ Sets the value
88
+
89
+ @param player Player
90
+ @param value T
91
+ ]=]
92
+ function SettingDefinition:Set(player, value)
93
+ assert(typeof(player) == "Instance" and player:IsA("Player") or player == nil, "Bad player")
94
+ assert(self._serviceBag, "Retrieve from serviceBag")
95
+
96
+ return self:GetSettingProperty(self._serviceBag, player):SetValue(value)
97
+ end
98
+
99
+ --[=[
100
+ Promise gets the value
101
+
102
+ @param player Player
103
+ @return Promise<T>
104
+ ]=]
105
+ function SettingDefinition:Promise(player)
106
+ assert(typeof(player) == "Instance" and player:IsA("Player") or player == nil, "Bad player")
107
+ assert(self._serviceBag, "Retrieve from serviceBag")
108
+
109
+ return self:GetSettingProperty(self._serviceBag, player):PromiseValue()
110
+ end
111
+
112
+ --[=[
113
+ Promise gets the value
114
+
115
+ @param player Player
116
+ @param value T
117
+ @return Promise<T>
118
+ ]=]
119
+ function SettingDefinition:PromiseSet(player, value)
120
+ assert(typeof(player) == "Instance" and player:IsA("Player") or player == nil, "Bad player")
121
+ assert(self._serviceBag, "Retrieve from serviceBag")
122
+
123
+ return self:GetSettingProperty(self._serviceBag, player):PromiseSetValue(value)
124
+ end
125
+
126
+ --[=[
127
+ Promise gets the value
128
+
129
+ @param player Player
130
+ @return Promise<T>
131
+ ]=]
132
+ function SettingDefinition:Observe(player)
133
+ assert(typeof(player) == "Instance" and player:IsA("Player") or player == nil, "Bad player")
134
+ assert(self._serviceBag, "Retrieve from serviceBag")
135
+
136
+ return self:GetSettingProperty(self._serviceBag, player):Observe()
137
+ end
138
+
139
+ --[=[
140
+ Returns true if the value is a setting definition
141
+
142
+ @param value any
143
+ @return boolean
144
+ ]=]
145
+ function SettingDefinition.isSettingDefinition(value)
146
+ return DuckTypeUtils.isImplementation(SettingDefinition, value)
147
+ end
148
+
54
149
  --[=[
55
150
  Gets a new setting property for the given definition
56
151
 
@@ -60,7 +155,9 @@ end
60
155
  ]=]
61
156
  function SettingDefinition:GetSettingProperty(serviceBag, player)
62
157
  assert(ServiceBag.isServiceBag(serviceBag), "Bad serviceBag")
63
- assert(typeof(player) == "Instance" and player:IsA("Player"), "Bad player")
158
+ assert(typeof(player) == "Instance" and player:IsA("Player") or player == nil, "Bad player")
159
+
160
+ player = player or Players.LocalPlayer
64
161
 
65
162
  return SettingProperty.new(serviceBag, player, self)
66
163
  end
@@ -93,4 +190,8 @@ function SettingDefinition:GetDefaultValue()
93
190
  return self._defaultValue
94
191
  end
95
192
 
193
+ function SettingDefinition:Destroy()
194
+ self._maid:DoCleaning()
195
+ end
196
+
96
197
  return SettingDefinition
@@ -15,9 +15,9 @@
15
15
  local SettingDefinition = require("SettingDefinition")
16
16
 
17
17
  return require("SettingDefinitionProvider").new({
18
- SettingDefinition.new("KeyBinding", Enum.KeyCode.X);
19
- SettingDefinition.new("CameraShake", true);
20
- SettingDefinition.new("CameraSensitivity", 1);
18
+ KeyBinding = Enum.KeyCode.X;
19
+ CameraShake = true;
20
+ CameraSensitivity = 1;
21
21
  })
22
22
  ```
23
23
 
@@ -26,8 +26,8 @@
26
26
 
27
27
  local require = require(script.Parent.loader).load(script)
28
28
 
29
- local SettingRegistryServiceShared = require("SettingRegistryServiceShared")
30
29
  local Maid = require("Maid")
30
+ local SettingDefinition = require("SettingDefinition")
31
31
 
32
32
  local SettingDefinitionProvider = {}
33
33
  SettingDefinitionProvider.ClassName = "SettingDefinitionProvider"
@@ -38,32 +38,67 @@ SettingDefinitionProvider.__index = SettingDefinitionProvider
38
38
  Constructs a new provider with a list of [SettingDefinition]'s.
39
39
 
40
40
  ```lua
41
+ -- In one location
41
42
  local SettingDefinition = require("SettingDefinition")
42
43
 
43
44
  return require("SettingDefinitionProvider").new({
44
- SettingDefinition.new("KeyBinding", Enum.KeyCode.X);
45
- SettingDefinition.new("CameraShake", true);
46
- SettingDefinition.new("CameraSensitivity", 1);
45
+ KeyBinding = Enum.KeyCode.X;
46
+ CameraShake = true;
47
+ CameraSensitivity = 1;
47
48
  })
48
49
  ```
49
50
 
51
+ Usage:
52
+
53
+ ```lua
54
+ local ourSettings = serviceBag:GetService(require("OurSettings"))
55
+
56
+ print(ourSettings.CameraShake:Get(Players.LocalPlayer), true)
57
+
58
+ ourSettings.CameraShake:Set(Players.LocalPlayer, false)
59
+
60
+ ourSettings.CameraShake:Promise(Players.LocalPlayer)
61
+ :Then(function(cameraShake)
62
+ print(cameraShake)
63
+ end)
64
+ ```
65
+
50
66
  @param settingDefinitions { SettingDefinition }
51
67
  @return SettingDefinitionProvider
52
68
  ]=]
53
69
  function SettingDefinitionProvider.new(settingDefinitions)
54
70
  local self = setmetatable({}, SettingDefinitionProvider)
55
71
 
56
- self._settingDefinitions = {}
72
+ self._settingDefinitionList = {}
57
73
  self._lookup = {}
58
74
 
59
- for _, settingDefinition in pairs(settingDefinitions) do
60
- table.insert(self._settingDefinitions, settingDefinition)
61
- self._lookup[settingDefinition:GetSettingName()] = settingDefinition
75
+ for key, value in pairs(settingDefinitions) do
76
+ if type(key) == "number" then
77
+ assert(SettingDefinition.isSettingDefinition(key), "Bad settingDefinition")
78
+
79
+ self:_addSettingDefinition(key)
80
+ elseif type(key) == "string" then
81
+ if SettingDefinition.isSettingDefinition(value) then
82
+ self:_addSettingDefinition(value)
83
+ else
84
+ local definition = SettingDefinition.new(key, value)
85
+ self:_addSettingDefinition(definition)
86
+ end
87
+ else
88
+ error("Bad key for settingDefinitions")
89
+ end
62
90
  end
63
91
 
64
92
  return self
65
93
  end
66
94
 
95
+ function SettingDefinitionProvider:_addSettingDefinition(settingDefinition)
96
+ assert(SettingDefinition.isSettingDefinition(settingDefinition), "Bad settingDefinition")
97
+
98
+ table.insert(self._settingDefinitionList, settingDefinition)
99
+ self._lookup[settingDefinition:GetSettingName()] = settingDefinition
100
+ end
101
+
67
102
  --[=[
68
103
  Initializes the provider, storing the data in [SettingRegistryServiceShared]
69
104
 
@@ -74,10 +109,17 @@ function SettingDefinitionProvider:Init(serviceBag)
74
109
  assert(not self._maid, "Already initialized")
75
110
 
76
111
  self._maid = Maid.new()
112
+ self._serviceBag = assert(serviceBag, "No serviceBag")
113
+
114
+ self._initializedDefinitionLookup = {}
77
115
 
78
- local settingRegistryServiceShared = serviceBag:GetService(SettingRegistryServiceShared)
79
- for _, settingDefinition in pairs(self._settingDefinitions) do
80
- self._maid:GiveTask(settingRegistryServiceShared:RegisterSettingDefinition(settingDefinition))
116
+ -- Register our setting definitions
117
+ for _, settingDefinition in pairs(self._settingDefinitionList) do
118
+ local initialized = self._serviceBag:GetService(settingDefinition)
119
+ self._initializedDefinitionLookup[settingDefinition] = initialized
120
+
121
+ -- Store lookup to overcome metatable lookup
122
+ self[settingDefinition:GetSettingName()] = initialized
81
123
  end
82
124
  end
83
125
 
@@ -94,7 +136,17 @@ end
94
136
  @return { SettingDefinition }
95
137
  ]=]
96
138
  function SettingDefinitionProvider:GetSettingDefinitions()
97
- return self._settingDefinitions
139
+ if self._serviceBag then
140
+ local copy = table.clone(self._settingDefinitionList)
141
+
142
+ for key, settingDefinition in pairs(copy) do
143
+ copy[key] = assert(self._initializedDefinitionLookup[settingDefinition], "Missing settingDefinition")
144
+ end
145
+
146
+ return copy
147
+ end
148
+
149
+ return table.clone(self._settingDefinitionList)
98
150
  end
99
151
 
100
152
  --[=[
@@ -104,9 +156,9 @@ end
104
156
  local SettingDefinition = require("SettingDefinition")
105
157
 
106
158
  local provider = require("SettingDefinitionProvider").new({
107
- SettingDefinition.new("KeyBinding", Enum.KeyCode.X);
108
- SettingDefinition.new("CameraShake", true);
109
- SettingDefinition.new("CameraSensitivity", 1);
159
+ KeyBinding = Enum.KeyCode.X;
160
+ CameraShake = true;
161
+ CameraSensitivity = 1;
110
162
  })
111
163
 
112
164
  local service = serviceBag:GetService(provider)
@@ -123,18 +175,27 @@ function SettingDefinitionProvider:__index(index)
123
175
  error("[SettingDefinitionProvider] - Cannot index provider with nil value")
124
176
  elseif SettingDefinitionProvider[index] then
125
177
  return SettingDefinitionProvider[index]
126
- elseif index == "_lookup" or index == "_settingDefinitions" or index == "_maid" then
178
+ elseif index == "_lookup"
179
+ or index == "_settingDefinitionList"
180
+ or index == "_maid"
181
+ or index == "_initializedDefinitionLookup"
182
+ or index == "_serviceBag" then
183
+
127
184
  return rawget(self, index)
128
185
  elseif type(index) == "string" then
129
186
  local lookup = rawget(self, "_lookup")
130
187
  local settingDefinition = lookup[index]
131
188
  if not settingDefinition then
132
- error(("Bad index %q into SettingDefinitionProvider"):format(tostring(index)))
189
+ error(string.format("Bad index %q into SettingDefinitionProvider", tostring(index)))
190
+ end
191
+
192
+ if self._serviceBag then
193
+ return assert(self._initializedDefinitionLookup[settingDefinition], "Missing settingDefinition")
133
194
  else
134
195
  return settingDefinition
135
196
  end
136
197
  else
137
- error(("Bad index %q into SettingDefinitionProvider"):format(tostring(index)))
198
+ error(string.format("Bad index %q into SettingDefinitionProvider", tostring(index)))
138
199
  end
139
200
  end
140
201
 
@@ -147,7 +208,16 @@ end
147
208
  function SettingDefinitionProvider:Get(settingName)
148
209
  assert(type(settingName) == "string", "Bad settingName")
149
210
 
150
- return self._lookup[settingName]
211
+ local found = self._lookup[settingName]
212
+ if not found then
213
+ return nil
214
+ end
215
+
216
+ if self._serviceBag then
217
+ return assert(self._initializedDefinitionLookup[found], "Missing settingDefinition")
218
+ else
219
+ return found
220
+ end
151
221
  end
152
222
 
153
223
  --[=[
@@ -83,7 +83,7 @@ function SettingProperty:__index(index)
83
83
  elseif SettingProperty[index] then
84
84
  return SettingProperty[index]
85
85
  else
86
- error(("%q is not a member of SettingProperty %s"):format(tostring(index), self._definition:GetSettingName()))
86
+ error(string.format("%q is not a member of SettingProperty %s", tostring(index), self._definition:GetSettingName()))
87
87
  end
88
88
  end
89
89
 
@@ -91,7 +91,7 @@ function SettingProperty:__newindex(index, value)
91
91
  if index == "Value" then
92
92
  self:SetValue(value)
93
93
  elseif index == "DefaultValue" or index == "Changed" or SettingProperty[index] then
94
- error(("Cannot set %q"):format(tostring(index)))
94
+ error(string.format("Cannot set %q", tostring(index)))
95
95
  else
96
96
  rawset(self, index, value)
97
97
  end
@@ -1,12 +0,0 @@
1
- --[=[
2
- @class SettingsBindersClient
3
- ]=]
4
-
5
- local require = require(script.Parent.loader).load(script)
6
-
7
- local BinderProvider = require("BinderProvider")
8
- local Binder = require("Binder")
9
-
10
- return BinderProvider.new(script.Name, function(self, serviceBag)
11
- self:Add(Binder.new("PlayerSettings", require("PlayerSettingsClient"), serviceBag))
12
- end)
@@ -1,14 +0,0 @@
1
- --[=[
2
- @class SettingsBindersServer
3
- ]=]
4
-
5
- local require = require(script.Parent.loader).load(script)
6
-
7
- local BinderProvider = require("BinderProvider")
8
- local Binder = require("Binder")
9
- local PlayerBinder = require("PlayerBinder")
10
-
11
- return BinderProvider.new(script.Name, function(self, serviceBag)
12
- self:Add(Binder.new("PlayerSettings", require("PlayerSettings"), serviceBag))
13
- self:Add(PlayerBinder.new("PlayerHasSettings", require("PlayerHasSettings"), serviceBag))
14
- end)