Skip to content
Merged
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
74 changes: 58 additions & 16 deletions DynamicVariablePowerTools/ContextMenu/DVMA.References.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,40 @@
using FrooxEngine;
using HarmonyLib;
using MonkeyLoader.Resonite;

using System.Reflection;
using GenerationEvent = MonkeyLoader.Resonite.UI.Inspectors.InspectorMemberActionsMenuItemsGenerationEvent;

namespace DynamicVariablePowerTools.ContextMenu
{
internal sealed partial class DynamicVariableMemberActions
{
private static ButtonEventHandler GetDriveSyncRefFromVariable<T>(GenerationEvent eventData, SyncRef<T> syncRefTarget, string variable)
private static readonly MethodInfo _getDriveSyncRefWithCastFromVariableMethod = AccessTools.Method(typeof(DynamicVariableMemberActions), nameof(GetDriveSyncRefWithCastFromVariable));

private static ButtonEventHandler GetDriveSyncRefFromVariable<T>(GenerationEvent eventData, SyncRef<T> syncRefTarget, string variable, Type? variableType = null)
where T : class, IWorldElement
{
if (variableType is null || variableType == syncRefTarget.TargetType)
{
return (button, args) =>
{
syncRefTarget.DriveFromVariable(variable);
eventData.CloseContextMenu();
};
}

var getMethod = _getDriveSyncRefWithCastFromVariableMethod.MakeGenericMethod(syncRefTarget.TargetType, variableType);
return (ButtonEventHandler)getMethod.Invoke(null, [eventData, syncRefTarget, variable])!;
}

private static ButtonEventHandler GetDriveSyncRefWithCastFromVariable<TTarget, TVariable>(GenerationEvent eventData, SyncRef<TTarget> syncRefTarget, string variable)
where TTarget : class, IWorldElement
where TVariable : class, IWorldElement
=> (button, args) =>
{
syncRefTarget.DriveFromVariable(variable);
var cast = syncRefTarget.Slot.AttachComponent<ReferenceCast<TVariable, TTarget>>();
cast.Target.Target = syncRefTarget;
cast.Source.DriveFromVariable(variable);

eventData.CloseContextMenu();
};

Expand All @@ -28,13 +51,32 @@ private static ButtonEventHandler GetOfferSyncRefDriveActions<T>(GenerationEvent

var blankVariableName = string.IsNullOrWhiteSpace(space.CurrentName) ? string.Empty : $"{space.CurrentName}/";

eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive.FromVariable", "variable", GetDisplayName(space, "")), DriveIcon, DriveColor)
eventData.ContextMenu.AddItem(Instance.GetLocaleString("Drive.FromVariable", "variable", GetDisplayName(space, "")), DriveIcon, DriveColor)
.Button.LocalPressed += GetDriveSyncRefFromVariable(eventData, syncRefTarget, blankVariableName);

foreach (var variable in space.GetVariableIdentities<T>().RemoveSharedConfigVariables())
foreach (var variable in space.GetVariableIdentities().WithoutSharedConfigVariables())
{
eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive.FromVariable", "variable", GetDisplayName(variable)), DriveIcon, DriveColor)
.Button.LocalPressed += GetDriveSyncRefFromVariable(eventData, syncRefTarget, variable.QualifiedName);
var couldDowncast = variable.Type.IsAssignableTo(syncRefTarget.TargetType);
var couldUpcast = syncRefTarget.TargetType.IsAssignableTo(variable.Type);

// Variable and target are completely incompatible
if (!couldDowncast && !couldUpcast)
continue;

// Variable and target are not the same but (potentially) compatible
if (couldDowncast ^ couldUpcast)
{
// Variable is more derived than target
if (!ConfigSection.AllowDowncastToDrive && couldDowncast)
continue;

// Variable is less derived than target
if (!ConfigSection.AllowUpcastToDrive && couldUpcast)
continue;
}

eventData.ContextMenu.AddItem(Instance.GetLocaleString("Drive.FromVariable", "variable", GetDisplayName(variable)), DriveIcon, DriveColor)
.Button.LocalPressed += GetDriveSyncRefFromVariable(eventData, syncRefTarget, variable.QualifiedName, variable.Type);
}
});
};
Expand All @@ -50,14 +92,14 @@ private static ButtonEventHandler GetOfferSyncRefDriveSpaceActions<T>(Generation
if (await eventData.OpenContextMenuAsync(args.source.Slot) is null)
return;

eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive.FromBlank"), DriveIcon, DriveColor)
eventData.ContextMenu.AddItem(Instance.GetLocaleString("Drive.FromBlank"), DriveIcon, DriveColor)
.Button.LocalPressed += GetDriveSyncRefFromVariable(eventData, syncRefTarget, string.Empty);

foreach (var space in eventData.Slot!.GetAvailableSpaces())
{
var spaceName = string.IsNullOrWhiteSpace(space.CurrentName) ? "<color=neutrals.midlight><i>null</i></color>" : space.CurrentName;

eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive.FromSpace", "space", spaceName), DriveIcon, DriveColor)
eventData.ContextMenu.AddItem(Instance.GetLocaleString("Drive.FromSpace", "space", spaceName), DriveIcon, DriveColor)
.Button.LocalPressed += GetOfferSyncRefDriveActions(eventData, syncRefTarget, space);
}
});
Expand All @@ -74,15 +116,15 @@ private static ButtonEventHandler GetOfferSyncRefReferenceActions<T>(GenerationE
if (await eventData.OpenContextMenuAsync(args.source.Slot) is null)
return;

eventData.ContextMenu.AddItem(Mod.GetLocaleString("Reference.Blank"), ReferenceIcon, ReferenceColor)
eventData.ContextMenu.AddItem(Instance.GetLocaleString("Reference.Blank"), ReferenceIcon, ReferenceColor)
.Button.LocalPressed += GetReferenceSyncRefForVariable(eventData, syncRefTarget, string.Empty);

var spaces = eventData.Slot!
.GetAvailableSpaces(SpaceHasName);

foreach (var space in spaces)
{
eventData.ContextMenu.AddItem(Mod.GetLocaleString("Reference.InSpace", "space", space.SpaceName), ReferenceIcon, ReferenceColor)
eventData.ContextMenu.AddItem(Instance.GetLocaleString("Reference.InSpace", "space", space.SpaceName), ReferenceIcon, ReferenceColor)
.Button.LocalPressed += GetReferenceSyncRefForVariable(eventData, syncRefTarget, $"{space.SpaceName}/");
}
});
Expand All @@ -99,15 +141,15 @@ private static ButtonEventHandler GetOfferSyncRefSourceActions<T>(GenerationEven
if (await eventData.OpenContextMenuAsync(args.source.Slot) is null)
return;

eventData.ContextMenu.AddItem(Mod.GetLocaleString("Source.Blank"), SourceIcon, SourceColor)
eventData.ContextMenu.AddItem(Instance.GetLocaleString("Source.Blank"), SourceIcon, SourceColor)
.Button.LocalPressed += GetSourceSyncRefForVariable(eventData, syncRefTarget, string.Empty);

var spaces = eventData.Slot!
.GetAvailableSpaces(SpaceHasName);

foreach (var space in spaces)
{
eventData.ContextMenu.AddItem(Mod.GetLocaleString("Source.InSpace", "space", space.SpaceName), SourceIcon, SourceColor)
eventData.ContextMenu.AddItem(Instance.GetLocaleString("Source.InSpace", "space", space.SpaceName), SourceIcon, SourceColor)
.Button.LocalPressed += GetSourceSyncRefForVariable(eventData, syncRefTarget, $"{space.SpaceName}/");
}
});
Expand Down Expand Up @@ -140,14 +182,14 @@ private static void OfferSyncRefActions<T>(GenerationEvent eventData)

