Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Packages/com.unity.inputsystem/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ however, it has to be formatted properly to pass verification tests.
### Fixed
- An issue where a UITK MouseEvent was triggered when changing from Scene View to Game View in the Editor has been fixed. [ISXB-1671](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1671)
- Fix documentation error in file AndroidGameController.cs mentioning a wrong controller. [DOCATT-9806]

- Deferred auto-registration of processors, interactions and composite binding types referenced by `InputActionAsset`
to only happen once when an unresolved type reference is found in an action definition. This avoids reflective
type loading from assemblies for all cases where the Input System is not extended. (ISXB-1766).

## [1.16.0] - 2025-11-10

Expand Down
31 changes: 23 additions & 8 deletions Packages/com.unity.inputsystem/InputSystem/InputManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1913,9 +1913,9 @@
internal void InitializeData()
{
m_Layouts.Allocate();
m_Processors.Initialize();
m_Interactions.Initialize();
m_Composites.Initialize();
m_Processors.Initialize(this);
m_Interactions.Initialize(this);
m_Composites.Initialize(this);
m_DevicesById = new Dictionary<int, InputDevice>();

// Determine our default set of enabled update types. By
Expand Down Expand Up @@ -2026,11 +2026,11 @@
composites.AddTypeRegistration("OneModifier", typeof(OneModifierComposite));
composites.AddTypeRegistration("TwoModifiers", typeof(TwoModifiersComposite));

// Register custom types by reflection
RegisterCustomTypes();
// ISXB-1766: Defer loading custom types by reflection unless we have to since referenced from
// .inputaction JSON assets. This is managed via TypeTable.cs.
}

void RegisterCustomTypes(Type[] types)
static void RegisterCustomTypes(Type[] types)
{
foreach (Type type in types)
{
Expand All @@ -2053,8 +2053,18 @@
}
}

void RegisterCustomTypes()
private bool m_CustomTypesRegistered;

internal bool RegisterCustomTypes()
{
// If we have already attempted to register custom types, there is no need to reattempt since we
// would end up with the same result again. Only with a domain reload would the resulting types
// be different, and hence it is sufficient to use a static flag that we do not reset.
if (m_CustomTypesRegistered)
return false; // Already evaluated

m_CustomTypesRegistered = true;

Check warning on line 2066 in Packages/com.unity.inputsystem/InputSystem/InputManager.cs

View check run for this annotation

Codecov GitHub.com / codecov/patch

Packages/com.unity.inputsystem/InputSystem/InputManager.cs#L2066

Added line #L2066 was not covered by tests

k_InputRegisterCustomTypesMarker.Begin();

var inputSystemAssembly = typeof(InputProcessor).Assembly;
Expand All @@ -2079,11 +2089,13 @@
}
catch (ReflectionTypeLoadException)
{
continue;
// Ignore exception
}
}

k_InputRegisterCustomTypesMarker.End();

return true; // Signal that custom types were extracted and registered.
}

internal void InstallRuntime(IInputRuntime runtime)
Expand Down Expand Up @@ -2164,6 +2176,9 @@
InputControlLayout.s_CacheInstance = default;
InputControlLayout.s_CacheInstanceRef = 0;

// Invalidate type registrations
m_CustomTypesRegistered = false;

// Detach from runtime.
if (m_Runtime != null)
{
Expand Down
28 changes: 23 additions & 5 deletions Packages/com.unity.inputsystem/InputSystem/Utilities/TypeTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,16 @@ internal struct TypeTable
public HashSet<InternedString> aliases;
#endif

public void Initialize()
// Strong coupling to Input Manager which is always the owner
private InputManager m_Manager;

public void Initialize(InputManager manager)
{
table = new Dictionary<InternedString, Type>();
#if UNITY_EDITOR
aliases = new HashSet<InternedString>();
#endif
m_Manager = manager;
}

public InternedString FindNameForType(Type type)
Expand Down Expand Up @@ -80,10 +84,24 @@ public Type LookupTypeRegistration(string name)
if (table == null)
throw new InvalidOperationException("Input System not yet initialized");

var internedName = new InternedString(name);
if (table.TryGetValue(internedName, out var type))
return type;
return null;
return TryLookupTypeRegistration(new InternedString(name));
}

private Type TryLookupTypeRegistration(InternedString internedName)
{
if (!table.TryGetValue(internedName, out var type))
{
// Failed to look-up type, either type do not exist or it is a custom type that has not been registered.
// Check whether we have attempted to load custom types and otherwise lazily load types only when
// relevant and reattempt looking up type by name. (ISXB-1766)
if (m_Manager != null)
{
if (m_Manager.RegisterCustomTypes())
table.TryGetValue(internedName, out type);
}
}

return type;
}

#if UNITY_EDITOR
Expand Down