@quenty/soundplayer 7.19.3 → 7.19.4-canary.11a5dcf.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.19.4-canary.11a5dcf.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/soundplayer@7.19.3...@quenty/soundplayer@7.19.4-canary.11a5dcf.0) (2025-05-10)
7
+
8
+
9
+ ### Features
10
+
11
+ * Add even more types ([b31717d](https://github.com/Quenty/NevermoreEngine/commit/b31717d8c9f7620c457f5018a2affa760a65334a))
12
+
13
+
14
+
15
+
16
+
6
17
  ## [7.19.3](https://github.com/Quenty/NevermoreEngine/compare/@quenty/soundplayer@7.19.2...@quenty/soundplayer@7.19.3) (2025-04-10)
7
18
 
8
19
  **Note:** Version bump only for package @quenty/soundplayer
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quenty/soundplayer",
3
- "version": "7.19.3",
3
+ "version": "7.19.4-canary.11a5dcf.0",
4
4
  "description": "Sound playback helper",
5
5
  "keywords": [
6
6
  "Roblox",
@@ -25,28 +25,28 @@
25
25
  "Quenty"
26
26
  ],
27
27
  "dependencies": {
28
- "@quenty/adorneeutils": "^3.3.3",
29
- "@quenty/baseobject": "^10.8.3",
30
- "@quenty/blend": "^12.18.3",
31
- "@quenty/brio": "^14.17.3",
32
- "@quenty/instanceutils": "^13.17.3",
33
- "@quenty/loader": "^10.8.3",
34
- "@quenty/maid": "^3.4.3",
35
- "@quenty/numberrangeutils": "^3.1.1",
36
- "@quenty/promise": "^10.10.4",
37
- "@quenty/promisemaid": "^5.10.4",
38
- "@quenty/randomutils": "^6.10.3",
39
- "@quenty/rbxasset": "^5.8.3",
40
- "@quenty/rx": "^13.17.3",
41
- "@quenty/signal": "^7.10.3",
42
- "@quenty/sounds": "^10.10.4",
43
- "@quenty/table": "^3.7.4",
44
- "@quenty/transitionmodel": "^7.19.3",
45
- "@quenty/valueobject": "^13.17.3",
28
+ "@quenty/adorneeutils": "3.3.3",
29
+ "@quenty/baseobject": "10.8.4-canary.11a5dcf.0",
30
+ "@quenty/blend": "12.18.4-canary.11a5dcf.0",
31
+ "@quenty/brio": "14.17.4-canary.11a5dcf.0",
32
+ "@quenty/instanceutils": "13.17.4-canary.11a5dcf.0",
33
+ "@quenty/loader": "10.8.4-canary.11a5dcf.0",
34
+ "@quenty/maid": "3.4.4-canary.11a5dcf.0",
35
+ "@quenty/numberrangeutils": "3.1.1",
36
+ "@quenty/promise": "10.10.5-canary.11a5dcf.0",
37
+ "@quenty/promisemaid": "5.10.5-canary.11a5dcf.0",
38
+ "@quenty/randomutils": "6.10.4-canary.11a5dcf.0",
39
+ "@quenty/rbxasset": "5.8.4-canary.11a5dcf.0",
40
+ "@quenty/rx": "13.17.4-canary.11a5dcf.0",
41
+ "@quenty/signal": "7.10.4-canary.11a5dcf.0",
42
+ "@quenty/sounds": "10.10.5-canary.11a5dcf.0",
43
+ "@quenty/table": "3.7.5-canary.11a5dcf.0",
44
+ "@quenty/transitionmodel": "7.19.4-canary.11a5dcf.0",
45
+ "@quenty/valueobject": "13.17.4-canary.11a5dcf.0",
46
46
  "@quentystudios/t": "^3.0.0"
47
47
  },
48
48
  "publishConfig": {
49
49
  "access": "public"
50
50
  },
51
- "gitHead": "b06c070ae91d5dab7bd8de6e290ad2caabb15d8f"
51
+ "gitHead": "11a5dcf7d4c7a0bfbf3337e97d30e8346ea09d3f"
52
52
  }
@@ -4,13 +4,14 @@
4
4
 
5
5
  local require = require(script.Parent.loader).load(script)
6
6
 
7
- local SpringTransitionModel = require("SpringTransitionModel")
8
- local ValueObject = require("ValueObject")
9
7
  local LoopedSoundPlayer = require("LoopedSoundPlayer")
10
8
  local Maid = require("Maid")
11
9
  local Rx = require("Rx")
12
- local SoundUtils = require("SoundUtils")
13
10
  local SoundLoopScheduleUtils = require("SoundLoopScheduleUtils")
11
+ local SoundUtils = require("SoundUtils")
12
+ local SpringTransitionModel = require("SpringTransitionModel")
13
+ local ValueObject = require("ValueObject")
14
+ local t = require("t")
14
15
 
15
16
  local LayeredLoopedSoundPlayer = setmetatable({}, SpringTransitionModel)
16
17
  LayeredLoopedSoundPlayer.ClassName = "LayeredLoopedSoundPlayer"
@@ -21,9 +22,9 @@ function LayeredLoopedSoundPlayer.new(soundParent)
21
22
 
22
23
  self._layerMaid = self._maid:Add(Maid.new())
23
24
 
24
- self._soundParent = self._maid:Add(ValueObject.new(nil))
25
- self._soundGroup = self._maid:Add(ValueObject.new(nil))
26
- self._bpm = self._maid:Add(ValueObject.new(nil))
25
+ self._soundParent = self._maid:Add(ValueObject.new(nil, t.optional(t.Instance)))
26
+ self._soundGroup = self._maid:Add(ValueObject.new(nil, t.optional(t.Instance)))
27
+ self._bpm = self._maid:Add(ValueObject.new(nil, t.optional(t.number)))
27
28
  self._defaultCrossFadeTime = self._maid:Add(ValueObject.new(0.5, "number"))
28
29
  self._volumeMultiplier = self._maid:Add(ValueObject.new(1, "number"))
29
30
 
@@ -36,32 +37,30 @@ function LayeredLoopedSoundPlayer.new(soundParent)
36
37
  return self
37
38
  end
38
39
 
39
- function LayeredLoopedSoundPlayer:SetDefaultCrossFadeTime(crossFadeTime)
40
+ function LayeredLoopedSoundPlayer:SetDefaultCrossFadeTime(crossFadeTime: ValueObject.Mountable<number>)
40
41
  return self._defaultCrossFadeTime:Mount(crossFadeTime)
41
42
  end
42
43
 
43
- function LayeredLoopedSoundPlayer:SetVolumeMultiplier(volumeMultiplier)
44
- self._volumeMultiplier.Value = volumeMultiplier
44
+ function LayeredLoopedSoundPlayer:SetVolumeMultiplier(volumeMultiplier: ValueObject.Mountable<number>)
45
+ return self._volumeMultiplier:Mount(volumeMultiplier)
45
46
  end
46
47
 
47
- function LayeredLoopedSoundPlayer:SetBPM(bpm)
48
- assert(type(bpm) == "number" or bpm == nil, "Bad bpm")
49
-
48
+ function LayeredLoopedSoundPlayer:SetBPM(bpm: ValueObject.Mountable<number?>)
50
49
  self._bpm.Value = bpm
51
50
  end
52
51
 
53
- function LayeredLoopedSoundPlayer:SetSoundParent(soundParent)
52
+ function LayeredLoopedSoundPlayer:SetSoundParent(soundParent: Instance?)
54
53
  assert(typeof(soundParent) == "Instance" or soundParent == nil, "Bad soundParent")
55
54
 
56
55
  self._soundParent.Value = soundParent
57
56
  end
58
57
 
59
- function LayeredLoopedSoundPlayer:SetSoundGroup(soundGroup)
58
+ function LayeredLoopedSoundPlayer:SetSoundGroup(soundGroup: SoundGroup?)
60
59
  return self._soundGroup:Mount(soundGroup)
61
60
  end
62
61
 
63
- function LayeredLoopedSoundPlayer:Swap(layerId, soundId, scheduleOptions)
64
- assert(type(layerId) == "string", 'Bad layerId')
62
+ function LayeredLoopedSoundPlayer:Swap(layerId: string, soundId, scheduleOptions)
63
+ assert(type(layerId) == "string", "Bad layerId")
65
64
  assert(SoundUtils.isConvertableToRbxAsset(soundId) or soundId == nil, "Bad soundId")
66
65
  assert(SoundLoopScheduleUtils.isLoopedSchedule(scheduleOptions) or scheduleOptions == nil, "Bad scheduleOptions")
67
66
 
@@ -70,7 +69,7 @@ function LayeredLoopedSoundPlayer:Swap(layerId, soundId, scheduleOptions)
70
69
  end
71
70
 
72
71
  function LayeredLoopedSoundPlayer:SwapOnLoop(layerId, soundId, scheduleOptions)
73
- assert(type(layerId) == "string", 'Bad layerId')
72
+ assert(type(layerId) == "string", "Bad layerId")
74
73
  assert(SoundUtils.isConvertableToRbxAsset(soundId) or soundId == nil, "Bad soundId")
75
74
 
76
75
  local layer = self:_getOrCreateLayer(layerId)
@@ -78,7 +77,7 @@ function LayeredLoopedSoundPlayer:SwapOnLoop(layerId, soundId, scheduleOptions)
78
77
  end
79
78
 
80
79
  function LayeredLoopedSoundPlayer:SwapToSamples(layerId, soundId, scheduleOptions)
81
- assert(type(layerId) == "string", 'Bad layerId')
80
+ assert(type(layerId) == "string", "Bad layerId")
82
81
  assert(SoundUtils.isConvertableToRbxAsset(soundId) or soundId == nil, "Bad soundId")
83
82
  assert(SoundLoopScheduleUtils.isLoopedSchedule(scheduleOptions) or scheduleOptions == nil, "Bad scheduleOptions")
84
83
 
@@ -87,7 +86,7 @@ function LayeredLoopedSoundPlayer:SwapToSamples(layerId, soundId, scheduleOption
87
86
  end
88
87
 
89
88
  function LayeredLoopedSoundPlayer:SwapToChoice(layerId, soundIdList, scheduleOptions)
90
- assert(type(layerId) == "string", 'Bad layerId')
89
+ assert(type(layerId) == "string", "Bad layerId")
91
90
  assert(type(soundIdList) == "table", "Bad soundIdList")
92
91
  assert(SoundLoopScheduleUtils.isLoopedSchedule(scheduleOptions) or scheduleOptions == nil, "Bad scheduleOptions")
93
92
 
@@ -96,7 +95,7 @@ function LayeredLoopedSoundPlayer:SwapToChoice(layerId, soundIdList, scheduleOpt
96
95
  end
97
96
 
98
97
  function LayeredLoopedSoundPlayer:PlayOnce(layerId, soundIdList, scheduleOptions)
99
- assert(type(layerId) == "string", 'Bad layerId')
98
+ assert(type(layerId) == "string", "Bad layerId")
100
99
  assert(type(soundIdList) == "table", "Bad soundIdList")
101
100
  assert(SoundLoopScheduleUtils.isLoopedSchedule(scheduleOptions) or scheduleOptions == nil, "Bad scheduleOptions")
102
101
 
@@ -105,14 +104,14 @@ function LayeredLoopedSoundPlayer:PlayOnce(layerId, soundIdList, scheduleOptions
105
104
  end
106
105
 
107
106
  function LayeredLoopedSoundPlayer:PlayOnceOnLoop(layerId, soundId, scheduleOptions)
108
- assert(type(layerId) == "string", 'Bad layerId')
107
+ assert(type(layerId) == "string", "Bad layerId")
109
108
 
110
109
  local layer = self:_getOrCreateLayer(layerId)
111
110
  layer:PlayOnceOnLoop(soundId, scheduleOptions)
112
111
  end
113
112
 
114
113
  function LayeredLoopedSoundPlayer:_getOrCreateLayer(layerId)
115
- if self._layers[layerId] then
114
+ if self._layers[layerId] then
116
115
  return self._layers[layerId]
117
116
  end
118
117
 
@@ -140,10 +139,10 @@ function LayeredLoopedSoundPlayer:_getOrCreateLayer(layerId)
140
139
  end))
141
140
 
142
141
  maid:GiveTask(Rx.combineLatest({
143
- visible = self:ObserveRenderStepped();
144
- multiplier = self._volumeMultiplier:Observe();
142
+ visible = self:ObserveRenderStepped(),
143
+ multiplier = self._volumeMultiplier:Observe(),
145
144
  }):Subscribe(function(state)
146
- layer:SetVolumeMultiplier(state.multiplier*state.visible)
145
+ layer:SetVolumeMultiplier(state.multiplier * state.visible)
147
146
  end))
148
147
 
149
148
  self._layers[layerId] = layer
@@ -168,4 +167,4 @@ function LayeredLoopedSoundPlayer:StopAll()
168
167
  self._layerMaid:DoCleaning()
169
168
  end
170
169
 
171
- return LayeredLoopedSoundPlayer
170
+ return LayeredLoopedSoundPlayer
@@ -2,11 +2,12 @@
2
2
  @class LayeredLoopedSoundPlayer.story
3
3
  ]]