if (!syncRefTarget.IsLinked)
{
eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive"), DriveIcon, DriveColor)
eventData.ContextMenu.AddItem(Instance.GetLocaleString("Drive"), DriveIcon, DriveColor)
.Button.LocalPressed += GetOfferSyncRefDriveSpaceActions(eventData, syncRefTarget);
}

eventData.ContextMenu.AddItem(Mod.GetLocaleString("Source", "type", "DynamicReference"), SourceIcon, SourceColor)
eventData.ContextMenu.AddItem(Instance.GetLocaleString("Source", "type", "DynamicReference"), SourceIcon, SourceColor)
.Button.LocalPressed += GetOfferSyncRefSourceActions(eventData, syncRefTarget);

eventData.ContextMenu.AddItem(Mod.GetLocaleString("Reference"), ReferenceIcon, ReferenceColor)
eventData.ContextMenu.AddItem(Instance.GetLocaleString("Reference"), ReferenceIcon, ReferenceColor)
.Button.LocalPressed += GetOfferSyncRefReferenceActions(eventData, syncRefTarget);
}
}
Expand Down
24 changes: 12 additions & 12 deletions DynamicVariablePowerTools/ContextMenu/DVMA.Types.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ private static ButtonEventHandler GetOfferTypeFieldDriveActions(GenerationEvent

var blankVariableName = string.IsNullOrWhiteSpace(space.CurrentName) ? string.Empty : $"{space.CurrentName}/";

eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive.FromVariable", "variable", GetDisplayName(space, "")), DriveIcon, DriveColor)
eventData.ContextMenu.AddItem(Instance.GetLocaleString("Drive.FromVariable", "variable", GetDisplayName(space, "")), DriveIcon, DriveColor)
.Button.LocalPressed += GetDriveTypeFieldFromVariable(eventData, syncTypeTarget, blankVariableName);

foreach (var variable in space.GetVariableIdentities<Type>().RemoveSharedConfigVariables())
foreach (var variable in space.GetVariableIdentities<Type>().WithoutSharedConfigVariables())
{
eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive.FromVariable", "variable", GetDisplayName(variable)), DriveIcon, DriveColor)
eventData.ContextMenu.AddItem(Instance.GetLocaleString("Drive.FromVariable", "variable", GetDisplayName(variable)), DriveIcon, DriveColor)
.Button.LocalPressed += GetDriveTypeFieldFromVariable(eventData, syncTypeTarget, variable.QualifiedName);
}
});
Expand All @@ -47,12 +47,12 @@ private static ButtonEventHandler GetOfferTypeFieldDriveSpaceActions(GenerationE
if (await eventData.OpenContextMenuAsync(args.source.Slot) is null)
return;

eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive.FromBlank"), DriveIcon, DriveColor)
eventData.ContextMenu.AddItem(Instance.GetLocaleString("Drive.FromBlank"), DriveIcon, DriveColor)
.Button.LocalPressed += GetDriveFieldFromVariable(eventData, syncTypeTarget, string.Empty);

foreach (var space in eventData.Slot!.GetAvailableSpaces())
{
eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive.FromSpace", "space", GetDisplayName(space)), DriveIcon, DriveColor)
eventData.ContextMenu.AddItem(Instance.GetLocaleString("Drive.FromSpace", "space", GetDisplayName(space)), DriveIcon, DriveColor)
.Button.LocalPressed += GetOfferTypeFieldDriveActions(eventData, syncTypeTarget, space);
}
});
Expand All @@ -68,12 +68,12 @@ private static ButtonEventHandler GetOfferTypeFieldReferenceActions(GenerationEv
if (await eventData.OpenContextMenuAsync(args.source.Slot) is null)
return;

eventData.ContextMenu.AddItem(Mod.GetLocaleString("Reference.Blank"), ReferenceIcon, ReferenceColor)
eventData.ContextMenu.AddItem(Instance.GetLocaleString("Reference.Blank"), ReferenceIcon, ReferenceColor)
.Button.LocalPressed += GetReferenceTypeFieldForVariable(eventData, syncTypeTarget, string.Empty);

foreach (var space in eventData.Slot!.GetAvailableSpaces(SpaceHasName))
{
eventData.ContextMenu.AddItem(Mod.GetLocaleString("Reference.InSpace", "space", space.SpaceName), ReferenceIcon, ReferenceColor)
eventData.ContextMenu.AddItem(Instance.GetLocaleString("Reference.InSpace", "space", space.SpaceName), ReferenceIcon, ReferenceColor)
.Button.LocalPressed += GetReferenceTypeFieldForVariable(eventData, syncTypeTarget, $"{space.SpaceName}/");
}
});
Expand All @@ -89,12 +89,12 @@ private static ButtonEventHandler GetOfferTypeFieldSourceActions(GenerationEvent
if (await eventData.OpenContextMenuAsync(args.source.Slot) is null)
return;

eventData.ContextMenu.AddItem(Mod.GetLocaleString("Source.Blank"), SourceIcon, SourceColor)
eventData.ContextMenu.AddItem(Instance.GetLocaleString("Source.Blank"), SourceIcon, SourceColor)
.Button.LocalPressed += GetSourceTypeFieldForVariable(eventData, syncTypeTarget, string.Empty);

foreach (var space in eventData.Slot!.GetAvailableSpaces(SpaceHasName))
{
eventData.ContextMenu.AddItem(Mod.GetLocaleString("Source.InSpace", "space", space.SpaceName), SourceIcon, SourceColor)
eventData.ContextMenu.AddItem(Instance.GetLocaleString("Source.InSpace", "space", space.SpaceName), SourceIcon, SourceColor)
.Button.LocalPressed += GetSourceTypeFieldForVariable(eventData, syncTypeTarget, $"{space.SpaceName}/");
}
});
Expand Down Expand Up @@ -124,14 +124,14 @@ private static void OfferTypeFieldActions(GenerationEvent eventData)

if (!syncTypeTarget.IsLinked)
{
eventData.ContextMenu.AddItem(Mod.GetLocaleString("Drive"), DriveIcon, DriveColor)
eventData.ContextMenu.AddItem(Instance.GetLocaleString("Drive"), DriveIcon, DriveColor)
.Button.LocalPressed += GetOfferTypeFieldDriveSpaceActions(eventData, syncTypeTarget);
}

eventData.ContextMenu.AddItem(Mod.GetLocaleString("Source", "type", "DynamicTypeField"), SourceIcon, SourceColor)
eventData.ContextMenu.AddItem(Instance.GetLocaleString("Source", "type", "DynamicTypeField"), SourceIcon, SourceColor)
.Button.LocalPressed += GetOfferTypeFieldSourceActions(eventData, syncTypeTarget);

eventData.ContextMenu.AddItem(Mod.GetLocaleString("Reference"), ReferenceIcon, ReferenceColor)
eventData.ContextMenu.AddItem(Instance.GetLocaleString("Reference"), ReferenceIcon, ReferenceColor)
.Button.LocalPressed += GetOfferTypeFieldReferenceActions(eventData, syncTypeTarget);
}
}
Expand Down
Loading
Loading