Files
RebootKit/Runtime/Engine/Code/Input/InputService.cs

177 lines
4.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using RebootKit.Engine.Foundation;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.InputSystem;
using UnityEngine.Profiling;
using Logger = RebootKit.Engine.Foundation.Logger;
namespace RebootKit.Engine.Input {
public class InputState : IDisposable {
static readonly Logger s_Logger = new Logger(nameof(InputState));
public string Name { get; private set; }
bool m_IsActive;
public bool IsActive {
get {
return m_IsActive;
}
set {
m_IsActive = value;
Service?.UpdateUnityInputState();
}
}
int m_Priority;
public int Priority {
get {
return m_Priority;
}
set {
m_Priority = value;
Service?.UpdateUnityInputState();
}
}
bool m_HideCursor;
public bool HideCursor {
get {
return m_HideCursor;
}
set {
m_HideCursor = value;
Service?.UpdateUnityInputState();
}
}
bool m_LockCursor;
public bool LockCursor {
get {
return m_LockCursor;
}
set {
m_LockCursor = value;
Service?.UpdateUnityInputState();
}
}
internal List<string> ActiveMaps = new List<string>(4);
internal InputService Service;
internal InputState(string name, InputService service) {
IsActive = true;
Name = name;
Service = service;
}
public void Dispose() {
Service.UnregisterInputState(this);
Service = null;
}
public void AddActiveMap(string mapName) {
if (ActiveMaps.Contains(mapName)) {
s_Logger.Warning($"Action Map '{mapName}' is already active in InputState '{Name}'");
return;
}
ActiveMaps.Add(mapName);
Service.UpdateUnityInputState();
}
public void RemoveActiveMap(string mapName) {
ActiveMaps.Remove(mapName);
Service.UpdateUnityInputState();
}
public bool IsMapActive(string mapName) {
return ActiveMaps.Contains(mapName);
}
}
public class InputService : IService {
static readonly Logger s_Logger = new Logger(nameof(InputService));
readonly Config m_Config;
InputActionAsset m_InputActionAsset;
readonly List<InputState> m_States = new List<InputState>(16);
public InputService(Config config) {
m_Config = config;
m_InputActionAsset = config.inputActionAsset;
}
public void Dispose() {
m_InputActionAsset = null;
}
public InputState NewInputState(string name) {
Assert.IsNull(m_States.FirstOrDefault(t => t.Name.Equals(name, StringComparison.Ordinal)),
$"State with name '{name}' already exists in the input service.");
var inputState = new InputState(name, this);
m_States.Add(inputState);
return inputState;
}
internal void UnregisterInputState(InputState state) {
m_States.Remove(state);
}
internal void UpdateUnityInputState() {
Profiler.BeginSample("Find Active State");
InputState activeState = m_States.Where(t => t.IsActive)
.OrderByDescending(t => t.Priority)
.FirstOrDefault();
Profiler.EndSample();
if (activeState == null) {
s_Logger.Warning("No Active input state found");
return;
}
Cursor.visible = !activeState.HideCursor;
Cursor.lockState = activeState.LockCursor ? CursorLockMode.Locked : CursorLockMode.None;
foreach (InputActionMap inputActionMap in m_InputActionAsset.actionMaps) {
if (activeState.IsMapActive(inputActionMap.name)) {
inputActionMap.Enable();
} else {
inputActionMap.Disable();
}
}
}
public void EnableControls() {
if (m_InputActionAsset == null) {
return;
}
m_InputActionAsset.Enable();
}
public void DisableControls() {
if (m_InputActionAsset == null) {
return;
}
m_InputActionAsset.Disable();
}
[Serializable]
public class Config {
public InputActionAsset inputActionAsset;
}
}
}