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
136 changes: 86 additions & 50 deletions MonkeyLoader.Resonite.Core/DynamicVariableExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
using Elements.Core;
using FrooxEngine;
using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace MonkeyLoader.Resonite
{
Expand All @@ -19,6 +13,12 @@ namespace MonkeyLoader.Resonite
[TypeForwardedFrom("MonkeyLoader.Resonite.Integration")]
public static class DynamicVariableExtensions
{
/// <summary>
/// The name of the shared config slot in a <see cref="World"/>'s
/// <see cref="World.AssetsSlot">Assets</see> <see cref="Slot"/>.
/// </summary>
public const string SharedConfigIdentifier = "MonkeyLoader.SharedConfig";

//public static DynamicReference<T> CreateReferenceVariable<T>(this SyncRef<T> syncRef, string name, bool overrideOnLink = false, bool persistent = true)
// where T : class, IWorldElement
//{
Expand Down Expand Up @@ -70,11 +70,11 @@ public static DynamicVariableSpace FindOrCreateSpace(this Slot slot, string? spa
/// </summary>
/// <remarks>
/// This function is different from a regular
/// <c><see cref="Slot"/>.<see cref="Slot.GetComponentInParents{T}(Predicate{T}, bool, bool)">GetComponentsInParents</see>&lt;<see cref="DynamicVariableSpace"/>&gt;()</c>
/// call,<br/> as it considers that <see cref="DynamicVariableSpace"/>s deeper in the hierarchy
/// hide ones higher up with the same <see cref="DynamicVariableSpace.SpaceName">name</see>.<br/>
/// <c><see cref="Slot"/>.<see cref="Slot.GetComponentsInParents{T}(Predicate{T})">GetComponentsInParents</see>&lt;<see cref="DynamicVariableSpace"/>&gt;()</c> call,<br/>
/// as it considers that <see cref="DynamicVariableSpace"/>s deeper in the hierarchy
/// hide ones higher up with the same <see cref="DynamicVariableSpace.CurrentName">name</see>.<br/>
/// If a <see cref="DynamicVariableSpace"/> deeper in the hierarchy doesn't pass the <paramref name="filter"/>,<br/>
/// it will still hide any higher up ones with the same <see cref="DynamicVariableSpace.SpaceName">name</see>
/// it will still hide any higher up ones with the same <see cref="DynamicVariableSpace.CurrentName">name</see>
/// that might pass it, because they don't apply to this <see cref="Slot"/>.
/// </remarks>
/// <param name="slot">The <see cref="Slot"/> to find all applicable <see cref="DynamicVariableSpace"/>s for.</param>
Expand All @@ -92,17 +92,14 @@ public static IEnumerable<DynamicVariableSpace> GetAvailableSpaces(this Slot slo

foreach (var currentSpace in currentSpaces)
{
if (!filter(currentSpace))
{
presentNames.Add(currentSpace.SpaceName);
// Use CurrentName because it includes the processing of the SpaceName
if (!presentNames.Add(currentSpace.CurrentName))
continue;
}

if (presentNames.Contains(currentSpace.SpaceName))
if (!filter(currentSpace))
continue;

result.Add(currentSpace);
presentNames.Add(currentSpace.SpaceName.Value);
}

slot = slot.Parent;
Expand Down Expand Up @@ -352,40 +349,6 @@ public static IEnumerable<DynamicVariableIdentity> GetVariableIdentities(this Dy
public static IEnumerable<DynamicVariableIdentity> GetVariableIdentities(this DynamicVariableSpace space, string name)
=> [.. space.GetVariableIdentities().Where(id => id.Name == name)];

//public static DynamicField<T>? CreateVariable<T>(this IField<T> field, string name, bool overrideOnLink = false, bool persistent = true)
//{
// var variable = field.FindNearestParent<Slot>().AttachComponent<DynamicField<T>>();
// variable.TargetField.Target = field;
// variable.VariableName.Value = name;
// variable.OverrideOnLink.Value = overrideOnLink;
// variable.Persistent = persistent;

// return variable;
//}

//public static DynamicReferenceVariableDriver<T> DriveReferenceFromVariable<T>(this SyncRef<T> syncRef, string name, T? defaultTarget = default, bool persistent = true)
// where T : class, IWorldElement
//{
// var driver = syncRef.FindNearestParent<Slot>().AttachComponent<DynamicReferenceVariableDriver<T>>();
// driver.Target.Target = syncRef;
// driver.VariableName.Value = name;
// driver.DefaultTarget.Target = defaultTarget!;
// driver.Persistent = persistent;

// return driver;
//}

//public static DynamicValueVariableDriver<T> DriveValueFromVariable<T>(this IField<T> field, string name, T? defaultValue = default, bool persistent = true)
//{
// var driver = field.FindNearestParent<Slot>().AttachComponent<DynamicValueVariableDriver<T>>();
// driver.Target.Target = field;
// driver.VariableName.Value = name;
// driver.DefaultValue.Value = defaultValue!;
// driver.Persistent = persistent;

// return driver;
//}

/// <summary>
/// Determines whether this <see cref="IDynamicVariable">dynamic variable</see>
/// is linked against a <see cref="DynamicVariableSpace"/>.
Expand All @@ -411,6 +374,40 @@ public static bool IsLinkedToSpace(this IDynamicVariable dynamicVariable)
public static bool IsLinkedToSpace(this IDynamicVariable dynamicVariable, DynamicVariableSpace space)
=> dynamicVariable.TryGetLinkedSpace(out var linkedSpace) && linkedSpace == space;

/// <summary>
/// Determines whether this dynamic variable is part of
/// the <see cref="SharedConfigIdentifier">shared config</see>.
/// </summary>
/// <param name="dynamicVariable">The dynamic variable to check.</param>
/// <returns>
/// <see langword="false"/> if this dynamic variable is part of
/// the <see cref="SharedConfigIdentifier">shared config</see>; otherwise, <see langword="true"/>.
/// </returns>
public static bool IsNotSharedConfigVariable(this IDynamicVariable dynamicVariable)
=> !dynamicVariable.VariableName.StartsWith(SharedConfigIdentifier) || dynamicVariable.GetLinkedSpace().CurrentName is not "World";

/// <summary>
/// Determines whether this dynamic variable identity is part of
/// the <see cref="SharedConfigIdentifier">shared config</see>.
/// </summary>
/// <param name="identity">The dynamic variable identity to check.</param>
/// <returns>
/// <see langword="false"/> if this dynamic variable identity is part of
/// the <see cref="SharedConfigIdentifier">shared config</see>; otherwise, <see langword="true"/>.
/// </returns>
public static bool IsNotSharedConfigVariable(this DynamicVariableIdentity identity)
=> identity.Space.CurrentName is not "World" || !identity.Name.StartsWith(SharedConfigIdentifier);

//public static DynamicValueVariableDriver<T> DriveValueFromVariable<T>(this IField<T> field, string name, T? defaultValue = default, bool persistent = true)
//{
// var driver = field.FindNearestParent<Slot>().AttachComponent<DynamicValueVariableDriver<T>>();
// driver.Target.Target = field;
// driver.VariableName.Value = name;
// driver.DefaultValue.Value = defaultValue!;
// driver.Persistent = persistent;
// return driver;
//}

/// <summary>
/// Tests whether this string is a <see cref="DynamicVariableHelper.IsValidName">valid dynamic variable name</see>.
/// </summary>
Expand All @@ -429,6 +426,17 @@ public static bool IsValidName(this string? variableName)
public static void ParseAsPath(this string? path, out string? spaceName, out string? variableName)
=> DynamicVariableHelper.ParsePath(path!, out spaceName, out variableName);

//public static DynamicReferenceVariableDriver<T> DriveReferenceFromVariable<T>(this SyncRef<T> syncRef, string name, T? defaultTarget = default, bool persistent = true)
// where T : class, IWorldElement
//{
// var driver = syncRef.FindNearestParent<Slot>().AttachComponent<DynamicReferenceVariableDriver<T>>();
// driver.Target.Target = syncRef;
// driver.VariableName.Value = name;
// driver.DefaultTarget.Target = defaultTarget!;
// driver.Persistent = persistent;
// return driver;
//}

/// <summary>
/// <see cref="DynamicVariableHelper.ProcessName">Processes</see>
/// this string to a <see cref="string.Trim()">trimmed</see>
Expand All @@ -439,6 +447,34 @@ public static void ParseAsPath(this string? path, out string? spaceName, out str
public static string? ProcessName(this string? variableName)
=> DynamicVariableHelper.ProcessName(variableName!);

/// <summary>
/// Removes all dynamic variables from this sequence that are
/// <see cref="IsNotSharedConfigVariable(IDynamicVariable)">part of the shared config</see>.
/// </summary>
/// <param name="dynamicVariables">The sequence to remove <see cref="SharedConfigIdentifier">shared config</see> variables from.</param>
/// <returns>The sequence without any <see cref="SharedConfigIdentifier">shared config</see> variables.</returns>
public static IEnumerable<IDynamicVariable> RemoveSharedConfigVariables(this IEnumerable<IDynamicVariable> dynamicVariables)
=> dynamicVariables.Where(IsNotSharedConfigVariable);

/// <summary>
/// Removes all dynamic variables identities from this sequence that are
/// <see cref="IsNotSharedConfigVariable(DynamicVariableIdentity)">part of the shared config</see>.
/// </summary>
/// <param name="identities">The sequence to remove the identities of <see cref="SharedConfigIdentifier">shared config</see> variables from.</param>
/// <returns>The sequence without any identities of <see cref="SharedConfigIdentifier">shared config</see> variables.</returns>
public static IEnumerable<DynamicVariableIdentity> RemoveSharedConfigVariables(this IEnumerable<DynamicVariableIdentity> identities)
=> identities.Where(IsNotSharedConfigVariable);

//public static DynamicField<T>? CreateVariable<T>(this IField<T> field, string name, bool overrideOnLink = false, bool persistent = true)
//{
// var variable = field.FindNearestParent<Slot>().AttachComponent<DynamicField<T>>();
// variable.TargetField.Target = field;
// variable.VariableName.Value = name;
// variable.OverrideOnLink.Value = overrideOnLink;
// variable.Persistent = persistent;
// return variable;
//}

/// <summary>
/// Tries to get the <see cref="DynamicVariableHandler{T}"/> of this
/// <see cref="IDynamicVariable{T}">dynamic variable</see>.
Expand Down
36 changes: 25 additions & 11 deletions MonkeyLoader.Resonite.Core/DynamicVariableIdentity.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
using FrooxEngine;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;

namespace MonkeyLoader.Resonite
{
Expand All @@ -15,10 +11,31 @@ namespace MonkeyLoader.Resonite
public readonly struct DynamicVariableIdentity : IEquatable<DynamicVariableIdentity>
{
/// <summary>
/// Gets the <see cref="IDynamicVariable.VariableName">name</see> of this Dynamic Variable.
/// Gets the <see cref="DynamicVariableSpace.VariableIdentity.name">name</see> of this Dynamic Variable.
/// </summary>
public readonly string Name { get; }

/// <summary>
/// Gets the qualified name of the this Dynamic Variable
/// that will always link to its <see cref="Space">Space</see>.
/// </summary>
/// <remarks>
/// Because of <see cref="DynamicVariableHelper.ProcessName(string)">processing</see>,
/// this may use a different space prefix than the <see cref="DynamicVariableSpace.SpaceName"/>.<br/>
/// If the processed space name <see cref="string.IsNullOrWhiteSpace(string?)">is null or white space</see>
/// then it can only have variables bind to it when <see cref="DynamicVariableSpace.OnlyDirectBinding">OnlyDirectBinding</see> is disabled.
/// </remarks>
/// <value>
/// <c>$"{<see cref="Space">Space</see>.<see cref="DynamicVariableSpace.CurrentName">CurrentName</see>}/{<see cref="Name">Name</see>}"</c>
/// if the <see cref="DynamicVariableSpace.CurrentName">current space name</see>
/// <see cref="string.IsNullOrWhiteSpace(string?)">is null or white space</see>;
/// otherwise, just the <see cref="Name">Name</see>.
/// </value>
public readonly string QualifiedName
=> !string.IsNullOrWhiteSpace(Space.CurrentName)
? $"{Space.CurrentName}/{Name}"
: Name;

/// <summary>
/// Gets the <see cref="DynamicVariableSpace"/> that this Dynamic Variable is a part of.
/// </summary>
Expand All @@ -34,7 +51,7 @@ namespace MonkeyLoader.Resonite
/// </summary>
/// <param name="space">The <see cref="DynamicVariableSpace"/> that this Dynamic Variable is a part of.</param>
/// <param name="type">The <see cref="System.Type"/> of this Dynamic Variable.</param>
/// <param name="name">The <see cref="IDynamicVariable.VariableName">name</see> of this Dynamic Variable.</param>
/// <param name="name">The <see cref="DynamicVariableSpace.VariableIdentity.name">name</see> of this Dynamic Variable.</param>
public DynamicVariableIdentity(DynamicVariableSpace space, Type type, string name)
{
Space = space;
Expand All @@ -48,11 +65,8 @@ public DynamicVariableIdentity(DynamicVariableSpace space, Type type, string nam
/// <param name="space">The <see cref="DynamicVariableSpace"/> that this Dynamic Variable is a part of.</param>
/// <param name="variableIdentity">The Dynamic Variable's identity within the given <paramref name="space"/>.</param>
public DynamicVariableIdentity(DynamicVariableSpace space, DynamicVariableSpace.VariableIdentity variableIdentity)
{
Space = space;
Type = variableIdentity.type;
Name = variableIdentity.name;
}
: this(space, variableIdentity.type, variableIdentity.name)
{ }

/// <summary>
/// Determines whether two Dynamic Variable identities refer to different ones.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@
using MonkeyLoader.Components;
using MonkeyLoader.Configuration;
using MonkeyLoader.Meta;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MonkeyLoader.Resonite.Configuration
{
Expand All @@ -25,7 +20,7 @@ public static class SharedConfig
/// The name of the <see cref="GetSharedConfigSlot(World)">shared config slot</see>
/// in a <see cref="World"/>'s <see cref="World.AssetsSlot">Assets</see> <see cref="Slot"/>.
/// </summary>
public const string Identifier = "MonkeyLoader.SharedConfig";
public const string Identifier = DynamicVariableExtensions.SharedConfigIdentifier;

/// <summary>
/// The prefix for the <see cref="IDefiningConfigKey{T}.SetValue(T, string?)">SetValue</see>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
using FrooxEngine.CommonAvatar;
using FrooxEngine.UIX;
using HarmonyLib;
using System;
using System.Linq;

using static FrooxEngine.InteractionHandler;

namespace MonkeyLoader.Resonite.UI.ContextMenus
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"msbuild-sdks": {
"Remora.Resonite.Sdk": "2.0.10"
"Remora.Resonite.Sdk": "2.1.0"
}
}
Loading