Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SyncArray<TubePoint> proxying and SyncCurve<T> proxying to SyncArrayEditor, generate button to grab the array ref #67

Merged
merged 4 commits into from
Sep 5, 2024
Merged
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
138 changes: 134 additions & 4 deletions MonkeyLoader.Resonite.Integration/UI/SyncArrayEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ internal sealed class SyncArrayEditor : ResoniteMonkey<SyncArrayEditor>
private static readonly MethodInfo _addLinearValueProxying = AccessTools.Method(typeof(SyncArrayEditor), nameof(AddLinearValueProxying));
private static readonly MethodInfo _addListReferenceProxying = AccessTools.Method(typeof(SyncArrayEditor), nameof(AddListReferenceProxying));
private static readonly MethodInfo _addListValueProxying = AccessTools.Method(typeof(SyncArrayEditor), nameof(AddListValueProxying));
private static readonly MethodInfo _addCurveValueProxying = AccessTools.Method(typeof(SyncArrayEditor), nameof(AddCurveValueProxying));
private static readonly Type _iWorldElementType = typeof(IWorldElement);
private static readonly Type _particleBurstType = typeof(ParticleBurst);

Expand Down Expand Up @@ -121,6 +122,53 @@ private static void AddParticleBurstListProxying(SyncArray<LinearKey<ParticleBur
list.ElementsRemoved += (list, startIndex, count) => array.Remove(startIndex, count);
}

private static void AddTubePointProxying(SyncArray<TubePoint> array, SyncElementList<ValueGradientDriver<float3>.Point> list)
{
foreach (var tubePoint in array)
{
var point = list.Add();
point.Position.Value = tubePoint.radius;
point.Value.Value = tubePoint.position;
}

AddUpdateProxies(array, list, list.Elements);

list.ElementsAdded += (list, startIndex, count) =>
{
var addedElements = list.Elements.Skip(startIndex).Take(count).ToArray();
var buffer = addedElements.Select(point => new TubePoint(point.Value.Value, point.Position.Value)).ToArray();

array.Insert(buffer, startIndex);
AddUpdateProxies(array, list, addedElements);
};

list.ElementsRemoved += (list, startIndex, count) => array.Remove(startIndex, count);
}

private static void AddCurveValueProxying<T>(SyncArray<CurveKey<T>> array, SyncElementList<ValueGradientDriver<T>.Point> list)
where T : IEquatable<T>
{
foreach (var key in array)
{
var point = list.Add();
point.Position.Value = key.time;
point.Value.Value = key.value;
}

AddUpdateProxies(array, list, list.Elements);

list.ElementsAdded += (list, startIndex, count) =>
{
var addedElements = list.Elements.Skip(startIndex).Take(count).ToArray();
var buffer = addedElements.Select(point => new CurveKey<T>(point.Position, point.Value)).ToArray();

array.Insert(buffer, startIndex);
AddUpdateProxies(array, list, addedElements);
};

list.ElementsRemoved += (list, startIndex, count) => array.Remove(startIndex, count);
}

private static void AddUpdateProxies<T>(SyncArray<LinearKey<T>> array,
SyncElementList<ValueGradientDriver<T>.Point> list, IEnumerable<ValueGradientDriver<T>.Point> elements)
where T : IEquatable<T>
Expand Down Expand Up @@ -175,6 +223,33 @@ private static void AddUpdateProxies<T>(SyncArray<T> array, SyncElementList<Sync
}
}

private static void AddUpdateProxies(SyncArray<TubePoint> array, SyncElementList<ValueGradientDriver<float3>.Point> list, IEnumerable<ValueGradientDriver<float3>.Point> elements)
{
foreach (var point in elements)
{
point.Changed += field =>
{
var index = list.IndexOfElement(point);
var tubePoint = new TubePoint(point.Value.Value, point.Position.Value);
array[index] = tubePoint;
};
}
}

private static void AddUpdateProxies<T>(SyncArray<CurveKey<T>> array,
SyncElementList<ValueGradientDriver<T>.Point> list, IEnumerable<ValueGradientDriver<T>.Point> elements)
where T : IEquatable<T>
{
foreach (var point in elements)
{
point.Changed += syncObject =>
{
var index = list.IndexOfElement(point);
array[index] = new CurveKey<T>(point.Position, point.Value, array[index].leftTangent, array[index].rightTangent);
};
}
}

