@quenty/inputkeymaputils 5.3.1 → 6.0.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 +8 -0
- package/package.json +12 -9
- package/src/Client/InputKeyMapListUtils.lua +108 -0
- package/src/Client/InputKeyMapServiceClient.lua +37 -39
- package/src/Client/InputKeyMapTranslator.lua +7 -0
- package/src/Server/InputKeyMapService.lua +18 -0
- package/src/{Client → Shared}/InputKeyMap.lua +17 -7
- package/src/{Client → Shared}/InputKeyMapList.lua +74 -94
- package/src/{Client → Shared}/InputKeyMapListProvider.lua +52 -29
- package/src/Shared/InputKeyMapRegistryServiceShared.lua +112 -0
- package/src/{Client → Shared}/ProximityPromptInputUtils.lua +14 -10
- package/src/{Client → Shared}/Types/InputTypeUtils.lua +21 -1
- package/src/{Client → Shared}/Types/SlottedTouchButtonUtils.lua +10 -6
- package/test/modules/Shared/TestInputKeyMap.lua +31 -0
- package/test/scripts/Client/ClientMain.client.lua +2 -2
- package/test/scripts/Server/ServerMain.server.lua +10 -1
- package/test/modules/Client/TestInputKeyMap.lua +0 -25
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
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
|
+
# [6.0.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/inputkeymaputils@5.3.1...@quenty/inputkeymaputils@6.0.0) (2022-08-14)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @quenty/inputkeymaputils
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
6
14
|
## [5.3.1](https://github.com/Quenty/NevermoreEngine/compare/@quenty/inputkeymaputils@5.3.0...@quenty/inputkeymaputils@5.3.1) (2022-08-11)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @quenty/inputkeymaputils
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/inputkeymaputils",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0",
|
|
4
4
|
"description": "Utility methods for input map",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -27,20 +27,23 @@
|
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@quenty/baseobject": "^5.1.0",
|
|
30
|
-
"@quenty/brio": "^
|
|
31
|
-
"@quenty/
|
|
30
|
+
"@quenty/brio": "^7.0.0",
|
|
31
|
+
"@quenty/clienttranslator": "^7.0.0",
|
|
32
|
+
"@quenty/inputmode": "^6.0.0",
|
|
32
33
|
"@quenty/loader": "^5.0.0",
|
|
33
34
|
"@quenty/maid": "^2.4.0",
|
|
34
|
-
"@quenty/observablecollection": "^
|
|
35
|
-
"@quenty/
|
|
35
|
+
"@quenty/observablecollection": "^4.0.0",
|
|
36
|
+
"@quenty/pseudolocalize": "^3.0.0",
|
|
37
|
+
"@quenty/rx": "^6.0.0",
|
|
36
38
|
"@quenty/servicebag": "^5.1.0",
|
|
37
|
-
"@quenty/statestack": "^
|
|
39
|
+
"@quenty/statestack": "^7.0.0",
|
|
40
|
+
"@quenty/string": "^3.0.0",
|
|
38
41
|
"@quenty/table": "^3.1.0",
|
|
39
|
-
"@quenty/valuebaseutils": "^
|
|
40
|
-
"@quenty/valueobject": "^
|
|
42
|
+
"@quenty/valuebaseutils": "^6.0.0",
|
|
43
|
+
"@quenty/valueobject": "^6.0.0"
|
|
41
44
|
},
|
|
42
45
|
"publishConfig": {
|
|
43
46
|
"access": "public"
|
|
44
47
|
},
|
|
45
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "dbb62609f980983cc32da90acfef13e30ed41113"
|
|
46
49
|
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
--[=[
|
|
2
|
+
Client side utility helpers for observing input modes for the current client.
|
|
3
|
+
|
|
4
|
+
@class InputKeyMapListUtils
|
|
5
|
+
]=]
|
|
6
|
+
|
|
7
|
+
local require = require(script.Parent.loader).load(script)
|
|
8
|
+
|
|
9
|
+
local InputKeyMapList = require("InputKeyMapList")
|
|
10
|
+
local InputModeTypeSelector = require("InputModeTypeSelector")
|
|
11
|
+
local Maid = require("Maid")
|
|
12
|
+
local Observable = require("Observable")
|
|
13
|
+
local Rx = require("Rx")
|
|
14
|
+
local ServiceBag = require("ServiceBag")
|
|
15
|
+
|
|
16
|
+
local InputKeyMapListUtils = {}
|
|
17
|
+
|
|
18
|
+
--[=[
|
|
19
|
+
Observes the input enums list
|
|
20
|
+
|
|
21
|
+
@param inputKeyMapList InputKeyMapList
|
|
22
|
+
@param serviceBag ServiceBag
|
|
23
|
+
@return InputModeTypeSelector
|
|
24
|
+
]=]
|
|
25
|
+
function InputKeyMapListUtils.getNewInputModeTypeSelector(inputKeyMapList, serviceBag)
|
|
26
|
+
assert(InputKeyMapList.isInputKeyMapList(inputKeyMapList), "Bad inputKeyMapList")
|
|
27
|
+
assert(ServiceBag.isServiceBag(serviceBag), "Bad serviceBag")
|
|
28
|
+
|
|
29
|
+
return InputModeTypeSelector.fromObservableBrio(serviceBag, inputKeyMapList:ObserveInputModesTypesBrio())
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
--[=[
|
|
33
|
+
Observes the input types for the active input map
|
|
34
|
+
|
|
35
|
+
@param inputKeyMapList InputKeyMapList
|
|
36
|
+
@param serviceBag ServiceBag
|
|
37
|
+
@return Observable<InputKeyMap>
|
|
38
|
+
]=]
|
|
39
|
+
function InputKeyMapListUtils.observeActiveInputKeyMap(inputKeyMapList, serviceBag)
|
|
40
|
+
assert(InputKeyMapList.isInputKeyMapList(inputKeyMapList), "Bad inputKeyMapList")
|
|
41
|
+
assert(ServiceBag.isServiceBag(serviceBag), "Bad serviceBag")
|
|
42
|
+
|
|
43
|
+
return InputKeyMapListUtils.observeActiveInputModeType(inputKeyMapList, serviceBag):Pipe({
|
|
44
|
+
Rx.switchMap(function(activeInputModeType)
|
|
45
|
+
if activeInputModeType then
|
|
46
|
+
return inputKeyMapList:ObserveInputKeyMapForInputMode(activeInputModeType)
|
|
47
|
+
else
|
|
48
|
+
return Rx.of(nil)
|
|
49
|
+
end
|
|
50
|
+
end);
|
|
51
|
+
})
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
--[=[
|
|
55
|
+
Observes the input types for the active input map.
|
|
56
|
+
|
|
57
|
+
:::warning
|
|
58
|
+
This should be used for hinting inputs, but it's preferred to
|
|
59
|
+
bind inputs for all modes. See [InputKeyMapList.ObserveInputEnumsList]
|
|
60
|
+
:::
|
|
61
|
+
|
|
62
|
+
@param inputKeyMapList InputKeyMapList
|
|
63
|
+
@param serviceBag ServiceBag
|
|
64
|
+
@return Observable<{ InputType }?>
|
|
65
|
+
]=]
|
|
66
|
+
function InputKeyMapListUtils.observeActiveInputTypesList(inputKeyMapList, serviceBag)
|
|
67
|
+
assert(InputKeyMapList.isInputKeyMapList(inputKeyMapList), "Bad inputKeyMapList")
|
|
68
|
+
assert(ServiceBag.isServiceBag(serviceBag), "Bad serviceBag")
|
|
69
|
+
|
|
70
|
+
return InputKeyMapListUtils.observeActiveInputKeyMap(inputKeyMapList, serviceBag):Pipe({
|
|
71
|
+
Rx.switchMap(function(activeInputMap)
|
|
72
|
+
if activeInputMap then
|
|
73
|
+
return activeInputMap:ObserveInputTypesList()
|
|
74
|
+
else
|
|
75
|
+
return Rx.of(nil)
|
|
76
|
+
end
|
|
77
|
+
end);
|
|
78
|
+
Rx.distinct();
|
|
79
|
+
})
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
--[=[
|
|
83
|
+
Observes the active input mode currently selected.
|
|
84
|
+
|
|
85
|
+
@param inputKeyMapList InputKeyMapList
|
|
86
|
+
@param serviceBag ServiceBag
|
|
87
|
+
@return Observable<InputModeType?>
|
|
88
|
+
]=]
|
|
89
|
+
function InputKeyMapListUtils.observeActiveInputModeType(inputKeyMapList, serviceBag)
|
|
90
|
+
assert(InputKeyMapList.isInputKeyMapList(inputKeyMapList), "Bad inputKeyMapList")
|
|
91
|
+
assert(ServiceBag.isServiceBag(serviceBag), "Bad serviceBag")
|
|
92
|
+
|
|
93
|
+
return Observable.new(function(sub)
|
|
94
|
+
local maid = Maid.new()
|
|
95
|
+
|
|
96
|
+
local selector = InputKeyMapListUtils.getNewInputModeTypeSelector(inputKeyMapList, serviceBag)
|
|
97
|
+
maid:GiveTask(selector)
|
|
98
|
+
|
|
99
|
+
maid:GiveTask(selector.Changed:Connect(function()
|
|
100
|
+
sub:Fire(selector.Value)
|
|
101
|
+
end))
|
|
102
|
+
sub:Fire(selector.Value)
|
|
103
|
+
|
|
104
|
+
return maid
|
|
105
|
+
end)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
return InputKeyMapListUtils
|
|
@@ -1,64 +1,62 @@
|
|
|
1
1
|
--[=[
|
|
2
|
-
Not required to be initialized
|
|
3
2
|
@class InputKeyMapServiceClient
|
|
4
3
|
]=]
|
|
5
4
|
|
|
6
|
-
local
|
|
5
|
+
local require = require(script.Parent.loader).load(script)
|
|
6
|
+
|
|
7
|
+
local Maid = require("Maid")
|
|
8
|
+
local PseudoLocalize = require("PseudoLocalize")
|
|
7
9
|
|
|
8
10
|
local InputKeyMapServiceClient = {}
|
|
11
|
+
InputKeyMapServiceClient.ServiceName = "InputKeyMapServiceClient"
|
|
9
12
|
|
|
10
13
|
function InputKeyMapServiceClient:Init(serviceBag)
|
|
11
14
|
assert(not self._serviceBag, "Already initialized")
|
|
12
15
|
self._serviceBag = assert(serviceBag, "No serviceBag")
|
|
16
|
+
self._maid = Maid.new()
|
|
13
17
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
function InputKeyMapServiceClient:RegisterProvider(provider)
|
|
18
|
-
assert(provider, "Bad provider")
|
|
19
|
-
assert(self._providers, "Not initialized")
|
|
18
|
+
-- External
|
|
19
|
+
self._serviceBag:GetService(require("InputModeServiceClient"))
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
self._providers[providerName] = provider
|
|
21
|
+
-- Internal
|
|
22
|
+
self._translator = self._serviceBag:GetService(require("InputKeyMapTranslator"))
|
|
23
|
+
self._registryService = self._serviceBag:GetService(require("InputKeyMapRegistryServiceShared"))
|
|
27
24
|
end
|
|
28
25
|
|
|
29
|
-
function InputKeyMapServiceClient:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
return self._providers[providerName]
|
|
26
|
+
function InputKeyMapServiceClient:FindInputKeyMapList(providerName, listName)
|
|
27
|
+
return self._registryService:FindInputKeyMapList(providerName, listName)
|
|
33
28
|
end
|
|
34
29
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
30
|
+
function InputKeyMapServiceClient:Start()
|
|
31
|
+
self:_ensureLocalizationEntries()
|
|
32
|
+
end
|
|
38
33
|
|
|
39
|
-
|
|
34
|
+
function InputKeyMapServiceClient:_ensureLocalizationEntries()
|
|
35
|
+
self._maid:GiveTask(self._registryService:ObserveInputKeyMapListsBrio():Subscribe(function(brio)
|
|
36
|
+
if brio:IsDead() then
|
|
37
|
+
return
|
|
38
|
+
end
|
|
40
39
|
|
|
41
|
-
|
|
42
|
-
assert(type(providerName) == "string", "Bad providerName")
|
|
43
|
-
assert(type(inputKeyMapListName) == "string", "Bad inputKeyMapListName")
|
|
40
|
+
local inputKeyMapList = brio:GetValue()
|
|
44
41
|
|
|
45
|
-
|
|
46
|
-
return nil
|
|
47
|
-
end
|
|
42
|
+
local text = inputKeyMapList:GetBindingName()
|
|
48
43
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
|
44
|
+
local localizationTable = self._translator:GetLocalizationTable()
|
|
45
|
+
local key = inputKeyMapList:GetBindingTranslationKey()
|
|
46
|
+
local source = text
|
|
47
|
+
local context = ("InputKeyMapServiceClient.%s"):format(inputKeyMapList:GetListName())
|
|
48
|
+
local localeId = "en"
|
|
49
|
+
local value = text
|
|
58
50
|
|
|
59
|
-
|
|
51
|
+
localizationTable:SetEntryValue(key, source, context, localeId, value)
|
|
52
|
+
localizationTable:SetEntryValue(key, source, context,
|
|
53
|
+
PseudoLocalize.getDefaultPseudoLocaleId(),
|
|
54
|
+
PseudoLocalize.pseudoLocalize(value))
|
|
55
|
+
end))
|
|
60
56
|
end
|
|
61
57
|
|
|
62
|
-
|
|
58
|
+
function InputKeyMapServiceClient:Destroy()
|
|
59
|
+
self._maid:DoCleaning()
|
|
60
|
+
end
|
|
63
61
|
|
|
64
62
|
return InputKeyMapServiceClient
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
--[=[
|
|
2
|
+
@class InputKeyMapService
|
|
3
|
+
]=]
|
|
4
|
+
|
|
5
|
+
local require = require(script.Parent.loader).load(script)
|
|
6
|
+
|
|
7
|
+
local InputKeyMapService = {}
|
|
8
|
+
InputKeyMapService.ServiceName = "InputKeyMapService"
|
|
9
|
+
|
|
10
|
+
function InputKeyMapService:Init(serviceBag)
|
|
11
|
+
assert(not self._serviceBag, "Already initialized")
|
|
12
|
+
self._serviceBag = assert(serviceBag, "No serviceBag")
|
|
13
|
+
|
|
14
|
+
-- Internal
|
|
15
|
+
self._serviceBag:GetService(require("InputKeyMapRegistryServiceShared"))
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
return InputKeyMapService
|
|
@@ -11,21 +11,23 @@ local require = require(script.Parent.loader).load(script)
|
|
|
11
11
|
|
|
12
12
|
local BaseObject = require("BaseObject")
|
|
13
13
|
local ValueObject = require("ValueObject")
|
|
14
|
-
local
|
|
14
|
+
local InputModeType = require("InputModeType")
|
|
15
15
|
|
|
16
16
|
local InputKeyMap = setmetatable({}, BaseObject)
|
|
17
17
|
InputKeyMap.ClassName = "InputKeyMap"
|
|
18
18
|
InputKeyMap.__index = InputKeyMap
|
|
19
19
|
|
|
20
|
-
function InputKeyMap.new(
|
|
21
|
-
assert(
|
|
20
|
+
function InputKeyMap.new(inputModeType, inputTypes)
|
|
21
|
+
assert(InputModeType.isInputModeType(inputModeType), "Bad inputModeType")
|
|
22
22
|
assert(type(inputTypes) == "table" or inputTypes == nil, "Bad inputTypes")
|
|
23
23
|
|
|
24
24
|
local self = setmetatable(BaseObject.new(), InputKeyMap)
|
|
25
25
|
|
|
26
|
-
self.
|
|
26
|
+
self._inputModeType = assert(inputModeType, "No inputModeType")
|
|
27
27
|
|
|
28
|
-
self.
|
|
28
|
+
self._defaultInputTypes = inputTypes or {}
|
|
29
|
+
|
|
30
|
+
self._inputType = ValueObject.new(self._defaultInputTypes)
|
|
29
31
|
self._maid:GiveTask(self._inputType)
|
|
30
32
|
|
|
31
33
|
return self
|
|
@@ -34,8 +36,8 @@ end
|
|
|
34
36
|
--[=[
|
|
35
37
|
Gets the input mode for this keymap. This will not change.
|
|
36
38
|
]=]
|
|
37
|
-
function InputKeyMap:
|
|
38
|
-
return self.
|
|
39
|
+
function InputKeyMap:GetInputModeType()
|
|
40
|
+
return self._inputModeType
|
|
39
41
|
end
|
|
40
42
|
|
|
41
43
|
function InputKeyMap:SetInputTypesList(inputTypes)
|
|
@@ -44,6 +46,14 @@ function InputKeyMap:SetInputTypesList(inputTypes)
|
|
|
44
46
|
self._inputType.Value = inputTypes
|
|
45
47
|
end
|
|
46
48
|
|
|
49
|
+
function InputKeyMap:GetDefaultInputTypesList()
|
|
50
|
+
return self._defaultInputTypes
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
function InputKeyMap:RestoreDefault()
|
|
54
|
+
self._inputType.Value = self._defaultInputTypes
|
|
55
|
+
end
|
|
56
|
+
|
|
47
57
|
function InputKeyMap:ObserveInputTypesList()
|
|
48
58
|
return self._inputType:Observe()
|
|
49
59
|
end
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
```lua
|
|
10
10
|
local inputKeyMapList = InputKeyMapList.new("BOOST", {
|
|
11
|
-
InputKeyMap.new(
|
|
12
|
-
InputKeyMap.new(
|
|
13
|
-
InputKeyMap.new(
|
|
11
|
+
InputKeyMap.new(InputModeTypes.KeyboardAndMouse, { Enum.KeyCode.LeftControl });
|
|
12
|
+
InputKeyMap.new(InputModeTypes.Gamepads, { Enum.KeyCode.ButtonX });
|
|
13
|
+
InputKeyMap.new(InputModeTypes.Touch, { SlottedTouchButtonUtils.createSlottedTouchButton("primary1") });
|
|
14
14
|
})
|
|
15
15
|
|
|
16
16
|
maid:GiveTask(Rx.combineLatest({
|
|
@@ -40,20 +40,19 @@
|
|
|
40
40
|
|
|
41
41
|
local require = require(script.Parent.loader).load(script)
|
|
42
42
|
|
|
43
|
-
local InputKeyMap = require("InputKeyMap")
|
|
44
|
-
local ObservableMap = require("ObservableMap")
|
|
45
43
|
local BaseObject = require("BaseObject")
|
|
46
|
-
local
|
|
47
|
-
local
|
|
44
|
+
local Brio = require("Brio")
|
|
45
|
+
local InputKeyMap = require("InputKeyMap")
|
|
46
|
+
local InputModeType = require("InputModeType")
|
|
47
|
+
local InputTypeUtils = require("InputTypeUtils")
|
|
48
48
|
local Maid = require("Maid")
|
|
49
|
-
local Rx = require("Rx")
|
|
50
49
|
local ObservableCountingMap = require("ObservableCountingMap")
|
|
51
|
-
local
|
|
52
|
-
local
|
|
50
|
+
local ObservableMap = require("ObservableMap")
|
|
51
|
+
local Rx = require("Rx")
|
|
53
52
|
local RxBrioUtils = require("RxBrioUtils")
|
|
54
|
-
local
|
|
53
|
+
local SlottedTouchButtonUtils = require("SlottedTouchButtonUtils")
|
|
55
54
|
local StateStack = require("StateStack")
|
|
56
|
-
local
|
|
55
|
+
local String = require("String")
|
|
57
56
|
|
|
58
57
|
local InputKeyMapList = setmetatable({}, BaseObject)
|
|
59
58
|
InputKeyMapList.ClassName = "InputKeyMapList"
|
|
@@ -64,15 +63,17 @@ InputKeyMapList.__index = InputKeyMapList
|
|
|
64
63
|
|
|
65
64
|
@param inputMapName string
|
|
66
65
|
@param inputKeyMapList { InputKeyMap }
|
|
66
|
+
@param options { bindingName: string, rebindable: boolean } -- configuration options
|
|
67
67
|
@return InputKeyMapList
|
|
68
68
|
]=]
|
|
69
|
-
function InputKeyMapList.new(inputMapName, inputKeyMapList)
|
|
69
|
+
function InputKeyMapList.new(inputMapName, inputKeyMapList, options)
|
|
70
70
|
local self = setmetatable(BaseObject.new(), InputKeyMapList)
|
|
71
71
|
|
|
72
72
|
self._inputKeyMapListName = assert(inputMapName, "No inputMapName")
|
|
73
|
+
self._options = assert(options, "No options")
|
|
73
74
|
|
|
74
|
-
self.
|
|
75
|
-
self._maid:GiveTask(self.
|
|
75
|
+
self._inputModeTypeToInputKeyMap = ObservableMap.new()
|
|
76
|
+
self._maid:GiveTask(self._inputModeTypeToInputKeyMap)
|
|
76
77
|
|
|
77
78
|
for _, inputKeyMap in pairs(inputKeyMapList) do
|
|
78
79
|
self:Add(inputKeyMap)
|
|
@@ -91,6 +92,26 @@ function InputKeyMapList.isInputKeyMapList(value)
|
|
|
91
92
|
return type(value) == "table" and getmetatable(value) == InputKeyMapList
|
|
92
93
|
end
|
|
93
94
|
|
|
95
|
+
--[=[
|
|
96
|
+
Returns user bindable time
|
|
97
|
+
@return boolean
|
|
98
|
+
]=]
|
|
99
|
+
function InputKeyMapList:IsUserRebindable()
|
|
100
|
+
return self._options.rebindable == true
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
--[=[
|
|
104
|
+
Gets the english name
|
|
105
|
+
@return string
|
|
106
|
+
]=]
|
|
107
|
+
function InputKeyMapList:GetBindingName()
|
|
108
|
+
return self._options.bindingName
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
function InputKeyMapList:GetBindingTranslationKey()
|
|
112
|
+
return "keybinds." .. String.toCamelCase(self._inputKeyMapListName)
|
|
113
|
+
end
|
|
114
|
+
|
|
94
115
|
--[=[
|
|
95
116
|
Adds an input key map into the actual list
|
|
96
117
|
@param inputKeyMap InputKeyMap
|
|
@@ -98,8 +119,8 @@ end
|
|
|
98
119
|
function InputKeyMapList:Add(inputKeyMap)
|
|
99
120
|
assert(inputKeyMap, "Bad inputKeyMap")
|
|
100
121
|
|
|
101
|
-
self._maid[inputKeyMap:
|
|
102
|
-
self.
|
|
122
|
+
self._maid[inputKeyMap:GetInputModeType()] = inputKeyMap
|
|
123
|
+
self._inputModeTypeToInputKeyMap:Set(inputKeyMap:GetInputModeType(), inputKeyMap)
|
|
103
124
|
end
|
|
104
125
|
|
|
105
126
|
--[=[
|
|
@@ -110,17 +131,17 @@ function InputKeyMapList:GetListName()
|
|
|
110
131
|
return self._inputKeyMapListName
|
|
111
132
|
end
|
|
112
133
|
|
|
113
|
-
function InputKeyMapList:SetInputTypesList(
|
|
114
|
-
assert(
|
|
134
|
+
function InputKeyMapList:SetInputTypesList(inputModeType, inputTypes)
|
|
135
|
+
assert(InputModeType.isInputModeType(inputModeType), "Bad inputModeType")
|
|
115
136
|
assert(type(inputTypes) == "table" or inputTypes == nil, "Bad inputTypes")
|
|
116
137
|
|
|
117
138
|
if inputTypes == nil then
|
|
118
|
-
self.
|
|
119
|
-
self._maid[
|
|
139
|
+
self._inputModeTypeToInputKeyMap:Remove(inputModeType)
|
|
140
|
+
self._maid[inputModeType] = nil
|
|
120
141
|
else
|
|
121
|
-
local inputKeyMap = self.
|
|
142
|
+
local inputKeyMap = self._inputModeTypeToInputKeyMap:Get(inputModeType)
|
|
122
143
|
if not inputKeyMap then
|
|
123
|
-
self:Add(InputKeyMap.new(
|
|
144
|
+
self:Add(InputKeyMap.new(inputModeType, inputTypes))
|
|
124
145
|
else
|
|
125
146
|
inputKeyMap:SetInputTypesList(inputTypes)
|
|
126
147
|
end
|
|
@@ -128,98 +149,57 @@ function InputKeyMapList:SetInputTypesList(inputMode, inputTypes)
|
|
|
128
149
|
end
|
|
129
150
|
|
|
130
151
|
--[=[
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
@param inputMode InputMode
|
|
152
|
+
Observes a brio with the first value as the InputModeType and the second value as the KeyMapList
|
|
153
|
+
@return Observable<Brio<InputModeType, InputKeyMap>>
|
|
134
154
|
]=]
|
|
135
|
-
function InputKeyMapList:
|
|
136
|
-
|
|
155
|
+
function InputKeyMapList:ObservePairsBrio()
|
|
156
|
+
return self._inputModeTypeToInputKeyMap:ObservePairsBrio()
|
|
157
|
+
end
|
|
137
158
|
|
|
138
|
-
|
|
159
|
+
--[=[
|
|
160
|
+
Restores the default value for all lists
|
|
161
|
+
]=]
|
|
162
|
+
function InputKeyMapList:RestoreDefault()
|
|
163
|
+
for _, item in pairs(self._inputModeTypeToInputKeyMap:GetValueList()) do
|
|
164
|
+
item:RestoreDefault()
|
|
165
|
+
end
|
|
139
166
|
end
|
|
140
167
|
|
|
141
168
|
--[=[
|
|
142
|
-
|
|
169
|
+
Removes the entry for the inputmodeType
|
|
143
170
|
|
|
144
|
-
@
|
|
171
|
+
@param inputModeType InputModeType
|
|
145
172
|
]=]
|
|
146
|
-
function InputKeyMapList:
|
|
147
|
-
|
|
173
|
+
function InputKeyMapList:RemoveInputModeType(inputModeType)
|
|
174
|
+
assert(InputModeType.isInputModeType(inputModeType), "Bad inputModeType")
|
|
175
|
+
|
|
176
|
+
self:SetInputTypesList(inputModeType, nil)
|
|
148
177
|
end
|
|
149
178
|
|
|
150
179
|
--[=[
|
|
151
180
|
@return Observable<Brio<InputKeyMap>>
|
|
152
181
|
]=]
|
|
153
182
|
function InputKeyMapList:ObserveInputKeyMapsBrio()
|
|
154
|
-
return self.
|
|
183
|
+
return self._inputModeTypeToInputKeyMap:ObserveValuesBrio()
|
|
155
184
|
end
|
|
156
185
|
|
|
157
186
|
--[=[
|
|
158
|
-
@return Observable<Brio<
|
|
187
|
+
@return Observable<Brio<InputModeType>>
|
|
159
188
|
]=]
|
|
160
|
-
function InputKeyMapList:
|
|
161
|
-
return self.
|
|
189
|
+
function InputKeyMapList:ObserveInputModesTypesBrio()
|
|
190
|
+
return self._inputModeTypeToInputKeyMap:ObserveKeysBrio()
|
|
162
191
|
end
|
|
163
192
|
|
|
164
193
|
--[=[
|
|
165
194
|
Observes the input types for the active input map
|
|
166
195
|
|
|
196
|
+
@param inputModeType InputModeType
|
|
167
197
|
@return Observable<InputKeyMap>
|
|
168
198
|
]=]
|
|
169
|
-
function InputKeyMapList:
|
|
170
|
-
|
|
171
|
-
Rx.switchMap(function(activeInputMode)
|
|
172
|
-
if activeInputMode then
|
|
173
|
-
return self._inputModeToInputKeyMap:ObserveValueForKey(activeInputMode)
|
|
174
|
-
else
|
|
175
|
-
return Rx.of(nil)
|
|
176
|
-
end
|
|
177
|
-
end);
|
|
178
|
-
})
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
--[=[
|
|
182
|
-
Observes the input types for the active input map.
|
|
183
|
-
|
|
184
|
-
:::warning
|
|
185
|
-
This should be used for hinting inputs, but it's preferred to
|
|
186
|
-
bind inputs for all modes. See [InputKeyMapList.ObserveInputEnumsList]
|
|
187
|
-
:::
|
|
188
|
-
|
|
189
|
-
@return Observable<{ InputType }?>
|
|
190
|
-
]=]
|
|
191
|
-
function InputKeyMapList:ObserveActiveInputTypesList()
|
|
192
|
-
return self:ObserveActiveInputKeyMap():Pipe({
|
|
193
|
-
Rx.switchMap(function(activeInputMap)
|
|
194
|
-
if activeInputMap then
|
|
195
|
-
return activeInputMap:ObserveInputTypesList()
|
|
196
|
-
else
|
|
197
|
-
return Rx.of(nil)
|
|
198
|
-
end
|
|
199
|
-
end);
|
|
200
|
-
Rx.distinct();
|
|
201
|
-
})
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
--[=[
|
|
205
|
-
Observes the active input mode currently selected.
|
|
206
|
-
|
|
207
|
-
@return Observable<InputMode?>
|
|
208
|
-
]=]
|
|
209
|
-
function InputKeyMapList:ObserveActiveInputMode()
|
|
210
|
-
return Observable.new(function(sub)
|
|
211
|
-
local maid = Maid.new()
|
|
212
|
-
|
|
213
|
-
local selector = self:GetNewInputModeSelector()
|
|
214
|
-
maid:GiveTask(selector)
|
|
215
|
-
|
|
216
|
-
maid:GiveTask(selector.Changed:Connect(function()
|
|
217
|
-
sub:Fire(selector.Value)
|
|
218
|
-
end))
|
|
219
|
-
sub:Fire(selector.Value)
|
|
199
|
+
function InputKeyMapList:ObserveInputKeyMapForInputMode(inputModeType)
|
|
200
|
+
assert(InputModeType.isInputModeType(inputModeType), "Bad inputModeType")
|
|
220
201
|
|
|
221
|
-
|
|
222
|
-
end)
|
|
202
|
+
return self._inputModeTypeToInputKeyMap:ObserveValueForKey(inputModeType)
|
|
223
203
|
end
|
|
224
204
|
|
|
225
205
|
--[=[
|
|
@@ -294,14 +274,14 @@ end
|
|
|
294
274
|
@return Observable<SlottedTouchButton>
|
|
295
275
|
]=]
|
|
296
276
|
function InputKeyMapList:ObserveSlottedTouchButtonDataBrio()
|
|
297
|
-
return self.
|
|
298
|
-
RxBrioUtils.flatMapBrio(function(
|
|
277
|
+
return self._inputModeTypeToInputKeyMap:ObservePairsBrio():Pipe({
|
|
278
|
+
RxBrioUtils.flatMapBrio(function(inputModeType, inputKeyMap)
|
|
299
279
|
return inputKeyMap:ObserveInputTypesList():Pipe({
|
|
300
280
|
Rx.switchMap(function(inputTypesList)
|
|
301
281
|
local valid = {}
|
|
302
282
|
for _, inputType in pairs(inputTypesList) do
|
|
303
283
|
if SlottedTouchButtonUtils.isSlottedTouchButton(inputType) then
|
|
304
|
-
local data = SlottedTouchButtonUtils.createTouchButtonData(inputType.slotId,
|
|
284
|
+
local data = SlottedTouchButtonUtils.createTouchButtonData(inputType.slotId, inputModeType)
|
|
305
285
|
table.insert(valid, Brio.new(data))
|
|
306
286
|
end
|
|
307
287
|
end
|
|
@@ -332,7 +312,7 @@ function InputKeyMapList:_ensureInit()
|
|
|
332
312
|
self._maid:GiveTask(self._isRobloxTouchButton)
|
|
333
313
|
|
|
334
314
|
-- Listen
|
|
335
|
-
self._maid:GiveTask(self.
|
|
315
|
+
self._maid:GiveTask(self._inputModeTypeToInputKeyMap:ObserveValuesBrio():Subscribe(function(brio)
|
|
336
316
|
if brio:IsDead() then
|
|
337
317
|
return
|
|
338
318
|
end
|
|
@@ -6,19 +6,28 @@
|
|
|
6
6
|
```lua
|
|
7
7
|
local inputMapProvider = InputKeyMapListProvider.new("General", function(self)
|
|
8
8
|
self:Add(InputKeyMapList.new("JUMP", {
|
|
9
|
-
InputKeyMap.new(
|
|
10
|
-
InputKeyMap.new(
|
|
11
|
-
InputKeyMap.new(
|
|
9
|
+
InputKeyMap.new(InputModeTypes.KeyboardAndMouse, { Enum.KeyCode.Space });
|
|
10
|
+
InputKeyMap.new(InputModeTypes.Gamepads, { Enum.KeyCode.ButtonA });
|
|
11
|
+
InputKeyMap.new(InputModeTypes.Touch, { SlottedTouchButtonUtils.createSlottedTouchButton("primary3") });
|
|
12
|
+
}, {
|
|
13
|
+
bindingName = "Jump";
|
|
14
|
+
rebindable = true;
|
|
12
15
|
}))
|
|
13
16
|
self:Add(InputKeyMapList.new("HONK", {
|
|
14
|
-
InputKeyMap.new(
|
|
15
|
-
InputKeyMap.new(
|
|
16
|
-
InputKeyMap.new(
|
|
17
|
+
InputKeyMap.new(InputModeTypes.KeyboardAndMouse, { Enum.KeyCode.H });
|
|
18
|
+
InputKeyMap.new(InputModeTypes.Gamepads, { Enum.KeyCode.DPadUp });
|
|
19
|
+
InputKeyMap.new(InputModeTypes.Touch, { SlottedTouchButtonUtils.createSlottedTouchButton("primary2") });
|
|
20
|
+
}, {
|
|
21
|
+
bindingName = "Honk";
|
|
22
|
+
rebindable = true;
|
|
17
23
|
}))
|
|
18
24
|
self:Add(InputKeyMapList.new("BOOST", {
|
|
19
|
-
InputKeyMap.new(
|
|
20
|
-
InputKeyMap.new(
|
|
21
|
-
InputKeyMap.new(
|
|
25
|
+
InputKeyMap.new(InputModeTypes.KeyboardAndMouse, { Enum.KeyCode.LeftControl });
|
|
26
|
+
InputKeyMap.new(InputModeTypes.Gamepads, { Enum.KeyCode.ButtonX });
|
|
27
|
+
InputKeyMap.new(InputModeTypes.Touch, { SlottedTouchButtonUtils.createSlottedTouchButton("primary4") });
|
|
28
|
+
}, {
|
|
29
|
+
bindingName = "Boost";
|
|
30
|
+
rebindable = true;
|
|
22
31
|
}))
|
|
23
32
|
end)
|
|
24
33
|
|
|
@@ -36,10 +45,12 @@ local require = require(script.Parent.loader).load(script)
|
|
|
36
45
|
local RunService = game:GetService("RunService")
|
|
37
46
|
|
|
38
47
|
local Maid = require("Maid")
|
|
39
|
-
local
|
|
48
|
+
local InputKeyMapRegistryServiceShared = require("InputKeyMapRegistryServiceShared")
|
|
49
|
+
local ObservableList = require("ObservableList")
|
|
40
50
|
|
|
41
51
|
local InputKeyMapListProvider = {}
|
|
42
52
|
InputKeyMapListProvider.ClassName = "InputKeyMapListProvider"
|
|
53
|
+
InputKeyMapListProvider.ServiceName = "InputKeyMapListProvider"
|
|
43
54
|
InputKeyMapListProvider.__index = InputKeyMapListProvider
|
|
44
55
|
|
|
45
56
|
--[=[
|
|
@@ -55,11 +66,30 @@ function InputKeyMapListProvider.new(providerName, createDefaults)
|
|
|
55
66
|
local self = setmetatable({}, InputKeyMapListProvider)
|
|
56
67
|
|
|
57
68
|
self._providerName = assert(providerName, "No providerName")
|
|
69
|
+
self.ServiceName = providerName
|
|
58
70
|
self._createDefaults = assert(createDefaults, "No createDefaults")
|
|
59
71
|
|
|
60
72
|
return self
|
|
61
73
|
end
|
|
62
74
|
|
|
75
|
+
function InputKeyMapListProvider:Init(serviceBag)
|
|
76
|
+
assert(not self._serviceBag, "Already initialized")
|
|
77
|
+
|
|
78
|
+
self._serviceBag = assert(serviceBag, "No serviceBag")
|
|
79
|
+
self._maid = Maid.new()
|
|
80
|
+
|
|
81
|
+
self._inputMapLists = ObservableList.new()
|
|
82
|
+
self._maid:GiveTask(self._inputMapLists)
|
|
83
|
+
|
|
84
|
+
self._maid:GiveTask(self._serviceBag:GetService(InputKeyMapRegistryServiceShared):RegisterProvider(self))
|
|
85
|
+
|
|
86
|
+
self:_ensureDefaultsInit()
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
function InputKeyMapListProvider:Start()
|
|
90
|
+
-- empty function
|
|
91
|
+
end
|
|
92
|
+
|
|
63
93
|
--[=[
|
|
64
94
|
Gets this providers name
|
|
65
95
|
@return string
|
|
@@ -92,16 +122,17 @@ end
|
|
|
92
122
|
function InputKeyMapListProvider:FindInputKeyMapList(keyMapListName)
|
|
93
123
|
assert(type(keyMapListName) == "string", "Bad keyMapListName")
|
|
94
124
|
|
|
125
|
+
if RunService:IsRunning() and not self._inputKeyMapLists then
|
|
126
|
+
error("Not initialized, make sure to retrieve via serviceBag and init")
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
-- Test mode initialize
|
|
95
130
|
if not self._inputKeyMapLists then
|
|
96
|
-
|
|
97
|
-
-- Test mode initialize
|
|
98
|
-
self._maid = Maid.new()
|
|
99
|
-
self:_ensureDefaultsInit()
|
|
100
|
-
else
|
|
101
|
-
error("Not initialized, make sure to retrieve via serviceBag and init")
|
|
102
|
-
end
|
|
131
|
+
self._maid = Maid.new()
|
|
103
132
|
end
|
|
104
133
|
|
|
134
|
+
self:_ensureDefaultsInit()
|
|
135
|
+
|
|
105
136
|
return self._inputKeyMapLists[keyMapListName]
|
|
106
137
|
end
|
|
107
138
|
|
|
@@ -115,16 +146,12 @@ function InputKeyMapListProvider:Add(inputKeyMapList)
|
|
|
115
146
|
|
|
116
147
|
self._inputKeyMapLists[inputKeyMapList:GetListName()] = inputKeyMapList
|
|
117
148
|
self._maid:GiveTask(inputKeyMapList)
|
|
118
|
-
end
|
|
119
149
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
self._serviceBag = assert(serviceBag, "No serviceBag")
|
|
124
|
-
self._serviceBag:GetService(InputKeyMapServiceClient):RegisterProvider(self)
|
|
125
|
-
self._maid = Maid.new()
|
|
150
|
+
self._maid:GiveTask(self._inputMapLists:Add(inputKeyMapList))
|
|
151
|
+
end
|
|
126
152
|
|
|
127
|
-
|
|
153
|
+
function InputKeyMapListProvider:ObserveInputKeyMapListsBrio()
|
|
154
|
+
return self._inputMapLists:ObserveItemsBrio()
|
|
128
155
|
end
|
|
129
156
|
|
|
130
157
|
function InputKeyMapListProvider:_ensureDefaultsInit()
|
|
@@ -135,10 +162,6 @@ function InputKeyMapListProvider:_ensureDefaultsInit()
|
|
|
135
162
|
end
|
|
136
163
|
end
|
|
137
164
|
|
|
138
|
-
function InputKeyMapListProvider:Start()
|
|
139
|
-
-- empty function
|
|
140
|
-
end
|
|
141
|
-
|
|
142
165
|
function InputKeyMapListProvider:Destroy()
|
|
143
166
|
if self._maid then
|
|
144
167
|
self._maid:DoCleaning()
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
--[=[
|
|
2
|
+
Provides retrieval of input key maps across the game. Available on both the client and the server.
|
|
3
|
+
|
|
4
|
+
Input key maps are needed on the server to bind datastore settings.
|
|
5
|
+
|
|
6
|
+
@class InputKeyMapRegistryServiceShared
|
|
7
|
+
]=]
|
|
8
|
+
|
|
9
|
+
local RunService = game:GetService("RunService")
|
|
10
|
+
|
|
11
|
+
local require = require(script.Parent.loader).load(script)
|
|
12
|
+
|
|
13
|
+
local Maid = require("Maid")
|
|
14
|
+
local ObservableList = require("ObservableList")
|
|
15
|
+
local RxBrioUtils = require("RxBrioUtils")
|
|
16
|
+
|
|
17
|
+
local InputKeyMapRegistryServiceShared = {}
|
|
18
|
+
InputKeyMapRegistryServiceShared.ServiceName = "InputKeyMapRegistryServiceShared"
|
|
19
|
+
|
|
20
|
+
function InputKeyMapRegistryServiceShared:Init(serviceBag)
|
|
21
|
+
assert(not self._serviceBag, "Already initialized")
|
|
22
|
+
self._serviceBag = assert(serviceBag, "No serviceBag")
|
|
23
|
+
self._maid = Maid.new()
|
|
24
|
+
|
|
25
|
+
self._providerLookupByName = {}
|
|
26
|
+
|
|
27
|
+
self._providersList = ObservableList.new()
|
|
28
|
+
self._maid:GiveTask(self._providersList)
|
|
29
|
+
|
|
30
|
+
self._maid:GiveTask(self._providersList:ObserveItemsBrio():Subscribe(function(brio)
|
|
31
|
+
if brio:IsDead() then
|
|
32
|
+
return
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
local maid = brio:ToMaid()
|
|
36
|
+
local provider = brio:GetValue()
|
|
37
|
+
|
|
38
|
+
local providerName = provider:GetProviderName()
|
|
39
|
+
|
|
40
|
+
if self._providerLookupByName[providerName] then
|
|
41
|
+
error(("Already have a provider with name %q"):format(providerName))
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
self._providerLookupByName[providerName] = provider
|
|
45
|
+
|
|
46
|
+
maid:GiveTask(function()
|
|
47
|
+
if self._providerLookupByName[providerName] == provider then
|
|
48
|
+
self._providerLookupByName[providerName] = nil
|
|
49
|
+
end
|
|
50
|
+
end)
|
|
51
|
+
end))
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
function InputKeyMapRegistryServiceShared:RegisterProvider(provider)
|
|
55
|
+
assert(provider, "Bad provider")
|
|
56
|
+
assert(self._providersList, "Not initialized")
|
|
57
|
+
|
|
58
|
+
return self._providersList:Add(provider)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
function InputKeyMapRegistryServiceShared:ObserveProvidersBrio()
|
|
62
|
+
return self._providersList:ObserveItemsBrio()
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
function InputKeyMapRegistryServiceShared:ObserveInputKeyMapListsBrio()
|
|
66
|
+
return self:ObserveProvidersBrio():Pipe({
|
|
67
|
+
RxBrioUtils.flatMapBrio(function(provider)
|
|
68
|
+
return provider:ObserveInputKeyMapListsBrio()
|
|
69
|
+
end)
|
|
70
|
+
})
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
function InputKeyMapRegistryServiceShared:GetProvider(providerName)
|
|
74
|
+
assert(type(providerName) == "string", "Bad providerName")
|
|
75
|
+
|
|
76
|
+
return self._providerLookupByName[providerName]
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
-- function InputKeyMapRegistryServiceShared:ObserveInputKeyMapList(providerName, inputKeyMapListName)
|
|
80
|
+
-- assert(type(providerName) == "string", "Bad providerName")
|
|
81
|
+
-- assert(type(inputKeyMapListName) == "string", "Bad inputKeyMapListName")
|
|
82
|
+
|
|
83
|
+
-- end
|
|
84
|
+
|
|
85
|
+
function InputKeyMapRegistryServiceShared:FindInputKeyMapList(providerName, inputKeyMapListName)
|
|
86
|
+
assert(type(providerName) == "string", "Bad providerName")
|
|
87
|
+
assert(type(inputKeyMapListName) == "string", "Bad inputKeyMapListName")
|
|
88
|
+
|
|
89
|
+
if not RunService:IsRunning() then
|
|
90
|
+
return nil
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
assert(self._providersList, "Not initialized")
|
|
94
|
+
|
|
95
|
+
for _, provider in pairs(self._providerLookupByName) do
|
|
96
|
+
if provider:GetProviderName() == providerName then
|
|
97
|
+
local found = provider:FindInputKeyMapList(inputKeyMapListName)
|
|
98
|
+
if found then
|
|
99
|
+
return found
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
return nil
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
function InputKeyMapRegistryServiceShared:Destroy()
|
|
108
|
+
self._maid:DoCleaning()
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
return InputKeyMapRegistryServiceShared
|
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
local require = require(script.Parent.loader).load(script)
|
|
8
8
|
|
|
9
9
|
local InputKeyMapList = require("InputKeyMapList")
|
|
10
|
-
local
|
|
10
|
+
local InputModeTypes = require("InputModeTypes")
|
|
11
11
|
local InputKeyMap = require("InputKeyMap")
|
|
12
|
+
local InputModeType = require("InputModeType")
|
|
12
13
|
|
|
13
14
|
local ProximityPromptInputUtils = {}
|
|
14
15
|
|
|
@@ -22,8 +23,11 @@ function ProximityPromptInputUtils.newInputKeyMapFromPrompt(prompt)
|
|
|
22
23
|
assert(typeof(prompt) == "Instance", "Bad prompt")
|
|
23
24
|
|
|
24
25
|
return InputKeyMapList.new("custom", {
|
|
25
|
-
InputKeyMap.new(
|
|
26
|
-
InputKeyMap.new(
|
|
26
|
+
InputKeyMap.new(InputModeTypes.Gamepads, { prompt.GamepadKeyCode });
|
|
27
|
+
InputKeyMap.new(InputModeTypes.Keyboard, { prompt.KeyboardKeyCode })
|
|
28
|
+
}, {
|
|
29
|
+
bindingName = prompt.ActionText;
|
|
30
|
+
rebindable = false;
|
|
27
31
|
})
|
|
28
32
|
end
|
|
29
33
|
|
|
@@ -38,8 +42,8 @@ function ProximityPromptInputUtils.configurePromptFromInputKeyMap(prompt, inputK
|
|
|
38
42
|
assert(typeof(prompt) == "Instance", "Bad prompt")
|
|
39
43
|
assert(type(inputKeyMapList) == "table", "Bad inputKeyMapList")
|
|
40
44
|
|
|
41
|
-
local keyboard = ProximityPromptInputUtils.getFirstInputKeyCode(inputKeyMapList,
|
|
42
|
-
local gamepad = ProximityPromptInputUtils.getFirstInputKeyCode(inputKeyMapList,
|
|
45
|
+
local keyboard = ProximityPromptInputUtils.getFirstInputKeyCode(inputKeyMapList, InputModeTypes.Keyboard)
|
|
46
|
+
local gamepad = ProximityPromptInputUtils.getFirstInputKeyCode(inputKeyMapList, InputModeTypes.Gamepads)
|
|
43
47
|
|
|
44
48
|
if keyboard then
|
|
45
49
|
prompt.KeyboardKeyCode = keyboard
|
|
@@ -51,21 +55,21 @@ function ProximityPromptInputUtils.configurePromptFromInputKeyMap(prompt, inputK
|
|
|
51
55
|
end
|
|
52
56
|
|
|
53
57
|
--[=[
|
|
54
|
-
Picks the first keyCode that matches the
|
|
58
|
+
Picks the first keyCode that matches the inputModeType.
|
|
55
59
|
|
|
56
60
|
@param inputKeyMapList InputKeyMapList
|
|
57
|
-
@param
|
|
61
|
+
@param inputModeType InputModeType
|
|
58
62
|
@return KeyCode?
|
|
59
63
|
]=]
|
|
60
|
-
function ProximityPromptInputUtils.getFirstInputKeyCode(inputKeyMapList,
|
|
64
|
+
function ProximityPromptInputUtils.getFirstInputKeyCode(inputKeyMapList, inputModeType)
|
|
61
65
|
assert(type(inputKeyMapList) == "table", "Bad inputKeyMapList")
|
|
62
|
-
assert(
|
|
66
|
+
assert(InputModeType.isInputModeType(inputModeType), "Bad inputModeType")
|
|
63
67
|
|
|
64
68
|
for _, item in pairs(inputKeyMapList) do
|
|
65
69
|
for _, entry in pairs(item.inputTypes) do
|
|
66
70
|
if typeof(entry) == "EnumItem"
|
|
67
71
|
and entry.EnumType == Enum.KeyCode
|
|
68
|
-
and
|
|
72
|
+
and inputModeType:IsValid(entry) then
|
|
69
73
|
|
|
70
74
|
return entry
|
|
71
75
|
end
|
|
@@ -10,10 +10,20 @@ local InputTypeUtils = {}
|
|
|
10
10
|
|
|
11
11
|
--[=[
|
|
12
12
|
A valid input type that can be represented here.
|
|
13
|
-
@type InputType KeyCode | UserInputType | SlottedTouchButton | "TouchButton" | "Tap" | any
|
|
13
|
+
@type InputType KeyCode | UserInputType | SlottedTouchButton | "TouchButton" | "Tap" | "Drag" | any
|
|
14
14
|
@within InputTypeUtils
|
|
15
15
|
]=]
|
|
16
16
|
|
|
17
|
+
function InputTypeUtils.isKnownInputType(inputType)
|
|
18
|
+
return InputTypeUtils.isTapInWorld(inputType)
|
|
19
|
+
or InputTypeUtils.isRobloxTouchButton(inputType)
|
|
20
|
+
or InputTypeUtils.isDrag(inputType)
|
|
21
|
+
or SlottedTouchButtonUtils.isSlottedTouchButton(inputType)
|
|
22
|
+
or (typeof(inputType) == "EnumItem" and (
|
|
23
|
+
tostring(inputType.EnumType) == "UserInputType"
|
|
24
|
+
or tostring(inputType.EnumType) == "KeyCode"))
|
|
25
|
+
end
|
|
26
|
+
|
|
17
27
|
--[=[
|
|
18
28
|
Returns true if the input type is specifying a tap in the world
|
|
19
29
|
@param inputKey any
|
|
@@ -23,6 +33,16 @@ function InputTypeUtils.isTapInWorld(inputKey)
|
|
|
23
33
|
return inputKey == "Tap"
|
|
24
34
|
end
|
|
25
35
|
|
|
36
|
+
|
|
37
|
+
--[=[
|
|
38
|
+
Returns true if the input type is specifying a drag
|
|
39
|
+
@param inputKey any
|
|
40
|
+
@return boolean
|
|
41
|
+
]=]
|
|
42
|
+
function InputTypeUtils.isDrag(inputKey)
|
|
43
|
+
return inputKey == "Drag"
|
|
44
|
+
end
|
|
45
|
+
|
|
26
46
|
--[=[
|
|
27
47
|
Returns true if the input type is specifying a Roblox touch button
|
|
28
48
|
@param inputKey any
|
|
@@ -2,13 +2,17 @@
|
|
|
2
2
|
@class SlottedTouchButtonUtils
|
|
3
3
|
]=]
|
|
4
4
|
|
|
5
|
+
local require = require(script.Parent.loader).load(script)
|
|
6
|
+
|
|
7
|
+
local InputModeType = require("InputModeType")
|
|
8
|
+
|
|
5
9
|
local SlottedTouchButtonUtils = {}
|
|
6
10
|
|
|
7
11
|
--[=[
|
|
8
12
|
Internal data representing a slotted touch button
|
|
9
13
|
@interface SlottedTouchButtonData
|
|
10
14
|
.slotId string
|
|
11
|
-
.
|
|
15
|
+
.inputModeType InputModeType
|
|
12
16
|
@within SlottedTouchButtonUtils
|
|
13
17
|
]=]
|
|
14
18
|
|
|
@@ -58,13 +62,13 @@ end
|
|
|
58
62
|
Gets slotted touch button data for an inputKeyMapList
|
|
59
63
|
|
|
60
64
|
@param slotId string
|
|
61
|
-
@param
|
|
65
|
+
@param inputModeType InputModeType
|
|
62
66
|
@return SlottedTouchButtonData
|
|
63
67
|
]=]
|
|
64
|
-
function SlottedTouchButtonUtils.createTouchButtonData(slotId,
|
|
68
|
+
function SlottedTouchButtonUtils.createTouchButtonData(slotId, inputModeType)
|
|
65
69
|
return {
|
|
66
70
|
slotId = slotId;
|
|
67
|
-
|
|
71
|
+
inputModeType = inputModeType;
|
|
68
72
|
}
|
|
69
73
|
end
|
|
70
74
|
|
|
@@ -78,13 +82,13 @@ function SlottedTouchButtonUtils.getSlottedTouchButtonData(inputKeyMapList)
|
|
|
78
82
|
local slottedTouchButtons = {}
|
|
79
83
|
|
|
80
84
|
for _, inputKeyMap in pairs(inputKeyMapList) do
|
|
81
|
-
assert(inputKeyMap.
|
|
85
|
+
assert(InputModeType.isInputModeType(inputKeyMap.inputModeType), "Bad inputKeyMap.inputModeType")
|
|
82
86
|
assert(inputKeyMap.inputTypes, "Bad inputKeyMap.inputTypes")
|
|
83
87
|
|
|
84
88
|
for _, touchButtonData in pairs(inputKeyMap.inputTypes) do
|
|
85
89
|
if SlottedTouchButtonUtils.isSlottedTouchButton(touchButtonData) then
|
|
86
90
|
table.insert(slottedTouchButtons, SlottedTouchButtonUtils.createTouchButtonData(
|
|
87
|
-
touchButtonData.slotId, inputKeyMap.
|
|
91
|
+
touchButtonData.slotId, inputKeyMap.inputModeType))
|
|
88
92
|
end
|
|
89
93
|
end
|
|
90
94
|
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
--[=[
|
|
2
|
+
Test input key map provider
|
|
3
|
+
@class TestInputKeyMap
|
|
4
|
+
]=]
|
|
5
|
+
local require = require(script.Parent.loader).load(script)
|
|
6
|
+
|
|
7
|
+
local InputModeTypes = require("InputModeTypes")
|
|
8
|
+
local InputKeyMap = require("InputKeyMap")
|
|
9
|
+
local InputKeyMapList = require("InputKeyMapList")
|
|
10
|
+
local InputKeyMapListProvider = require("InputKeyMapListProvider")
|
|
11
|
+
local SlottedTouchButtonUtils = require("SlottedTouchButtonUtils")
|
|
12
|
+
|
|
13
|
+
return InputKeyMapListProvider.new(script.Name, function(self)
|
|
14
|
+
self:Add(InputKeyMapList.new("JUMP", {
|
|
15
|
+
InputKeyMap.new(InputModeTypes.KeyboardAndMouse, { Enum.KeyCode.Q });
|
|
16
|
+
InputKeyMap.new(InputModeTypes.Gamepads, { Enum.KeyCode.ButtonY });
|
|
17
|
+
InputKeyMap.new(InputModeTypes.Touch, { SlottedTouchButtonUtils.createSlottedTouchButton("primary3") });
|
|
18
|
+
}, {
|
|
19
|
+
bindingName = "Jump";
|
|
20
|
+
rebindable = true;
|
|
21
|
+
}))
|
|
22
|
+
|
|
23
|
+
self:Add(InputKeyMapList.new("HONK", {
|
|
24
|
+
InputKeyMap.new(InputModeTypes.KeyboardAndMouse, { Enum.KeyCode.H });
|
|
25
|
+
InputKeyMap.new(InputModeTypes.Gamepads, { Enum.KeyCode.ButtonL1 });
|
|
26
|
+
InputKeyMap.new(InputModeTypes.Touch, { SlottedTouchButtonUtils.createSlottedTouchButton("primary2") });
|
|
27
|
+
}, {
|
|
28
|
+
bindingName = "Honk";
|
|
29
|
+
rebindable = true;
|
|
30
|
+
}))
|
|
31
|
+
end)
|
|
@@ -5,7 +5,7 @@ local packages = game:GetService("ReplicatedStorage"):WaitForChild("Packages")
|
|
|
5
5
|
|
|
6
6
|
local ContextActionService = game:GetService("ContextActionService")
|
|
7
7
|
|
|
8
|
-
local
|
|
8
|
+
local InputModeTypes = require(packages.InputModeTypes)
|
|
9
9
|
local serviceBag = require(packages.ServiceBag).new()
|
|
10
10
|
|
|
11
11
|
serviceBag:GetService(packages.InputKeyMapServiceClient)
|
|
@@ -25,4 +25,4 @@ keyMapList:ObserveInputEnumsList():Subscribe(function(...)
|
|
|
25
25
|
end)
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
keyMapList:SetForInputMode(
|
|
28
|
+
keyMapList:SetForInputMode(InputModeTypes.Keypad, { Enum.KeyCode.Space })
|
|
@@ -4,4 +4,13 @@
|
|
|
4
4
|
local ServerScriptService = game:GetService("ServerScriptService")
|
|
5
5
|
|
|
6
6
|
local loader = ServerScriptService:FindFirstChild("LoaderUtils", true).Parent
|
|
7
|
-
require(loader).bootstrapGame(ServerScriptService.inputkeymaputils)
|
|
7
|
+
local packages = require(loader).bootstrapGame(ServerScriptService.inputkeymaputils)
|
|
8
|
+
|
|
9
|
+
local serviceBag = require(packages.ServiceBag).new()
|
|
10
|
+
|
|
11
|
+
serviceBag:GetService(packages.TestInputKeyMap)
|
|
12
|
+
|
|
13
|
+
-- Start game
|
|
14
|
+
serviceBag:Init()
|
|
15
|
+
serviceBag:Start()
|
|
16
|
+
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
--[=[
|
|
2
|
-
Test input key map provider
|
|
3
|
-
@class TestInputKeyMap
|
|
4
|
-
]=]
|
|
5
|
-
local require = require(script.Parent.loader).load(script)
|
|
6
|
-
|
|
7
|
-
local INPUT_MODES = require("INPUT_MODES")
|
|
8
|
-
local InputKeyMap = require("InputKeyMap")
|
|
9
|
-
local InputKeyMapList = require("InputKeyMapList")
|
|
10
|
-
local InputKeyMapListProvider = require("InputKeyMapListProvider")
|
|
11
|
-
local SlottedTouchButtonUtils = require("SlottedTouchButtonUtils")
|
|
12
|
-
|
|
13
|
-
return InputKeyMapListProvider.new(script.Name, function(self)
|
|
14
|
-
self:Add(InputKeyMapList.new("JUMP", {
|
|
15
|
-
InputKeyMap.new(INPUT_MODES.KeyboardAndMouse, { Enum.KeyCode.Q });
|
|
16
|
-
InputKeyMap.new(INPUT_MODES.Gamepads, { Enum.KeyCode.ButtonY });
|
|
17
|
-
InputKeyMap.new(INPUT_MODES.Touch, { SlottedTouchButtonUtils.createSlottedTouchButton("primary3") });
|
|
18
|
-
}))
|
|
19
|
-
|
|
20
|
-
self:Add(InputKeyMapList.new("HONK", {
|
|
21
|
-
InputKeyMap.new(INPUT_MODES.KeyboardAndMouse, { Enum.KeyCode.H });
|
|
22
|
-
InputKeyMap.new(INPUT_MODES.Gamepads, { Enum.KeyCode.ButtonL1 });
|
|
23
|
-
InputKeyMap.new(INPUT_MODES.Touch, { SlottedTouchButtonUtils.createSlottedTouchButton("primary2") });
|
|
24
|
-
}))
|
|
25
|
-
end)
|