4
4
 
5
- local require = require(game:GetService("ServerScriptService"):FindFirstChild("LoaderUtils", true).Parent).bootstrapStory(script)
5
+ local require =
6
+ require(game:GetService("ServerScriptService"):FindFirstChild("LoaderUtils", true).Parent).bootstrapStory(script)
6
7
 
7
- local Maid = require("Maid")
8
- local LayeredLoopedSoundPlayer = require("LayeredLoopedSoundPlayer")
9
8
  local Blend = require("Blend")
9
+ local LayeredLoopedSoundPlayer = require("LayeredLoopedSoundPlayer")
10
+ local Maid = require("Maid")
10
11
 
11
12
  return function(target)
12
13
  local maid = Maid.new()
@@ -19,23 +20,23 @@ return function(target)
19
20
  local function initial()
20
21
  layeredLoopedSoundPlayer:SwapToChoice("drums", {
21
22
  {
22
- SoundId = "rbxassetid://14478151709";
23
- Volume = 0.1;
24
- };
23
+ SoundId = "rbxassetid://14478151709",
24
+ Volume = 0.1,
25
+ },
25
26
  {
26
- SoundId = "rbxassetid://14478738244";
27
- Volume = 0.1;
28
- }
27
+ SoundId = "rbxassetid://14478738244",
28
+ Volume = 0.1,
29
+ },
29
30
  })