private static Component GetOrAttachComponent(Slot targetSlot, Type type, out bool attachedNew)
{
attachedNew = false;
Expand All @@ -186,7 +261,7 @@ private static Component GetOrAttachComponent(Slot targetSlot, Type type, out bo
return comp;
}

private static bool Prefix(ISyncArray array, string name, FieldInfo fieldInfo, UIBuilder ui)
private static bool Prefix(ISyncArray array, string name, FieldInfo fieldInfo, UIBuilder ui, float labelSize)
{
if (!Enabled) return true;

Expand All @@ -195,8 +270,11 @@ private static bool Prefix(ISyncArray array, string name, FieldInfo fieldInfo, U

var isSyncLinear = TryGetGenericParameters(typeof(SyncLinear<>), array.GetType(), out var syncLinearGenericParameters);

var isSyncCurve = TryGetGenericParameters(typeof(SyncCurve<>), array.GetType(), out var syncCurveGenericParameters);

var arrayType = genericParameters!.Value.First();
var syncLinearType = syncLinearGenericParameters?.First();
var syncCurveType = syncCurveGenericParameters?.First();

var isParticleBurst = syncLinearType == _particleBurstType;

Expand Down Expand Up @@ -231,9 +309,34 @@ private static bool Prefix(ISyncArray array, string name, FieldInfo fieldInfo, U
_addLinearValueProxying.MakeGenericMethod(syncLinearType).Invoke(null, new object[] { array, list });
}
}
else if (isSyncCurve && SupportsLerp(syncCurveType!))
{
var gradientType = typeof(ValueGradientDriver<>).MakeGenericType(syncCurveType);
var gradient = GetOrAttachComponent(proxySlot, gradientType, out bool attachedNew);

list = (ISyncList)gradient.GetSyncMember(nameof(ValueGradientDriver<float>.Points));
listField = gradient.GetSyncMemberFieldInfo(nameof(ValueGradientDriver<float>.Points));

if (attachedNew)
{
_addCurveValueProxying.MakeGenericMethod(syncCurveType).Invoke(null, new object[] { array, list });
}
}
else
{
if (Coder.IsEnginePrimitive(arrayType))
if (arrayType == typeof(TubePoint))
{
var gradient = GetOrAttachComponent(proxySlot, typeof(ValueGradientDriver<float3>), out bool attachedNew);

list = (ISyncList)gradient.GetSyncMember(nameof(ValueGradientDriver<float3>.Points));
listField = gradient.GetSyncMemberFieldInfo(nameof(ValueGradientDriver<float3>.Points));

if (attachedNew)
{
AddTubePointProxying((SyncArray<TubePoint>)array, (SyncElementList<ValueGradientDriver<float3>.Point>)list);
}
}
else if (Coder.IsEnginePrimitive(arrayType))
{
var multiplexerType = typeof(ValueMultiplexer<>).MakeGenericType(arrayType);
var multiplexer = GetOrAttachComponent(proxySlot, multiplexerType, out bool attachedNew);
Expand All @@ -260,8 +363,35 @@ private static bool Prefix(ISyncArray array, string name, FieldInfo fieldInfo, U
}
}

SyncMemberEditorBuilder.BuildList(list, name, listField, ui);
ui.Current[ui.Current.ChildrenCount - 1].DestroyWhenLocalUserLeaves();
ui.Panel().Slot.GetComponent<LayoutElement>();
var memberFieldSlot = SyncMemberEditorBuilder.GenerateMemberField(array, name, ui, labelSize);
ui.NestOut();
if (!array.IsDriven)
{
SyncMemberEditorBuilder.BuildList(list, name, listField, ui);
var listSlot = ui.Current;
listSlot.DestroyWhenLocalUserLeaves();
void ArrayChanged(IChangeable changeable)
{
if (((ISyncArray)changeable).IsDriven)
{
listSlot.DestroyChildren();
listSlot.Components.ToArray().Do((Component c) => c.Destroy());
listSlot.AttachComponent<LayoutElement>().MinHeight.Value = 24f;
var newUi = new UIBuilder(listSlot, listSlot);
RadiantUI_Constants.SetupEditorStyle(newUi);
newUi.Text("(array is driven)");
proxySlot?.Destroy();
array.Changed -= ArrayChanged;
}
}
array.Changed += ArrayChanged;
}
else
{
LocaleString text = "(array is driven)";
ui.Text(in text);
}

return false;
}
Expand Down
Loading