30
31
  layeredLoopedSoundPlayer:SwapToChoice("rifts", {
31
32
  {
32
- SoundId = "rbxassetid://14478152812";
33
- Volume = 0.2;
34
- };
33
+ SoundId = "rbxassetid://14478152812",
34
+ Volume = 0.2,
35
+ },
35
36
  {
36
- SoundId = "rbxassetid://14478729478";
37
- Volume = 0.015;
38
- };
37
+ SoundId = "rbxassetid://14478729478",
38
+ Volume = 0.015,
39
+ },
39
40
  })
40
41
  end
41
42
  initial()
@@ -44,117 +45,112 @@ return function(target)
44
45
 
45
46
  local function button(props)
46
47
  return Blend.New "TextButton" {
47
- Text = props.Text;
48
- AutoButtonColor = true;
49
- Font = Enum.Font.FredokaOne;
50
- Size = UDim2.new(0, 100, 0, 30);
51
-
52
- Blend.New "UICorner" {
48
+ Text = props.Text,
49
+ AutoButtonColor = true,
50
+ Font = Enum.Font.FredokaOne,
51
+ Size = UDim2.new(0, 100, 0, 30),
53
52
 
54
- };
53
+ Blend.New "UICorner" {},
55
54
 
56
55
  [Blend.OnEvent "Activated"] = function()
57
- props.OnActivated();
58
- end;
59
- };
56
+ props.OnActivated()
57
+ end,
58
+ }
60
59
  end
61
60
 
62
61
  maid:GiveTask(Blend.mount(target, {
63
62
  Blend.New "Frame" {
64
- Name = "ButtonContainer";
65
- BackgroundTransparency = 1;
66
- Position = UDim2.new(0.5, 0, 0, 5);
67
- AnchorPoint = Vector2.new(0.5, 0);
68
- Size = UDim2.new(1, 0, 0, 30);
63
+ Name = "ButtonContainer",
64
+ BackgroundTransparency = 1,
65
+ Position = UDim2.new(0.5, 0, 0, 5),
66
+ AnchorPoint = Vector2.new(0.5, 0),
67
+ Size = UDim2.new(1, 0, 0, 30),
69
68
 
70
69
  Blend.New "UIListLayout" {
71
- FillDirection = Enum.FillDirection.Horizontal;
72
- Padding = UDim.new(0, 5);
73
- HorizontalAlignment = Enum.HorizontalAlignment.Center;
74
- };
70
+ FillDirection = Enum.FillDirection.Horizontal,
71
+ Padding = UDim.new(0, 5),
72
+ HorizontalAlignment = Enum.HorizontalAlignment.Center,
73
+ },
75
74
 
76
75
  button({
77
- Text = "Toggle";
76
+ Text = "Toggle",
78
77
  OnActivated = function()
79
78
  layeredLoopedSoundPlayer:Toggle()
80
- end;
81
- });
79
+ end,
80
+ }),
82
81
 
83
82
  button({
84
- Text = "Reset";
83
+ Text = "Reset",
85
84
  OnActivated = function()
86
85
  initial()
87
- end;
88
- });
86
+ end,
87
+ }),
89
88
 
90
89
  button({
91
- Text = "Combat equip";
90
+ Text = "Combat equip",
92
91
  OnActivated = function()
93
92
  layeredLoopedSoundPlayer:SwapToChoice("drums", {
94
- "rbxassetid://14478154829";
95
- "rbxassetid://14478714545";
96
- "rbxassetid://14478772830";
97
- "rbxassetid://14478897865";
93
+ "rbxassetid://14478154829",
94
+ "rbxassetid://14478714545",
95
+ "rbxassetid://14478772830",
96
+ "rbxassetid://14478897865",
98
97
  })
99
98
  layeredLoopedSoundPlayer:PlayOnceOnLoop("rifts", nil)
100
- end;
101
- });
99
+ end,
100
+ }),
102
101
 
103
102
  button({
104
- Text = "On target lock";
103
+ Text = "On target lock",
105
104
  OnActivated = function()
106
105
  layeredLoopedSoundPlayer:SwapToChoice("drums", {
107
106
  {
108
- SoundId = "rbxassetid://14478150956";
109
- Volume = 0.1;
110
- };
107
+ SoundId = "rbxassetid://14478150956",
108
+ Volume = 0.1,
109
+ },
111
110
  {
112
- SoundId = "rbxassetid://14478721669";
113
- Volume = 0.2;
114
- };
115
- "rbxassetid://14478154829";
116
- "rbxassetid://14478764914";
111
+ SoundId = "rbxassetid://14478721669",
112
+ Volume = 0.2,
113
+ },
114
+ "rbxassetid://14478154829",
115
+ "rbxassetid://14478764914",
117
116
  })
118
117
 
119
118
  layeredLoopedSoundPlayer:SwapToChoice("rifts", {
120
- "rbxassetid://14478145963";
121
- "rbxassetid://14478156714";
119
+ "rbxassetid://14478145963",
120
+ "rbxassetid://14478156714",
122
121
  {
123
- SoundId = "rbxassetid://14478777472";
124
- Volume = 0.1;
125
- };
122
+ SoundId = "rbxassetid://14478777472",
123
+ Volume = 0.1,
124
+ },
126
125
  {
127
- SoundId = "rbxassetid://14478793045";
128
- Volume = 0.1;
129
- };
126
+ SoundId = "rbxassetid://14478793045",
127
+ Volume = 0.1,
128
+ },
130
129
  })
131
- end;
132
- });
130
+ end,
131
+ }),
133
132
 
134
133
  button({
135
- Text = "On low health";
134
+ Text = "On low health",
136
135
  OnActivated = function()
137
136
  layeredLoopedSoundPlayer:SwapToChoice("drums", {
138
- "rbxassetid://14478746326";
139
- "rbxassetid://14478767498";
140
- "rbxassetid://14478797936"; -- record scratch
137
+ "rbxassetid://14478746326",
138
+ "rbxassetid://14478767498",
139
+ "rbxassetid://14478797936", -- record scratch
141
140
  })
142
-
143
- end;
144
- });
145
-
141
+ end,
142
+ }),
146
143
 
147
144
  button({
148
- Text = "Target drop";
145
+ Text = "Target drop",
149
146
  OnActivated = function()
150
147
  layeredLoopedSoundPlayer:PlayOnceOnLoop("rifts", "rbxassetid://14478158396")
151
- end;
152
- });
153
- }
148
+ end,
149
+ }),
150
+ },
154
151
  }))
155
152
 
156
-
157
153
  return function()
158
154
  maid:DoCleaning()
159
155
  end
160
- end
156
+ end
@@ -1,3 +1,4 @@
1
+ --!strict
1
2
  --[=[
2
3
  @class LoopedSoundPlayer
3
4
  ]=]
@@ -25,13 +26,31 @@ local LoopedSoundPlayer = setmetatable({}, SpringTransitionModel)
25
26
  LoopedSoundPlayer.ClassName = "LoopedSoundPlayer"
26
27
  LoopedSoundPlayer.__index = LoopedSoundPlayer
27
28
 
28
- function LoopedSoundPlayer.new(soundId, soundParent: Instance?)
29
- assert(SoundUtils.isConvertableToRbxAsset(soundId) or soundId == nil, "Bad soundId")
30
-
31
- local self = setmetatable(SpringTransitionModel.new(), LoopedSoundPlayer)
32
-
33
- self._currentSoundLooped = self._maid:Add(Signal.new())
34
- self._currentSoundLoopedAfterDelay = self._maid:Add(Signal.new())
29
+ export type LoopedSoundPlayer = typeof(setmetatable(
30
+ {} :: {
31
+ _currentSoundLooped: Signal.Signal<()>,
32
+ _currentSoundLoopedAfterDelay: Signal.Signal<()>,
33
+ _bpm: ValueObject.ValueObject<number?>,
34
+ _soundParent: ValueObject.ValueObject<Instance?>,
35
+ _soundGroup: ValueObject.ValueObject<SoundGroup?>,
36
+ _crossFadeTime: ValueObject.ValueObject<number>,
37
+ _volumeMultiplier: ValueObject.ValueObject<number>,
38
+ _doSyncSoundPlayback: ValueObject.ValueObject<boolean>,
39
+ _currentActiveSound: ValueObject.ValueObject<Sound?>,
40
+ _currentSoundId: ValueObject.ValueObject<(string | number)?>,
41
+ _defaultScheduleOptions: SoundLoopScheduleUtils.SoundLoopSchedule,
42
+ _currentLoopSchedule: ValueObject.ValueObject<SoundLoopScheduleUtils.SoundLoopSchedule>,
43
+ },
44
+ {} :: typeof({ __index = LoopedSoundPlayer })
45
+ )) & SpringTransitionModel.SpringTransitionModel<number>
46
+
47
+ function LoopedSoundPlayer.new(soundId: (string | number)?, soundParent: Instance?)
48
+ assert(soundId == nil or SoundUtils.isConvertableToRbxAsset(soundId), "Bad soundId")
49
+
50
+ local self: LoopedSoundPlayer = setmetatable(SpringTransitionModel.new() :: any, LoopedSoundPlayer)
51
+
52
+ self._currentSoundLooped = self._maid:Add(Signal.new() :: any)
53
+ self._currentSoundLoopedAfterDelay = self._maid:Add(Signal.new() :: any)
35
54
 
36
55
  self:SetSpeed(10)
37
56
 
@@ -60,29 +79,29 @@ function LoopedSoundPlayer.new(soundId, soundParent: Instance?)
60
79
  return self
61
80
  end
62
81
 
63
- function LoopedSoundPlayer:SetCrossFadeTime(crossFadeTime: number)
82
+ function LoopedSoundPlayer.SetCrossFadeTime(self: LoopedSoundPlayer, crossFadeTime: number)
64
83
  return self._crossFadeTime:Mount(crossFadeTime)
65
84
  end
66
85
 
67
- function LoopedSoundPlayer:SetVolumeMultiplier(volume: number)
86
+ function LoopedSoundPlayer.SetVolumeMultiplier(self: LoopedSoundPlayer, volume: number)
68
87
  self._volumeMultiplier.Value = volume
69
88
  end
70
89
 
71
- function LoopedSoundPlayer:SetSoundGroup(soundGroup: SoundGroup?)
90
+ function LoopedSoundPlayer.SetSoundGroup(self: LoopedSoundPlayer, soundGroup: SoundGroup?)
72
91
  return self._soundGroup:Mount(soundGroup)
73
92
  end
74
93
 
75
- function LoopedSoundPlayer:SetBPM(bpm: number?)
94
+ function LoopedSoundPlayer.SetBPM(self: LoopedSoundPlayer, bpm: number?)
76
95
  assert(type(bpm) == "number" or bpm == nil, "Bad bpm")
77
96
 
78
97
  self._bpm.Value = bpm
79
98
  end
80
99
 
81
- function LoopedSoundPlayer:SetSoundParent(parent: Instance?)
100
+ function LoopedSoundPlayer.SetSoundParent(self: LoopedSoundPlayer, parent: Instance?)
82
101
  self._soundParent.Value = parent
83
102
  end
84
103
 
85
- function LoopedSoundPlayer:Swap(soundId, loopSchedule)
104
+ function LoopedSoundPlayer.Swap(self: LoopedSoundPlayer, soundId, loopSchedule)
86
105
  assert(SoundUtils.isConvertableToRbxAsset(soundId) or soundId == nil, "Bad soundId")
87
106
  loopSchedule = self:_convertToLoopedSchedule(loopSchedule)
88
107
 
@@ -96,11 +115,11 @@ function LoopedSoundPlayer:Swap(soundId, loopSchedule)
96
115
  self._maid._swappingTo = maid
97
116
  end
98
117
 
99
- function LoopedSoundPlayer:SetDoSyncSoundPlayback(doSyncSoundPlayback: boolean)
118
+ function LoopedSoundPlayer.SetDoSyncSoundPlayback(self: LoopedSoundPlayer, doSyncSoundPlayback: boolean)
100
119
  self._doSyncSoundPlayback.Value = doSyncSoundPlayback
101
120
  end
102
121
 
103
- function LoopedSoundPlayer:_setupRender()
122
+ function LoopedSoundPlayer._setupRender(self: LoopedSoundPlayer)
104
123
  self._maid:GiveTask(self._currentSoundId
105
124
  :ObserveBrio(function(value)
106
125
  return value ~= nil
@@ -117,7 +136,7 @@ function LoopedSoundPlayer:_setupRender()
117
136
  end))
118
137
  end
119
138
 
120
- function LoopedSoundPlayer:_renderSoundPlayer(soundId)
139
+ function LoopedSoundPlayer._renderSoundPlayer(self: LoopedSoundPlayer, soundId)
121
140
  local maid = Maid.new()
122
141
 
123
142
  local renderMaid = Maid.new()
@@ -133,7 +152,7 @@ function LoopedSoundPlayer:_renderSoundPlayer(soundId)
133
152
  isLoaded = Rx.fromPromise(SoundPromiseUtils.promiseLoaded(soundPlayer.Sound)),
134
153
  doSyncSoundPlayback = self._doSyncSoundPlayback:Observe(),
135
154
  timeLength = RxInstanceUtils.observeProperty(soundPlayer.Sound, "TimeLength"),
136
- }):Subscribe(function(state)
155
+ }):Subscribe(function(state: any)
137
156
  local syncMaid = Maid.new()
138
157
 
139
158
  if state.doSyncSoundPlayback then
@@ -197,7 +216,7 @@ function LoopedSoundPlayer:_renderSoundPlayer(soundId)
197
216
  maid:GiveTask(Rx.combineLatest({
198
217
  visible = self:ObserveRenderStepped(),
199
218
  multiplier = self._volumeMultiplier:Observe(),
200
- }):Subscribe(function(state)
219
+ }):Subscribe(function(state: any)
201
220
  soundPlayer:SetVolumeMultiplier(state.multiplier * state.visible)
202
221
  end))
203
222
 
@@ -214,7 +233,7 @@ function LoopedSoundPlayer:_renderSoundPlayer(soundId)
214
233
  return maid
215
234
  end
216
235
 
217
- function LoopedSoundPlayer:_setupLoopScheduling(soundPlayer, loopSchedule)
236
+ function LoopedSoundPlayer._setupLoopScheduling(self: LoopedSoundPlayer, soundPlayer, loopSchedule)
218
237
  local maid = Maid.new()
219
238
 
220
239
  if loopSchedule.maxLoops then
@@ -249,7 +268,7 @@ function LoopedSoundPlayer:_setupLoopScheduling(soundPlayer, loopSchedule)
249
268
  return maid
250
269
  end
251
270
 
252
- function LoopedSoundPlayer:SwapToSamples(soundIdList, loopSchedule)
271
+ function LoopedSoundPlayer.SwapToSamples(self: LoopedSoundPlayer, soundIdList, loopSchedule)
253
272
  assert(type(soundIdList) == "table", "Bad soundIdList")
254
273
  loopSchedule = self:_convertToLoopedSchedule(loopSchedule)
255
274
 
@@ -268,7 +287,7 @@ function LoopedSoundPlayer:SwapToSamples(soundIdList, loopSchedule)
268
287
  self._maid._swappingTo = loopMaid
269
288
  end
270
289
 
271
- function LoopedSoundPlayer:SwapToChoice(soundIdList, loopSchedule)
290
+ function LoopedSoundPlayer.SwapToChoice(self: LoopedSoundPlayer, soundIdList, loopSchedule)
272
291
  assert(type(soundIdList) == "table", "Bad soundIdList")
273
292
  loopSchedule = self:_convertToLoopedSchedule(loopSchedule)
274
293
 
@@ -286,39 +305,39 @@ function LoopedSoundPlayer:SwapToChoice(soundIdList, loopSchedule)
286
305
  self._maid._swappingTo = loopMaid
287
306
  end
288
307
 
289
- function LoopedSoundPlayer:PlayOnce(soundId, loopSchedule)
308
+ function LoopedSoundPlayer.PlayOnce(self: LoopedSoundPlayer, soundId, loopSchedule)
290
309
  assert(SoundUtils.isConvertableToRbxAsset(soundId) or soundId == nil, "Bad soundId")
291
310
  loopSchedule = self:_convertToLoopedSchedule(loopSchedule)
292
311
 
293
312
  self:Swap(soundId, SoundLoopScheduleUtils.maxLoops(1, loopSchedule))
294
313
  end
295
314
 
296
- function LoopedSoundPlayer:SwapOnLoop(soundId, loopSchedule)
315
+ function LoopedSoundPlayer.SwapOnLoop(self: LoopedSoundPlayer, soundId, loopSchedule)
297
316
  assert(SoundUtils.isConvertableToRbxAsset(soundId) or soundId == nil, "Bad soundId")
298
317
  loopSchedule = self:_convertToLoopedSchedule(loopSchedule)
299
318
 
300
319
  self:Swap(soundId, SoundLoopScheduleUtils.onNextLoop(loopSchedule))
301
320
  end
302
321
 
303
- function LoopedSoundPlayer:PlayOnceOnLoop(soundId, loopSchedule)
322
+ function LoopedSoundPlayer.PlayOnceOnLoop(self: LoopedSoundPlayer, soundId, loopSchedule)
304
323
  assert(SoundUtils.isConvertableToRbxAsset(soundId) or soundId == nil, "Bad soundId")
305
324
  loopSchedule = self:_convertToLoopedSchedule(loopSchedule)
306
325
 
307
326
  self:PlayOnce(soundId, SoundLoopScheduleUtils.onNextLoop(loopSchedule))
308
327
  end
309
328
 
310
- function LoopedSoundPlayer:_convertToLoopedSchedule(loopSchedule)
329
+ function LoopedSoundPlayer._convertToLoopedSchedule(self: LoopedSoundPlayer, loopSchedule)
311
330
  assert(SoundLoopScheduleUtils.isLoopedSchedule(loopSchedule) or loopSchedule == nil, "Bad loopSchedule")
312
331
  return loopSchedule or self._defaultScheduleOptions
313
332
  end
314
333
 
315
- function LoopedSoundPlayer:_scheduleFirstPlay(loopSchedule, callback)
334
+ function LoopedSoundPlayer._scheduleFirstPlay(self: LoopedSoundPlayer, loopSchedule, callback)
316
335
  assert(SoundLoopScheduleUtils.isLoopedSchedule(loopSchedule), "Bad loopSchedule")
317
336
  assert(type(callback) == "function", "Bad callback")
318
337
 
319
338
  local maid = Maid.new()
320
339
 
321
- local observable = Rx.of(true)
340
+ local observable: any = Rx.of(true)
322
341
  if loopSchedule.playOnNextLoop then
323
342
  observable = observable:Pipe({
324
343
  Rx.switchMap(function()
@@ -328,15 +347,15 @@ function LoopedSoundPlayer:_scheduleFirstPlay(loopSchedule, callback)
328
347
  end
329
348
 
330
349
  return self:_observeActiveSoundFinishLoop(waitTime)
331
- end),
350
+ end) :: any,
332
351
  })
333
352
  end
334
353
 
335
354
  if loopSchedule.initialDelay then
336
355
  observable = observable:Pipe({
337
356
  Rx.switchMap(function()
338
- return Rx.delayed(SoundLoopScheduleUtils.getWaitTimeSeconds(loopSchedule.initialDelay))
339
- end),
357
+ return Rx.delayed(SoundLoopScheduleUtils.getWaitTimeSeconds(loopSchedule.initialDelay)) :: any
358
+ end) :: any,
340
359
  })
341
360
  end
342
361
 
@@ -353,7 +372,7 @@ function LoopedSoundPlayer:_scheduleFirstPlay(loopSchedule, callback)
353
372
  return maid
354
373
  end
355
374
 
356
- function LoopedSoundPlayer:StopAfterLoop()
375
+ function LoopedSoundPlayer.StopAfterLoop(self: LoopedSoundPlayer)
357
376
  local swapMaid = Maid.new()
358
377
 
359
378
  swapMaid:GiveTask(self._currentSoundLooped:Connect(function()
@@ -365,22 +384,22 @@ function LoopedSoundPlayer:StopAfterLoop()
365
384
  self._maid._swappingTo = swapMaid
366
385
  end
367
386
 
368
- function LoopedSoundPlayer:_observeActiveSoundFinishLoop(maxWaitTime)
387
+ function LoopedSoundPlayer._observeActiveSoundFinishLoop(self: LoopedSoundPlayer, maxWaitTime)
369
388
  local startTime = os.clock()
370
389
 
371
390
  return self._currentActiveSound:Observe():Pipe({
372
- Rx.throttleDefer();
373
- Rx.switchMap(function(sound)
391
+ Rx.throttleDefer() :: any,
392
+ Rx.switchMap(function(sound): any
374
393
  if not sound then
375
394
  return Rx.of(true)
376
395
  end
377
396
 
378
397
  return Rx.combineLatest({
379
- timeLength = RxInstanceUtils.observeProperty(sound, "TimeLength");
380
- timePosition = RxInstanceUtils.observeProperty(sound, "TimePosition");
381
- crossFadeTime = self._crossFadeTime:Observe();
398
+ timeLength = RxInstanceUtils.observeProperty(sound, "TimeLength"),
399
+ timePosition = RxInstanceUtils.observeProperty(sound, "TimePosition"),
400
+ crossFadeTime = self._crossFadeTime:Observe(),
382
401
  }):Pipe({
383
- Rx.switchMap(function(state)
402
+ Rx.switchMap(function(state: any): any
384
403
  local timeElapsed = os.clock() - startTime
385
404
  local timeRemaining
386
405
  if maxWaitTime then
@@ -403,13 +422,13 @@ function LoopedSoundPlayer:_observeActiveSoundFinishLoop(maxWaitTime)
403
422
  end
404
423
 
405
424
  return Rx.delayed(waitTime)
406
- end);
425
+ end) :: any,
407
426
  })
408
- end)
409
- })
427
+ end) :: any,
428
+ }) :: any
410
429
  end
411
430
 
412
- function LoopedSoundPlayer:PromiseLoopDone()
431
+ function LoopedSoundPlayer.PromiseLoopDone(self: LoopedSoundPlayer): Promise.Promise<()>
413
432
  local promise = self._maid:GivePromise(Promise.new())
414
433
 
415
434
  PromiseMaidUtils.whilePromise(promise, function(maid)
@@ -421,14 +440,13 @@ function LoopedSoundPlayer:PromiseLoopDone()
421
440
  return promise
422
441
  end
423
442
 
424
- function LoopedSoundPlayer:PromiseSustain()
443
+ function LoopedSoundPlayer.PromiseSustain(_self: LoopedSoundPlayer): Promise.Promise<()>
425
444
  -- Never resolve (?)
426
445
  return Promise.new()
427
446
  end
428
447
 
429
-
430
- function LoopedSoundPlayer:GetSound()
431
- return self._sound
448
+ function LoopedSoundPlayer.GetSound(self: LoopedSoundPlayer): Sound?
449
+ return self._currentActiveSound.Value
432
450
  end
433
451
 
434
- return LoopedSoundPlayer
452
+ return LoopedSoundPlayer
@@ -2,13 +2,14 @@
2
2
  @class LoopedSoundPlayer.story
3
3
  ]]
4
4
 
5
- local require = require(game:GetService("ServerScriptService"):FindFirstChild("LoaderUtils", true).Parent).bootstrapStory(script)
5
+ local require =
6
+ require(game:GetService("ServerScriptService"):FindFirstChild("LoaderUtils", true).Parent).bootstrapStory(script)
6
7
 
7
- local Maid = require("Maid")
8
- local LoopedSoundPlayer = require("LoopedSoundPlayer")
9
- local RandomUtils = require("RandomUtils")
10
8
  local Blend = require("Blend")
9
+ local LoopedSoundPlayer = require("LoopedSoundPlayer")
11
10
  local LoopedSoundScheduleUtils = require("LoopedSoundScheduleUtils")
11
+ local Maid = require("Maid")
12
+ local RandomUtils = require("RandomUtils")
12
13
 
13
14
  return function(target)
14
15
  local maid = Maid.new()
@@ -22,7 +23,7 @@ return function(target)
22
23
  loopedSoundPlayer:SetSoundParent(target)
23
24
 
24
25
  local OPTIONS = {
25
- "rbxassetid://14477453689";
26
+ "rbxassetid://14477453689",
26
27
  }
27
28
 
28
29
  maid:GiveTask(task.spawn(function()
@@ -36,89 +37,90 @@ return function(target)
36
37
 
37
38
  local function button(props)
38
39
  return Blend.New "TextButton" {
39
- Text = props.Text;
40
- AutoButtonColor = true;
41
- Font = Enum.Font.FredokaOne;
42
- Size = UDim2.new(0, 100, 0, 30);
43
-
44
- Blend.New "UICorner" {
40
+ Text = props.Text,
41
+ AutoButtonColor = true,
42
+ Font = Enum.Font.FredokaOne,
43
+ Size = UDim2.new(0, 100, 0, 30),
45
44
 
46
- };
45
+ Blend.New "UICorner" {},
47
46
 
48
47
  [Blend.OnEvent "Activated"] = function()
49
- props.OnActivated();
50
- end;
51
- };
48
+ props.OnActivated()
49
+ end,
50
+ }
52
51
  end
53
52
 
54
53
  maid:GiveTask(Blend.mount(target, {
55
54
  Blend.New "Frame" {
56
- Name = "ButtonContainer";
57
- BackgroundTransparency = 1;
58
- Position = UDim2.new(0.5, 0, 0, 5);
59
- AnchorPoint = Vector2.new(0.5, 0);
60
- Size = UDim2.new(1, 0, 0, 30);
55
+ Name = "ButtonContainer",
56
+ BackgroundTransparency = 1,
57
+ Position = UDim2.new(0.5, 0, 0, 5),
58
+ AnchorPoint = Vector2.new(0.5, 0),
59
+ Size = UDim2.new(1, 0, 0, 30),
61
60
 
62
61
  Blend.New "UIListLayout" {
63
- FillDirection = Enum.FillDirection.Horizontal;
64
- Padding = UDim.new(0, 5);
65
- HorizontalAlignment = Enum.HorizontalAlignment.Center;
66
- };
62
+ FillDirection = Enum.FillDirection.Horizontal,
63
+ Padding = UDim.new(0, 5),
64
+ HorizontalAlignment = Enum.HorizontalAlignment.Center,
65
+ },
67
66
 
68
67
  button({
69
- Text = "Toggle";
68
+ Text = "Toggle",
70
69
  OnActivated = function()
71
70
  loopedSoundPlayer:Toggle()
72
- end;
73
- });
71
+ end,
72
+ }),
74
73
 
75
74
  button({
76
- Text = "Reset";
75
+ Text = "Reset",
77
76
  OnActivated = function()
78
77
  loopedSoundPlayer:Swap(ORIGINAL)
79
- end;
80
- });
78
+ end,
79
+ }),
81
80
 
82
81
  button({
83
- Text = "Swap sample";
82
+ Text = "Swap sample",
84
83
  OnActivated = function()
85
84
  loopedSoundPlayer:SwapToSamples({
86
- "rbxassetid://14478670277";
87
- "rbxassetid://14478671494";
88
- "rbxassetid://14478672676";
85
+ "rbxassetid://14478670277",
86
+ "rbxassetid://14478671494",
87
+ "rbxassetid://14478672676",
89
88
  })
90
- end;
91
- });
89
+ end,
90
+ }),
92
91
 
93
92
  button({
94
- Text = "Play once";
93
+ Text = "Play once",
95
94
  OnActivated = function()
96
95
  loopedSoundPlayer:PlayOnce("rbxassetid://14478764914")
97
- end;
98
- });
96
+ end,
97
+ }),
99
98
 
100
99
  button({
101
- Text = "Play delayed loop";
100
+ Text = "Play delayed loop",
102
101
  OnActivated = function()
103
- loopedSoundPlayer:Swap({
104
- SoundId ="rbxassetid://6052547865";
105
- Volume = 3;
106
- }, LoopedSoundScheduleUtils.schedule({
107
- loopDelay = NumberRange.new(0.25, 1);
108
- }))
109
- end;
110
- });
102
+ loopedSoundPlayer:Swap(
103
+ {
104
+ SoundId = "rbxassetid://6052547865",
105
+ Volume = 3,
106
+ },
107
+ LoopedSoundScheduleUtils.schedule({
108
+ loopDelay = NumberRange.new(0.25, 1),
109
+ })
110
+ )
111
+ end,
112
+ }),
111
113
 
112
114
  button({
113
- Text = "Swap on loop";
115
+ Text = "Swap on loop",
114
116
  OnActivated = function()
115
117
  loopedSoundPlayer:SwapOnLoop(RandomUtils.choice(OPTIONS))
116
- end;
117
- });
118
- }
118
+ end,
119
+ }),
120
+ },
119
121
  }))
120
122
 
121
123
  return function()
122
124
  maid:DoCleaning()
123
125
  end
124
- end
126
+ end
@@ -4,11 +4,11 @@
4
4
 
5
5
  local require = require(script.Parent.loader).load(script)
6
6
 
7
- local TimedTransitionModel = require("TimedTransitionModel")
7
+ local Promise = require("Promise")
8
8
  local Rx = require("Rx")
9
- local SoundUtils = require("SoundUtils")
10
9
  local SoundPromiseUtils = require("SoundPromiseUtils")
11
- local Promise = require("Promise")
10
+ local SoundUtils = require("SoundUtils")
11
+ local TimedTransitionModel = require("TimedTransitionModel")
12
12
  local ValueObject = require("ValueObject")
13
13
 
14
14
  local SimpleLoopedSoundPlayer = setmetatable({}, TimedTransitionModel)
@@ -29,10 +29,10 @@ function SimpleLoopedSoundPlayer.new(soundId)
29
29
  self._maxVolume = self.Sound.Volume
30
30
 
31
31
  self._maid:GiveTask(Rx.combineLatest({
32
- visible = self:ObserveRenderStepped();
33
- multiplier = self._volumeMultiplier:Observe();
32
+ visible = self:ObserveRenderStepped(),
33
+ multiplier = self._volumeMultiplier:Observe(),
34
34
  }):Subscribe(function(state)
35
- self.Sound.Volume = state.visible*self._maxVolume*state.multiplier
35
+ self.Sound.Volume = state.visible * self._maxVolume * state.multiplier
36
36
  end))
37
37
 
38
38
  self._maid:GiveTask(self.VisibleChanged:Connect(function(isVisible)
@@ -63,5 +63,4 @@ function SimpleLoopedSoundPlayer:PromiseLoopDone()
63
63
  return SoundPromiseUtils.promiseLooped(self.Sound)
64
64
  end
65
65
 
66
-
67
- return SimpleLoopedSoundPlayer
66
+ return SimpleLoopedSoundPlayer
@@ -2,11 +2,12 @@
2
2
  @class SimpleLoopedSoundPlayer.story
3
3
  ]]
4
4
 
5
- local require = require(game:GetService("ServerScriptService"):FindFirstChild("LoaderUtils", true).Parent).bootstrapStory(script)
5
+ local require =
6
+ require(game:GetService("ServerScriptService"):FindFirstChild("LoaderUtils", true).Parent).bootstrapStory(script)
6
7
 
8
+ local Blend = require("Blend")
7
9
  local Maid = require("Maid")
8
10
  local SimpleLoopedSoundPlayer = require("SimpleLoopedSoundPlayer")
9
- local Blend = require("Blend")
10
11
 
11
12
  return function(target)
12
13
  local maid = Maid.new()
@@ -20,45 +21,43 @@ return function(target)
20
21
 
21
22
  local function button(props)
22
23
  return Blend.New "TextButton" {
23
- Text = props.Text;
24
- AutoButtonColor = true;
25
- Font = Enum.Font.FredokaOne;
26
- Size = UDim2.new(0, 100, 0, 30);
27
-
28
- Blend.New "UICorner" {
24
+ Text = props.Text,
25
+ AutoButtonColor = true,
26
+ Font = Enum.Font.FredokaOne,
27
+ Size = UDim2.new(0, 100, 0, 30),
29
28
 
30
- };
29
+ Blend.New "UICorner" {},
31
30
 
32
31
  [Blend.OnEvent "Activated"] = function()
33
- props.OnActivated();
34
- end;
35
- };
32
+ props.OnActivated()
33
+ end,
34
+ }
36
35
  end
37
36
 
38
37
  maid:GiveTask(Blend.mount(target, {
39
38
  Blend.New "Frame" {
40
- Name = "ButtonContainer";
41
- BackgroundTransparency = 1;
42
- Position = UDim2.new(0.5, 0, 0, 5);
43
- AnchorPoint = Vector2.new(0.5, 0);
44
- Size = UDim2.new(1, 0, 0, 30);
39
+ Name = "ButtonContainer",
40
+ BackgroundTransparency = 1,
41
+ Position = UDim2.new(0.5, 0, 0, 5),
42
+ AnchorPoint = Vector2.new(0.5, 0),
43
+ Size = UDim2.new(1, 0, 0, 30),
45
44
 
46
45
  Blend.New "UIListLayout" {
47
- FillDirection = Enum.FillDirection.Horizontal;
48
- Padding = UDim.new(0, 5);
49
- HorizontalAlignment = Enum.HorizontalAlignment.Center;
50
- };
46
+ FillDirection = Enum.FillDirection.Horizontal,
47
+ Padding = UDim.new(0, 5),
48
+ HorizontalAlignment = Enum.HorizontalAlignment.Center,
49
+ },
51
50
 
52
51
  button({
53
- Text = "Toggle";
52
+ Text = "Toggle",
54
53
  OnActivated = function()
55
54
  simpleLoopedSoundPlayer:Toggle()
56
- end;
57
- });
58
- }
55
+ end,
56
+ }),
57
+ },
59
58
  }))
60
59
 
61
60
  return function()
62
61
  maid:DoCleaning()
63
62
  end
64
- end
63
+ end
@@ -4,52 +4,60 @@
4
4
 
5
5
  local require = require(script.Parent.loader).load(script)
6
6
 
7
- local t = require("t")
8
7
  local NumberRangeUtils = require("NumberRangeUtils")
9
8
  local Table = require("Table")
9
+ local t = require("t")
10
10
 
11
11
  local SoundLoopScheduleUtils = {}
12
12
 
13
- function SoundLoopScheduleUtils.schedule(loopedSchedule)
13
+ function SoundLoopScheduleUtils.schedule(loopedSchedule: SoundLoopSchedule): SoundLoopSchedule
14
14
  assert(SoundLoopScheduleUtils.isLoopedSchedule(loopedSchedule))
15
15
 
16
16
  return table.freeze(loopedSchedule)
17
17
  end
18
18
 
19
- function SoundLoopScheduleUtils.onNextLoop(loopedSchedule)
20
- assert(SoundLoopScheduleUtils.isLoopedSchedule(loopedSchedule) or loopedSchedule == nil, "Bad loopedSchedule")
19
+ function SoundLoopScheduleUtils.onNextLoop(loopedSchedule: SoundLoopSchedule): SoundLoopSchedule
20
+ assert(SoundLoopScheduleUtils.isLoopedSchedule(loopedSchedule) or loopedSchedule == nil, "Bad loopedSchedule")
21
21
 
22
22
  loopedSchedule = loopedSchedule or {}
23
23
  return SoundLoopScheduleUtils.schedule(Table.merge(loopedSchedule, {
24
- playOnNextLoop = true;
24
+ playOnNextLoop = true,
25
25
  }))
26
26
  end
27
27
 
28
- function SoundLoopScheduleUtils.maxLoops(maxLoops, loopedSchedule)
28
+ function SoundLoopScheduleUtils.maxLoops(maxLoops: number, loopedSchedule: SoundLoopSchedule): SoundLoopSchedule
29
29
  assert(type(maxLoops) == "number", "Bad maxLoops")
30
30
  assert(SoundLoopScheduleUtils.isLoopedSchedule(loopedSchedule) or loopedSchedule == nil, "Bad loopedSchedule")
31
31
 
32
32
  loopedSchedule = loopedSchedule or {}
33
33
  return SoundLoopScheduleUtils.schedule(Table.merge(loopedSchedule, {
34
- maxLoops = maxLoops;
34
+ maxLoops = maxLoops,
35
35
  }))
36
36
  end
37
37
 
38
- function SoundLoopScheduleUtils.default()
38
+ function SoundLoopScheduleUtils.default(): SoundLoopSchedule
39
39
  return SoundLoopScheduleUtils.schedule({})
40
40
  end
41
41
 
42
42
  SoundLoopScheduleUtils.isWaitTimeSeconds = t.union(t.number, t.NumberRange)
43
43
 
44
44
  SoundLoopScheduleUtils.isLoopedSchedule = t.interface({
45
- playOnNextLoop = t.optional(t.boolean);
46
- maxLoops = t.optional(t.number);
47
- initialDelay = t.optional(SoundLoopScheduleUtils.isWaitTimeSeconds);
48
- loopDelay = t.optional(SoundLoopScheduleUtils.isWaitTimeSeconds);
49
- maxInitialWaitTimeForNextLoop = t.optional(SoundLoopScheduleUtils.isWaitTimeSeconds);
45
+ playOnNextLoop = t.optional(t.boolean),
46
+ maxLoops = t.optional(t.number),
47
+ initialDelay = t.optional(SoundLoopScheduleUtils.isWaitTimeSeconds),
48
+ loopDelay = t.optional(SoundLoopScheduleUtils.isWaitTimeSeconds),
49
+ maxInitialWaitTimeForNextLoop = t.optional(SoundLoopScheduleUtils.isWaitTimeSeconds),
50
50
  })
51
51
 
52
- function SoundLoopScheduleUtils.getWaitTimeSeconds(waitTime)
52
+ export type SoundLoopSchedule = {
53
+ playOnNextLoop: boolean?,
54
+ maxLoops: number?,
55
+ initialDelay: number | NumberRange?,
56
+ loopDelay: number | NumberRange?,
57
+ maxInitialWaitTimeForNextLoop: number | NumberRange?,
58
+ }
59
+
60
+ function SoundLoopScheduleUtils.getWaitTimeSeconds(waitTime: number | NumberRange): number
53
61
  assert(SoundLoopScheduleUtils.isWaitTimeSeconds(waitTime))
54
62
 
55
63
  if type(waitTime) == "number" then
@@ -61,4 +69,4 @@ function SoundLoopScheduleUtils.getWaitTimeSeconds(waitTime)
61
69
  end
62
70
  end
63
71
 
64
- return SoundLoopScheduleUtils
72
+ return SoundLoopScheduleUtils