testss
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Descriptor(typeof(CreateStruct))]
|
||||
public class CreateStructDescriptor : UnitDescriptor<CreateStruct>
|
||||
{
|
||||
public CreateStructDescriptor(CreateStruct unit) : base(unit) { }
|
||||
|
||||
protected override string DefinedTitle()
|
||||
{
|
||||
if (BoltCore.Configuration.humanNaming)
|
||||
{
|
||||
return $"Create {unit.type.HumanName()}";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"new {unit.type.CSharpName()}";
|
||||
}
|
||||
}
|
||||
|
||||
protected override string DefinedShortTitle()
|
||||
{
|
||||
return BoltCore.Configuration.humanNaming ? "Create" : "new";
|
||||
}
|
||||
|
||||
protected override string DefinedSurtitle()
|
||||
{
|
||||
return unit.type.DisplayName();
|
||||
}
|
||||
|
||||
protected override string DefinedSummary()
|
||||
{
|
||||
return unit.type.Summary();
|
||||
}
|
||||
|
||||
protected override EditorTexture DefinedIcon()
|
||||
{
|
||||
return unit.type.Icon();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[FuzzyOption(typeof(CreateStruct))]
|
||||
public class CreateStructOption : UnitOption<CreateStruct>
|
||||
{
|
||||
public CreateStructOption() : base() { }
|
||||
|
||||
public CreateStructOption(CreateStruct unit) : base(unit) { }
|
||||
|
||||
public Type structType { get; private set; }
|
||||
|
||||
protected override void FillFromUnit()
|
||||
{
|
||||
structType = unit.type;
|
||||
base.FillFromUnit();
|
||||
}
|
||||
|
||||
protected override string Label(bool human)
|
||||
{
|
||||
if (human)
|
||||
{
|
||||
return $"Create {structType.HumanName()} ()";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"new {structType.CSharpName()} ()";
|
||||
}
|
||||
}
|
||||
|
||||
protected override string Haystack(bool human)
|
||||
{
|
||||
if (human)
|
||||
{
|
||||
return $"{structType.HumanName()}: Create {structType.HumanName()}";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"new {structType.CSharpName()}";
|
||||
}
|
||||
}
|
||||
|
||||
public override string SearchResultLabel(string query)
|
||||
{
|
||||
return base.SearchResultLabel(query) + " ()";
|
||||
}
|
||||
|
||||
protected override int Order()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected override string FavoriteKey()
|
||||
{
|
||||
return $"{structType.FullName}@create";
|
||||
}
|
||||
|
||||
public override void Deserialize(UnitOptionRow row)
|
||||
{
|
||||
base.Deserialize(row);
|
||||
|
||||
structType = Codebase.DeserializeType(row.tag1);
|
||||
}
|
||||
|
||||
public override UnitOptionRow Serialize()
|
||||
{
|
||||
var row = base.Serialize();
|
||||
|
||||
row.tag1 = Codebase.SerializeType(structType);
|
||||
|
||||
return row;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Descriptor(typeof(Expose))]
|
||||
public class ExposeDescriptor : UnitDescriptor<Expose>
|
||||
{
|
||||
public ExposeDescriptor(Expose unit) : base(unit) { }
|
||||
|
||||
protected override string DefinedTitle()
|
||||
{
|
||||
return $"Expose {unit.type.DisplayName()}";
|
||||
}
|
||||
|
||||
protected override string DefinedSurtitle()
|
||||
{
|
||||
return "Expose";
|
||||
}
|
||||
|
||||
protected override string DefinedShortTitle()
|
||||
{
|
||||
return unit.type.DisplayName();
|
||||
}
|
||||
|
||||
protected override EditorTexture DefinedIcon()
|
||||
{
|
||||
return unit.type.Icon();
|
||||
}
|
||||
|
||||
protected override void DefinedPort(IUnitPort port, UnitPortDescription description)
|
||||
{
|
||||
base.DefinedPort(port, description);
|
||||
|
||||
if (port is ValueOutput && unit.members.TryGetValue((ValueOutput)port, out Member member))
|
||||
{
|
||||
description.label = member.info.HumanName();
|
||||
description.summary = member.info.Summary();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[FuzzyOption(typeof(Expose))]
|
||||
public class ExposeOption : UnitOption<Expose>
|
||||
{
|
||||
public ExposeOption() : base() { }
|
||||
|
||||
public ExposeOption(Expose unit) : base(unit)
|
||||
{
|
||||
sourceScriptGuids = UnitBase.GetScriptGuids(unit.type).ToHashSet();
|
||||
}
|
||||
|
||||
public Type exposedType { get; private set; }
|
||||
|
||||
protected override string FavoriteKey()
|
||||
{
|
||||
return $"{exposedType.FullName}@expose";
|
||||
}
|
||||
|
||||
protected override string Label(bool human)
|
||||
{
|
||||
return $"Expose {unit.type.SelectedName(human)}";
|
||||
}
|
||||
|
||||
protected override bool ShowValueOutputsInFooter()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override void FillFromUnit()
|
||||
{
|
||||
exposedType = unit.type;
|
||||
|
||||
base.FillFromUnit();
|
||||
}
|
||||
|
||||
public override void Deserialize(UnitOptionRow row)
|
||||
{
|
||||
base.Deserialize(row);
|
||||
|
||||
exposedType = Codebase.DeserializeType(row.tag1);
|
||||
}
|
||||
|
||||
public override UnitOptionRow Serialize()
|
||||
{
|
||||
var row = base.Serialize();
|
||||
|
||||
row.tag1 = Codebase.SerializeType(exposedType);
|
||||
|
||||
return row;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Descriptor(typeof(GetMember))]
|
||||
public class GetMemberDescriptor : MemberUnitDescriptor<GetMember>
|
||||
{
|
||||
public GetMemberDescriptor(GetMember unit) : base(unit) { }
|
||||
|
||||
protected override ActionDirection direction => ActionDirection.Get;
|
||||
|
||||
protected override void DefinedPort(IUnitPort port, UnitPortDescription description)
|
||||
{
|
||||
base.DefinedPort(port, description);
|
||||
|
||||
if (port == unit.value)
|
||||
{
|
||||
description.summary = unit.member.info.Summary();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[FuzzyOption(typeof(GetMember))]
|
||||
public class GetMemberOption : MemberUnitOption<GetMember>
|
||||
{
|
||||
public GetMemberOption() : base() { }
|
||||
|
||||
public GetMemberOption(GetMember unit) : base(unit) { }
|
||||
|
||||
protected override ActionDirection direction => ActionDirection.Get;
|
||||
}
|
||||
}
|
@@ -0,0 +1,77 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Descriptor(typeof(InvokeMember))]
|
||||
public class InvokeMemberDescriptor : MemberUnitDescriptor<InvokeMember>
|
||||
{
|
||||
public InvokeMemberDescriptor(InvokeMember unit) : base(unit) { }
|
||||
|
||||
protected override ActionDirection direction => ActionDirection.Any;
|
||||
|
||||
protected override string DefinedShortTitle()
|
||||
{
|
||||
if (member.isConstructor)
|
||||
{
|
||||
return BoltCore.Configuration.humanNaming ? "Create" : "new";
|
||||
}
|
||||
|
||||
return base.DefinedShortTitle();
|
||||
}
|
||||
|
||||
protected override void DefinedPort(IUnitPort port, UnitPortDescription description)
|
||||
{
|
||||
base.DefinedPort(port, description);
|
||||
|
||||
var documentation = member.info.Documentation();
|
||||
|
||||
if (port == unit.enter)
|
||||
{
|
||||
description.label = "Invoke";
|
||||
description.summary = "The entry point to invoke the method.";
|
||||
|
||||
if (member.isGettable)
|
||||
{
|
||||
description.summary += " You can still get the return value without connecting this port.";
|
||||
}
|
||||
}
|
||||
else if (port == unit.exit)
|
||||
{
|
||||
description.summary = "The action to call once the method has been invoked.";
|
||||
}
|
||||
else if (port == unit.result)
|
||||
{
|
||||
if (member.isGettable)
|
||||
{
|
||||
description.summary = documentation?.returns;
|
||||
}
|
||||
|
||||
if (unit.supportsChaining && unit.chainable)
|
||||
{
|
||||
description.showLabel = true;
|
||||
}
|
||||
}
|
||||
else if (port == unit.targetOutput)
|
||||
{
|
||||
if (member.isGettable)
|
||||
{
|
||||
description.showLabel = true;
|
||||
}
|
||||
}
|
||||
else if (port is ValueInput && unit.inputParameters.ContainsValue((ValueInput)port))
|
||||
{
|
||||
var parameter = member.GetParameterInfos().Single(p => "%" + p.Name == port.key);
|
||||
|
||||
description.label = parameter.DisplayName();
|
||||
description.summary = documentation?.ParameterSummary(parameter);
|
||||
}
|
||||
else if (port is ValueOutput && unit.outputParameters.ContainsValue((ValueOutput)port))
|
||||
{
|
||||
var parameter = member.GetParameterInfos().Single(p => "&" + p.Name == port.key);
|
||||
|
||||
description.label = parameter.DisplayName();
|
||||
description.summary = documentation?.ParameterSummary(parameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[FuzzyOption(typeof(InvokeMember))]
|
||||
public class InvokeMemberOption : MemberUnitOption<InvokeMember>
|
||||
{
|
||||
public InvokeMemberOption() : base() { }
|
||||
|
||||
public InvokeMemberOption(InvokeMember unit) : base(unit) { }
|
||||
|
||||
protected override ActionDirection direction => ActionDirection.Any;
|
||||
|
||||
public override string SearchResultLabel(string query)
|
||||
{
|
||||
return base.SearchResultLabel(query) + $" ({unit.member.methodBase.DisplayParameterString(unit.member.targetType)})";
|
||||
}
|
||||
|
||||
protected override string Label(bool human)
|
||||
{
|
||||
return base.Label(human) + $" ({unit.member.methodBase.SelectedParameterString(unit.member.targetType, human)})";
|
||||
}
|
||||
|
||||
protected override string Haystack(bool human)
|
||||
{
|
||||
if (!human && member.isConstructor)
|
||||
{
|
||||
return base.Label(human);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"{targetType.SelectedName(human)}{(human ? ": " : ".")}{base.Label(human)}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Descriptor(typeof(Literal))]
|
||||
public class LiteralDescriptor : UnitDescriptor<Literal>
|
||||
{
|
||||
public LiteralDescriptor(Literal unit) : base(unit) { }
|
||||
|
||||
protected override string DefinedTitle()
|
||||
{
|
||||
return unit.type.DisplayName() + " Literal";
|
||||
}
|
||||
|
||||
protected override string DefinedShortTitle()
|
||||
{
|
||||
return unit.type.DisplayName();
|
||||
}
|
||||
|
||||
protected override string DefinedSummary()
|
||||
{
|
||||
return unit.type.Summary();
|
||||
}
|
||||
|
||||
protected override EditorTexture DefinedIcon()
|
||||
{
|
||||
return unit.type.Icon();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Inspector(typeof(Literal))]
|
||||
public sealed class LiteralInspector : Inspector
|
||||
{
|
||||
public LiteralInspector(Metadata metadata) : base(metadata) { }
|
||||
|
||||
private Metadata typeMetadata => metadata[nameof(Literal.type)];
|
||||
private Metadata valueMetadata => metadata[nameof(Literal.value)];
|
||||
private Metadata typedValueMetadata => valueMetadata.Cast((Type)typeMetadata.value);
|
||||
|
||||
private bool hasType => typeMetadata.value != null;
|
||||
|
||||
protected override float GetHeight(float width, GUIContent label)
|
||||
{
|
||||
if (hasType)
|
||||
{
|
||||
return LudiqGUI.GetInspectorHeight(this, typedValueMetadata, width, label);
|
||||
}
|
||||
else
|
||||
{
|
||||
return LudiqGUI.GetInspectorHeight(this, typeMetadata, width, label);
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool cacheHeight => false;
|
||||
|
||||
protected override void OnGUI(Rect position, GUIContent label)
|
||||
{
|
||||
if (hasType)
|
||||
{
|
||||
LudiqGUI.Inspector(typedValueMetadata, position, label);
|
||||
}
|
||||
else
|
||||
{
|
||||
LudiqGUI.Inspector(typeMetadata, position, label);
|
||||
}
|
||||
}
|
||||
|
||||
public override float GetAdaptiveWidth()
|
||||
{
|
||||
if (hasType)
|
||||
{
|
||||
return typedValueMetadata.Inspector().GetAdaptiveWidth();
|
||||
}
|
||||
else
|
||||
{
|
||||
return typeMetadata.Inspector().GetAdaptiveWidth();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using UnityObject = UnityEngine.Object;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[FuzzyOption(typeof(Literal))]
|
||||
public class LiteralOption : UnitOption<Literal>
|
||||
{
|
||||
public LiteralOption() : base() { }
|
||||
|
||||
public LiteralOption(Literal unit) : base(unit)
|
||||
{
|
||||
sourceScriptGuids = UnitBase.GetScriptGuids(unit.type).ToHashSet();
|
||||
}
|
||||
|
||||
public Type literalType { get; private set; }
|
||||
|
||||
protected override void FillFromUnit()
|
||||
{
|
||||
literalType = unit.type;
|
||||
base.FillFromUnit();
|
||||
}
|
||||
|
||||
protected override string Label(bool human)
|
||||
{
|
||||
if (unit.value is UnityObject uo && !uo.IsUnityNull())
|
||||
{
|
||||
return UnityAPI.Await(() => uo.name);
|
||||
}
|
||||
|
||||
return unit.type.SelectedName(human) + " Literal";
|
||||
}
|
||||
|
||||
protected override EditorTexture Icon()
|
||||
{
|
||||
if (unit.value is UnityObject uo && !uo.IsUnityNull())
|
||||
{
|
||||
return uo.Icon();
|
||||
}
|
||||
|
||||
return base.Icon();
|
||||
}
|
||||
|
||||
protected override string FavoriteKey()
|
||||
{
|
||||
return $"{literalType.FullName}@literal";
|
||||
}
|
||||
|
||||
public override void Deserialize(UnitOptionRow row)
|
||||
{
|
||||
base.Deserialize(row);
|
||||
|
||||
literalType = Codebase.DeserializeType(row.tag1);
|
||||
}
|
||||
|
||||
public override UnitOptionRow Serialize()
|
||||
{
|
||||
var row = base.Serialize();
|
||||
|
||||
row.tag1 = Codebase.SerializeType(literalType);
|
||||
|
||||
return row;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Widget(typeof(Literal))]
|
||||
public sealed class LiteralWidget : UnitWidget<Literal>
|
||||
{
|
||||
public LiteralWidget(FlowCanvas canvas, Literal unit) : base(canvas, unit) { }
|
||||
|
||||
protected override bool showHeaderAddon => unit.isDefined;
|
||||
|
||||
public override bool foregroundRequiresInput => true;
|
||||
|
||||
protected override float GetHeaderAddonWidth()
|
||||
{
|
||||
var adaptiveWidthAttribute = unit.type.GetAttribute<InspectorAdaptiveWidthAttribute>();
|
||||
|
||||
return Mathf.Min(metadata.Inspector().GetAdaptiveWidth(), adaptiveWidthAttribute?.width ?? Styles.maxSettingsWidth);
|
||||
}
|
||||
|
||||
protected override float GetHeaderAddonHeight(float width)
|
||||
{
|
||||
return LudiqGUI.GetInspectorHeight(null, metadata, width, GUIContent.none);
|
||||
}
|
||||
|
||||
public override void BeforeFrame()
|
||||
{
|
||||
base.BeforeFrame();
|
||||
|
||||
if (showHeaderAddon &&
|
||||
GetHeaderAddonWidth() != headerAddonPosition.width ||
|
||||
GetHeaderAddonHeight(headerAddonPosition.width) != headerAddonPosition.height)
|
||||
{
|
||||
Reposition();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void DrawHeaderAddon()
|
||||
{
|
||||
using (LudiqGUIUtility.labelWidth.Override(75)) // For reflected inspectors / custom property drawers
|
||||
using (Inspector.adaptiveWidth.Override(true))
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
LudiqGUI.Inspector(metadata, headerAddonPosition, GUIContent.none);
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
unit.EnsureDefined();
|
||||
Reposition();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Analyser(typeof(MemberUnit))]
|
||||
public class MemberUnitAnalyser : UnitAnalyser<MemberUnit>
|
||||
{
|
||||
public MemberUnitAnalyser(GraphReference reference, MemberUnit target) : base(reference, target) { }
|
||||
|
||||
protected override IEnumerable<Warning> Warnings()
|
||||
{
|
||||
foreach (var baseWarning in base.Warnings())
|
||||
{
|
||||
yield return baseWarning;
|
||||
}
|
||||
|
||||
if (target.member != null && target.member.isReflected)
|
||||
{
|
||||
var obsoleteAttribute = target.member.info.GetAttribute<ObsoleteAttribute>();
|
||||
|
||||
if (obsoleteAttribute != null)
|
||||
{
|
||||
if (obsoleteAttribute.Message != null)
|
||||
{
|
||||
Debug.LogWarning($"\"{target.member.name}\" unit member is deprecated: {obsoleteAttribute.Message}");
|
||||
yield return Warning.Caution("Deprecated: " + obsoleteAttribute.Message);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"\"{target.member.name}\" unit member is deprecated.");
|
||||
yield return Warning.Caution($"Member {target.member.name} is deprecated.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Unity.VisualScripting.AssemblyQualifiedNameParser;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public abstract class MemberUnitDescriptor<TMemberUnit> : UnitDescriptor<TMemberUnit> where TMemberUnit : MemberUnit
|
||||
{
|
||||
protected MemberUnitDescriptor(TMemberUnit unit) : base(unit)
|
||||
{
|
||||
}
|
||||
|
||||
protected Member member => unit.member;
|
||||
|
||||
protected abstract ActionDirection direction { get; }
|
||||
|
||||
private string Name()
|
||||
{
|
||||
return unit.member.info.DisplayName(direction);
|
||||
}
|
||||
|
||||
protected override string DefinedTitle()
|
||||
{
|
||||
return Name();
|
||||
}
|
||||
|
||||
protected override string ErrorSurtitle(Exception exception)
|
||||
{
|
||||
if (member?.targetType != null)
|
||||
{
|
||||
return member.targetType.DisplayName();
|
||||
}
|
||||
else if (member?.targetTypeName != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var parsedName = new ParsedAssemblyQualifiedName(member.targetTypeName).TypeName.Split('.').Last();
|
||||
|
||||
if (BoltCore.Configuration.humanNaming)
|
||||
{
|
||||
return parsedName.Prettify();
|
||||
}
|
||||
else
|
||||
{
|
||||
return parsedName;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
return "Malformed Type Name";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Missing Type";
|
||||
}
|
||||
}
|
||||
|
||||
protected override string ErrorTitle(Exception exception)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(member?.name))
|
||||
{
|
||||
if (BoltCore.Configuration.humanNaming)
|
||||
{
|
||||
return member.name.Prettify();
|
||||
}
|
||||
else
|
||||
{
|
||||
return member.name;
|
||||
}
|
||||
}
|
||||
|
||||
return base.ErrorTitle(exception);
|
||||
}
|
||||
|
||||
protected override string DefinedShortTitle()
|
||||
{
|
||||
return Name();
|
||||
}
|
||||
|
||||
protected override EditorTexture DefinedIcon()
|
||||
{
|
||||
return member.targetType.Icon();
|
||||
}
|
||||
|
||||
protected override EditorTexture ErrorIcon(Exception exception)
|
||||
{
|
||||
if (member.targetType != null)
|
||||
{
|
||||
return member.targetType.Icon();
|
||||
}
|
||||
|
||||
return base.ErrorIcon(exception);
|
||||
}
|
||||
|
||||
protected override string DefinedSurtitle()
|
||||
{
|
||||
return member.targetType.DisplayName();
|
||||
}
|
||||
|
||||
protected override string DefinedSummary()
|
||||
{
|
||||
return member.info.Summary();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public interface IMemberUnitOption : IUnitOption
|
||||
{
|
||||
Type targetType { get; }
|
||||
Member member { get; }
|
||||
Member pseudoDeclarer { get; }
|
||||
}
|
||||
|
||||
public abstract class MemberUnitOption<TMemberUnit> : UnitOption<TMemberUnit>, IMemberUnitOption where TMemberUnit : MemberUnit
|
||||
{
|
||||
protected MemberUnitOption() : base() { }
|
||||
|
||||
protected MemberUnitOption(TMemberUnit unit) : base(unit)
|
||||
{
|
||||
sourceScriptGuids = UnitBase.GetScriptGuids(unit.member.targetType).ToHashSet();
|
||||
}
|
||||
|
||||
private Member _member;
|
||||
|
||||
private Member _pseudoDeclarer;
|
||||
|
||||
public Member member
|
||||
{
|
||||
get => _member ?? unit.member;
|
||||
set => _member = value;
|
||||
}
|
||||
|
||||
public Member pseudoDeclarer
|
||||
{
|
||||
get => _pseudoDeclarer ?? member.ToPseudoDeclarer();
|
||||
set => _pseudoDeclarer = value;
|
||||
}
|
||||
|
||||
public bool isPseudoInherited => member == pseudoDeclarer;
|
||||
|
||||
protected abstract ActionDirection direction { get; }
|
||||
|
||||
public Type targetType { get; private set; }
|
||||
|
||||
protected override GUIStyle Style()
|
||||
{
|
||||
if (unit.member.isPseudoInherited)
|
||||
{
|
||||
return FuzzyWindow.Styles.optionWithIconDim;
|
||||
}
|
||||
|
||||
return base.Style();
|
||||
}
|
||||
|
||||
protected override string Label(bool human)
|
||||
{
|
||||
return unit.member.info.SelectedName(human, direction);
|
||||
}
|
||||
|
||||
protected override string FavoriteKey()
|
||||
{
|
||||
return $"{member.ToUniqueString()}@{direction.ToString().ToLower()}";
|
||||
}
|
||||
|
||||
protected override int Order()
|
||||
{
|
||||
if (member.isConstructor)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return base.Order();
|
||||
}
|
||||
|
||||
protected override string Haystack(bool human)
|
||||
{
|
||||
return $"{targetType.SelectedName(human)}{(human ? ": " : ".")}{Label(human)}";
|
||||
}
|
||||
|
||||
protected override void FillFromUnit()
|
||||
{
|
||||
targetType = unit.member.targetType;
|
||||
member = unit.member;
|
||||
pseudoDeclarer = member.ToPseudoDeclarer();
|
||||
|
||||
base.FillFromUnit();
|
||||
}
|
||||
|
||||
public override void Deserialize(UnitOptionRow row)
|
||||
{
|
||||
base.Deserialize(row);
|
||||
|
||||
targetType = Codebase.DeserializeType(row.tag1);
|
||||
|
||||
if (!string.IsNullOrEmpty(row.tag2))
|
||||
{
|
||||
member = Codebase.DeserializeMember(row.tag2);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(row.tag3))
|
||||
{
|
||||
pseudoDeclarer = Codebase.DeserializeMember(row.tag3);
|
||||
}
|
||||
}
|
||||
|
||||
public override UnitOptionRow Serialize()
|
||||
{
|
||||
var row = base.Serialize();
|
||||
|
||||
row.tag1 = Codebase.SerializeType(targetType);
|
||||
row.tag2 = Codebase.SerializeMember(member);
|
||||
row.tag3 = Codebase.SerializeMember(pseudoDeclarer);
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
public override void OnPopulate()
|
||||
{
|
||||
// Members are late-reflected to speed up loading and search
|
||||
// We only reflect them when we're just about to populate their node
|
||||
// By doing it in OnPopulate instead of on-demand later, we ensure
|
||||
// any error will be gracefully catched and shown as a warning by
|
||||
// the fuzzy window
|
||||
|
||||
member.EnsureReflected();
|
||||
pseudoDeclarer.EnsureReflected();
|
||||
|
||||
base.OnPopulate();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
#if PACKAGE_INPUT_SYSTEM_EXISTS
|
||||
using System.Collections.Generic;
|
||||
using Unity.VisualScripting.InputSystem;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Analyser(typeof(OnInputSystemEvent))]
|
||||
public class OnInputSystemEventAnalyser : UnitAnalyser<OnInputSystemEvent>
|
||||
{
|
||||
public OnInputSystemEventAnalyser(GraphReference reference, OnInputSystemEvent target) : base(reference, target) {}
|
||||
|
||||
protected override IEnumerable<Warning> Warnings()
|
||||
{
|
||||
foreach (var baseWarning in base.Warnings())
|
||||
yield return baseWarning;
|
||||
|
||||
if (target.InputActionChangeType == InputActionChangeOption.OnHold ||
|
||||
target.InputActionChangeType == InputActionChangeOption.OnReleased)
|
||||
{
|
||||
if (Flow.CanPredict(target.InputAction, reference))
|
||||
{
|
||||
var inputAction = Flow.Predict<InputAction>(target.InputAction, reference);
|
||||
if (inputAction.type == InputActionType.PassThrough)
|
||||
yield return Warning.Caution($"Input action '{inputAction.name}' is of type 'Passthrough', which do not support 'On Hold' or 'On Released' events");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,30 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Descriptor(typeof(SetMember))]
|
||||
public class SetMemberDescriptor : MemberUnitDescriptor<SetMember>
|
||||
{
|
||||
public SetMemberDescriptor(SetMember unit) : base(unit) { }
|
||||
|
||||
protected override ActionDirection direction => ActionDirection.Set;
|
||||
|
||||
protected override void DefinedPort(IUnitPort port, UnitPortDescription description)
|
||||
{
|
||||
base.DefinedPort(port, description);
|
||||
|
||||
if (port == unit.assign)
|
||||
{
|
||||
description.label = "Set";
|
||||
description.summary = "The entry point to set the value.";
|
||||
}
|
||||
else if (port == unit.assigned)
|
||||
{
|
||||
description.label = "On Set";
|
||||
description.summary = "The action to call once the value has been set.";
|
||||
}
|
||||
else if (port == unit.output)
|
||||
{
|
||||
description.summary = unit.member.info.Summary();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,17 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[FuzzyOption(typeof(SetMember))]
|
||||
public class SetMemberOption : MemberUnitOption<SetMember>
|
||||
{
|
||||
public SetMemberOption() : base() { }
|
||||
|
||||
public SetMemberOption(SetMember unit) : base(unit) { }
|
||||
|
||||
protected override ActionDirection direction => ActionDirection.Set;
|
||||
|
||||
protected override bool ShowValueOutputsInFooter()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Analyser(typeof(For))]
|
||||
public class ForAnalyser : UnitAnalyser<For>
|
||||
{
|
||||
public ForAnalyser(GraphReference reference, For target)
|
||||
: base(reference, target) { }
|
||||
|
||||
protected override IEnumerable<Warning> Warnings()
|
||||
{
|
||||
foreach (var baseWarning in base.Warnings())
|
||||
{
|
||||
yield return baseWarning;
|
||||
}
|
||||
|
||||
if (unit.IsStepValueZero())
|
||||
{
|
||||
yield return Warning.Caution("The step value is 0. This will prevent the For unit to be executed or can cause an infinite loop.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Descriptor(typeof(ForEach))]
|
||||
public class ForEachDescriptor : UnitDescriptor<ForEach>
|
||||
{
|
||||
public ForEachDescriptor(ForEach unit) : base(unit) { }
|
||||
|
||||
protected override void DefinedPort(IUnitPort port, UnitPortDescription description)
|
||||
{
|
||||
base.DefinedPort(port, description);
|
||||
|
||||
if (unit.dictionary && port == unit.currentItem)
|
||||
{
|
||||
description.label = "Value";
|
||||
description.summary = "The value of the current item of the loop.";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Descriptor(typeof(SelectOnEnum))]
|
||||
public class SelectOnEnumDescriptor : UnitDescriptor<SelectOnEnum>
|
||||
{
|
||||
public SelectOnEnumDescriptor(SelectOnEnum unit) : base(unit) { }
|
||||
|
||||
protected override void DefinedPort(IUnitPort port, UnitPortDescription description)
|
||||
{
|
||||
base.DefinedPort(port, description);
|
||||
|
||||
foreach (var branch in unit.branches)
|
||||
{
|
||||
if (branch.Value == port)
|
||||
{
|
||||
var enumValue = (Enum)branch.Key;
|
||||
|
||||
description.label = enumValue.DisplayName();
|
||||
description.summary = $"The value to return if the enum has the value '{enumValue}'.";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Descriptor(typeof(SelectOnFlow))]
|
||||
public class SelectOnFlowDescriptor : UnitDescriptor<SelectOnFlow>
|
||||
{
|
||||
public SelectOnFlowDescriptor(SelectOnFlow unit) : base(unit) { }
|
||||
|
||||
protected override void DefinedPort(IUnitPort port, UnitPortDescription description)
|
||||
{
|
||||
base.DefinedPort(port, description);
|
||||
|
||||
foreach (var branch in unit.branches)
|
||||
{
|
||||
if (port == branch.Key || port == branch.Value)
|
||||
{
|
||||
var index = int.Parse(port.key.PartAfter('_'));
|
||||
|
||||
var letter = ((char)('A' + index)).ToString();
|
||||
|
||||
description.label = letter;
|
||||
|
||||
if (port == branch.Key)
|
||||
{
|
||||
description.summary = $"Trigger to select the {letter} value.";
|
||||
}
|
||||
else if (port == branch.Value)
|
||||
{
|
||||
description.summary = $"The value to return if the {letter} control input is triggered.";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Descriptor(typeof(SelectOnInteger))]
|
||||
public class SelectOnIntegerDescriptor : SelectUnitDescriptor<int>
|
||||
{
|
||||
public SelectOnIntegerDescriptor(SelectOnInteger unit) : base(unit) { }
|
||||
|
||||
protected override string GetLabelForOption(int option)
|
||||
{
|
||||
return option.ToString();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Descriptor(typeof(SelectOnString))]
|
||||
public class SelectOnStringDescriptor : SelectUnitDescriptor<string>
|
||||
{
|
||||
public SelectOnStringDescriptor(SelectOnString unit) : base(unit) { }
|
||||
|
||||
protected override string GetLabelForOption(string option)
|
||||
{
|
||||
if (string.IsNullOrEmpty(option))
|
||||
{
|
||||
return "Null / Empty";
|
||||
}
|
||||
|
||||
return $"\"{option}\"";
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class SelectUnitDescriptor<T> : UnitDescriptor<SelectUnit<T>>
|
||||
{
|
||||
public SelectUnitDescriptor(SelectUnit<T> unit) : base(unit) { }
|
||||
|
||||
protected virtual string GetLabelForOption(T option)
|
||||
{
|
||||
return option.ToString();
|
||||
}
|
||||
|
||||
protected override void DefinedPort(IUnitPort port, UnitPortDescription description)
|
||||
{
|
||||
base.DefinedPort(port, description);
|
||||
|
||||
foreach (var branch in unit.branches)
|
||||
{
|
||||
if (branch.Value == port)
|
||||
{
|
||||
var option = branch.Key;
|
||||
|
||||
description.label = GetLabelForOption(option);
|
||||
description.summary = $"The value to return if the enum has the value {GetLabelForOption(option)}.";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Descriptor(typeof(Sequence))]
|
||||
public class SequenceDescriptor : UnitDescriptor<Sequence>
|
||||
{
|
||||
public SequenceDescriptor(Sequence unit) : base(unit) { }
|
||||
|
||||
protected override void DefinedPort(IUnitPort port, UnitPortDescription description)
|
||||
{
|
||||
base.DefinedPort(port, description);
|
||||
|
||||
if (port is ControlOutput)
|
||||
{
|
||||
var index = unit.multiOutputs.IndexOf((ControlOutput)port);
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
description.label = index.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Descriptor(typeof(SwitchOnEnum))]
|
||||
public class SwitchOnEnumDescriptor : UnitDescriptor<SwitchOnEnum>
|
||||
{
|
||||
public SwitchOnEnumDescriptor(SwitchOnEnum unit) : base(unit) { }
|
||||
|
||||
protected override void DefinedPort(IUnitPort port, UnitPortDescription description)
|
||||
{
|
||||
base.DefinedPort(port, description);
|
||||
|
||||
foreach (var branch in unit.branches)
|
||||
{
|
||||
if (branch.Value == port)
|
||||
{
|
||||
var enumValue = branch.Key;
|
||||
description.label = enumValue.DisplayName();
|
||||
description.summary = $"The action to execute if the enum has the value '{enumValue}'.";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Descriptor(typeof(SwitchOnInteger))]
|
||||
public class SwitchOnIntegerDescriptor : SwitchUnitDescriptor<int>
|
||||
{
|
||||
public SwitchOnIntegerDescriptor(SwitchOnInteger unit) : base(unit) { }
|
||||
|
||||
protected override string GetLabelForOption(int option)
|
||||
{
|
||||
return option.ToString();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Descriptor(typeof(SwitchOnString))]
|
||||
public class SwitchOnStringDescriptor : SwitchUnitDescriptor<string>
|
||||
{
|
||||
public SwitchOnStringDescriptor(SwitchOnString unit) : base(unit) { }
|
||||
|
||||
protected override string GetLabelForOption(string option)
|
||||
{
|
||||
if (string.IsNullOrEmpty(option))
|
||||
{
|
||||
return "Null / Empty";
|
||||
}
|
||||
|
||||
return $"\"{option}\"";
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class SwitchUnitDescriptor<T> : UnitDescriptor<SwitchUnit<T>>
|
||||
{
|
||||
public SwitchUnitDescriptor(SwitchUnit<T> unit) : base(unit) { }
|
||||
|
||||
protected virtual string GetLabelForOption(T option)
|
||||
{
|
||||
return option.ToString();
|
||||
}
|
||||
|
||||
protected override void DefinedPort(IUnitPort port, UnitPortDescription description)
|
||||
{
|
||||
base.DefinedPort(port, description);
|
||||
|
||||
foreach (var branch in unit.branches)
|
||||
{
|
||||
if (branch.Value == port)
|
||||
{
|
||||
var option = branch.Key;
|
||||
|
||||
description.label = GetLabelForOption(option);
|
||||
description.summary = $"The action to execute if the selector has the value {GetLabelForOption(option)}.";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,109 @@
|
||||
#if PACKAGE_INPUT_SYSTEM_EXISTS
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Unity.VisualScripting.FullSerializer;
|
||||
using Unity.VisualScripting.InputSystem;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Inspector(typeof(InputAction))]
|
||||
public class InputActionInspector : Inspector
|
||||
{
|
||||
private readonly GraphReference m_Reference;
|
||||
private readonly OnInputSystemEvent m_InputSystemUnit;
|
||||
|
||||
public InputActionInspector(Metadata metadata, GraphReference reference, OnInputSystemEvent inputSystemUnit) : base(metadata)
|
||||
{
|
||||
m_Reference = reference;
|
||||
m_InputSystemUnit = inputSystemUnit;
|
||||
}
|
||||
|
||||
// Called by reflection from TypeUtility.Instantiate
|
||||
[UsedImplicitly]
|
||||
public InputActionInspector(Metadata metadata) : base(metadata)
|
||||
{
|
||||
}
|
||||
|
||||
protected override float GetHeight(float width, GUIContent label) => EditorGUIUtility.singleLineHeight;
|
||||
public override float GetAdaptiveWidth()
|
||||
{
|
||||
return Mathf.Max(100, metadata.value is InputAction action && action.name != null
|
||||
? (EditorStyles.popup.CalcSize(new GUIContent(action.name)).x + 1)
|
||||
: 0);
|
||||
}
|
||||
|
||||
protected override void OnGUI(Rect position, GUIContent label)
|
||||
{
|
||||
position = BeginLabeledBlock(metadata, position, label);
|
||||
|
||||
var togglePosition = position.VerticalSection(ref y, EditorGUIUtility.singleLineHeight);
|
||||
|
||||
if (m_InputSystemUnit == null)
|
||||
{
|
||||
EndBlock(metadata);
|
||||
return;
|
||||
}
|
||||
|
||||
var inputActionAsset = Flow.Predict<PlayerInput>(m_InputSystemUnit.Target, m_Reference)?.actions;
|
||||
if (!inputActionAsset)
|
||||
EditorGUI.LabelField(togglePosition, "No Actions found");
|
||||
else
|
||||
{
|
||||
var value = metadata.value is InputAction ? (InputAction)metadata.value : default;
|
||||
|
||||
int currentIndex = -1;
|
||||
if (value != null && value.id != default)
|
||||
{
|
||||
int i = 0;
|
||||
foreach (var playerInputAction in inputActionAsset)
|
||||
{
|
||||
if (playerInputAction.id == value.id)
|
||||
{
|
||||
currentIndex = i;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
var displayedOptions = Enumerable.Repeat(new GUIContent("<None>"), 1).Concat(inputActionAsset.Select(a => new GUIContent(a.name))).ToArray();
|
||||
var newIndex = EditorGUI.Popup(togglePosition, currentIndex + 1, displayedOptions);
|
||||
if (EndBlock(metadata) || ActionTypeHasChanged(currentIndex, value))
|
||||
{
|
||||
metadata.RecordUndo();
|
||||
if (newIndex == 0)
|
||||
metadata.value = default;
|
||||
else
|
||||
{
|
||||
var inputAction = inputActionAsset.ElementAt(newIndex - 1);
|
||||
|
||||
metadata.value =
|
||||
InputAction_DirectConverter.MakeInputActionWithId(inputAction.id.ToString(),
|
||||
inputAction.name, inputAction.expectedControlType, inputAction.type);
|
||||
m_InputSystemUnit.Analyser(m_Reference).isDirty = true;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
EndBlock(metadata);
|
||||
|
||||
bool ActionTypeHasChanged(int currentIndex, InputAction value)
|
||||
{
|
||||
try
|
||||
{
|
||||
// getting the total action count would be expensive, as it would need to be computed everytime
|
||||
return value?.type != inputActionAsset.ElementAt(currentIndex)?.type;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,52 @@
|
||||
#if PACKAGE_INPUT_SYSTEM_EXISTS
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using Unity.VisualScripting.InputSystem;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Widget(typeof(OnInputSystemEvent)), UsedImplicitly]
|
||||
public class InputSystemWidget : UnitWidget<OnInputSystemEvent>
|
||||
{
|
||||
public InputSystemWidget(FlowCanvas canvas, OnInputSystemEvent unit) : base(canvas, unit)
|
||||
{
|
||||
inputActionInspectorConstructor = metadata => new InputActionInspector(metadata, reference, unit);
|
||||
}
|
||||
|
||||
protected override NodeColorMix baseColor => NodeColor.Green;
|
||||
|
||||
private InputActionInspector nameInspector;
|
||||
|
||||
private Func<Metadata, InputActionInspector> inputActionInspectorConstructor;
|
||||
|
||||
public override Inspector GetPortInspector(IUnitPort port, Metadata metadata)
|
||||
{
|
||||
if (port == unit.InputAction)
|
||||
{
|
||||
InspectorProvider.instance.Renew(ref nameInspector, metadata, inputActionInspectorConstructor);
|
||||
return nameInspector;
|
||||
}
|
||||
|
||||
return base.GetPortInspector(port, metadata);
|
||||
}
|
||||
}
|
||||
|
||||
[Descriptor(typeof(OnInputSystemEvent)), UsedImplicitly]
|
||||
public class OnInputSystemButtonDescriptor : UnitDescriptor<OnInputSystemEvent>
|
||||
{
|
||||
public OnInputSystemButtonDescriptor(OnInputSystemEvent unit) : base(unit) {}
|
||||
|
||||
protected override void DefinedPort(IUnitPort port, UnitPortDescription description)
|
||||
{
|
||||
base.DefinedPort(port, description);
|
||||
|
||||
if (port == unit.Target)
|
||||
description.summary =
|
||||
"A player input component used to list available actions and find the referenced InputAction";
|
||||
if (port == unit.InputAction)
|
||||
description.summary =
|
||||
"An input action, either from the linked player input component or directly connected";
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,46 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Descriptor(typeof(Minimum<>))]
|
||||
[Descriptor(typeof(Maximum<>))]
|
||||
[Descriptor(typeof(Sum<>))]
|
||||
[Descriptor(typeof(Average<>))]
|
||||
[Descriptor(typeof(MergeDictionaries))]
|
||||
[Descriptor(typeof(Formula))]
|
||||
public class MultiInputUnitAlphabeticDescriptor : UnitDescriptor<IMultiInputUnit>
|
||||
{
|
||||
public MultiInputUnitAlphabeticDescriptor(IMultiInputUnit unit) : base(unit) { }
|
||||
|
||||
protected override void DefinedPort(IUnitPort port, UnitPortDescription description)
|
||||
{
|
||||
base.DefinedPort(port, description);
|
||||
|
||||
if (port is ValueInput)
|
||||
{
|
||||
var index = unit.multiInputs.IndexOf((ValueInput)port);
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
description.label = ((char)('A' + index)).ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[FuzzyOption(typeof(Minimum<>))]
|
||||
[FuzzyOption(typeof(Maximum<>))]
|
||||
[FuzzyOption(typeof(Sum<>))]
|
||||
[FuzzyOption(typeof(Average<>))]
|
||||
[FuzzyOption(typeof(MergeDictionaries))]
|
||||
[FuzzyOption(typeof(Formula))]
|
||||
public class MultiInputUnitAlphabeticOption : UnitOption<IMultiInputUnit>
|
||||
{
|
||||
public MultiInputUnitAlphabeticOption() : base() { }
|
||||
|
||||
public MultiInputUnitAlphabeticOption(IMultiInputUnit unit) : base(unit) { }
|
||||
|
||||
protected override bool ShowValueInputsInFooter()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Descriptor(typeof(CreateList))]
|
||||
[Descriptor(typeof(MergeLists))]
|
||||
public class MultiInputUnitNumericDescriptor : UnitDescriptor<IMultiInputUnit>
|
||||
{
|
||||
public MultiInputUnitNumericDescriptor(IMultiInputUnit unit) : base(unit) { }
|
||||
|
||||
protected override void DefinedPort(IUnitPort port, UnitPortDescription description)
|
||||
{
|
||||
base.DefinedPort(port, description);
|
||||
|
||||
if (port is ValueInput)
|
||||
{
|
||||
var index = unit.multiInputs.IndexOf((ValueInput)port);
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
description.label = index.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[FuzzyOption(typeof(CreateList))]
|
||||
[FuzzyOption(typeof(MergeLists))]
|
||||
public class MultiInputUnitNumericOption : UnitOption<IMultiInputUnit>
|
||||
{
|
||||
public MultiInputUnitNumericOption() : base() { }
|
||||
|
||||
public MultiInputUnitNumericOption(IMultiInputUnit unit) : base(unit) { }
|
||||
|
||||
protected override bool ShowValueInputsInFooter()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Analyser(typeof(GraphInput))]
|
||||
public class GraphInputAnalyser : UnitAnalyser<GraphInput>
|
||||
{
|
||||
public GraphInputAnalyser(GraphReference reference, GraphInput unit) : base(reference, unit) { }
|
||||
|
||||
protected override IEnumerable<Warning> Warnings()
|
||||
{
|
||||
foreach (var baseWarning in base.Warnings())
|
||||
{
|
||||
yield return baseWarning;
|
||||
}
|
||||
|
||||
if (unit.graph != null)
|
||||
{
|
||||
foreach (var definitionWarning in UnitPortDefinitionUtility.Warnings(unit.graph, LinqUtility.Concat<IUnitPortDefinition>(unit.graph.controlInputDefinitions, unit.graph.valueInputDefinitions)))
|
||||
{
|
||||
yield return definitionWarning;
|
||||
}
|
||||
|
||||
var inputs = unit.graph.units.Where(u => u is GraphInput).ToList();
|
||||
if (inputs.Count > 1)
|
||||
{
|
||||
var firstInput = inputs[0];
|
||||
if (unit != firstInput)
|
||||
{
|
||||
var graphName = string.IsNullOrEmpty(unit.graph.title) ? nameof(SuperUnit) : unit.graph.title;
|
||||
Debug.LogWarning($"Only one Input node can be used and will execute in {graphName}.");
|
||||
yield return Warning.Caution("Only one Input node can be used and will execute.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Descriptor(typeof(GraphInput))]
|
||||
public class GraphInputDescriptor : UnitDescriptor<GraphInput>
|
||||
{
|
||||
public GraphInputDescriptor(GraphInput unit) : base(unit) { }
|
||||
|
||||
protected override void DefinedPort(IUnitPort port, UnitPortDescription description)
|
||||
{
|
||||
base.DefinedPort(port, description);
|
||||
|
||||
var definition = unit.graph.validPortDefinitions.OfType<IUnitInputPortDefinition>().SingleOrDefault(d => d.key == port.key);
|
||||
|
||||
if (definition != null)
|
||||
{
|
||||
description.label = definition.Label();
|
||||
description.summary = definition.summary;
|
||||
|
||||
if (definition.hideLabel)
|
||||
{
|
||||
description.showLabel = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,64 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Inspector(typeof(GraphInput))]
|
||||
public class GraphInputInspector : Inspector
|
||||
{
|
||||
public GraphInputInspector(Metadata metadata) : base(metadata) { }
|
||||
|
||||
private Metadata graphMetadata => metadata[nameof(GraphInput.graph)];
|
||||
private Metadata controlInputDefinitionsMetadata => graphMetadata[nameof(FlowGraph.controlInputDefinitions)];
|
||||
private Metadata valueInputDefinitionsMetadata => graphMetadata[nameof(FlowGraph.valueInputDefinitions)];
|
||||
|
||||
protected override float GetHeight(float width, GUIContent label)
|
||||
{
|
||||
var height = 0f;
|
||||
|
||||
if (graphMetadata.value != null)
|
||||
{
|
||||
height += GetControlInputDefinitionsHeight(width);
|
||||
|
||||
height += EditorGUIUtility.standardVerticalSpacing;
|
||||
|
||||
height += GetValueInputDefinitionsHeight(width);
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
protected override void OnGUI(Rect position, GUIContent label)
|
||||
{
|
||||
BeginLabeledBlock(metadata, position, label);
|
||||
|
||||
if (graphMetadata.value != null)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
LudiqGUI.Inspector(controlInputDefinitionsMetadata, position.VerticalSection(ref y, GetControlInputDefinitionsHeight(position.width)));
|
||||
|
||||
y += EditorGUIUtility.standardVerticalSpacing;
|
||||
|
||||
LudiqGUI.Inspector(valueInputDefinitionsMetadata, position.VerticalSection(ref y, GetValueInputDefinitionsHeight(position.width)));
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
((FlowGraph)graphMetadata.value).PortDefinitionsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
EndBlock(metadata);
|
||||
}
|
||||
|
||||
private float GetControlInputDefinitionsHeight(float width)
|
||||
{
|
||||
return LudiqGUI.GetInspectorHeight(this, controlInputDefinitionsMetadata, width);
|
||||
}
|
||||
|
||||
private float GetValueInputDefinitionsHeight(float width)
|
||||
{
|
||||
return LudiqGUI.GetInspectorHeight(this, valueInputDefinitionsMetadata, width);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Widget(typeof(GraphInput))]
|
||||
public sealed class GraphInputWidget : UnitWidget<GraphInput>
|
||||
{
|
||||
public GraphInputWidget(FlowCanvas canvas, GraphInput unit) : base(canvas, unit) { }
|
||||
|
||||
protected override NodeColorMix baseColor => NodeColorMix.TealReadable;
|
||||
}
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Analyser(typeof(GraphOutput))]
|
||||
public class GraphOutputAnalyser : UnitAnalyser<GraphOutput>
|
||||
{
|
||||
public GraphOutputAnalyser(GraphReference reference, GraphOutput unit) : base(reference, unit) { }
|
||||
|
||||
protected override IEnumerable<Warning> Warnings()
|
||||
{
|
||||
foreach (var baseWarning in base.Warnings())
|
||||
{
|
||||
yield return baseWarning;
|
||||
}
|
||||
|
||||
if (unit.graph != null)
|
||||
{
|
||||
foreach (var definitionWarning in UnitPortDefinitionUtility.Warnings(unit.graph, LinqUtility.Concat<IUnitPortDefinition>(unit.graph.controlOutputDefinitions, unit.graph.valueOutputDefinitions)))
|
||||
{
|
||||
yield return definitionWarning;
|
||||
}
|
||||
|
||||
if (unit.graph.units.Count(unit => unit is GraphOutput) > 1)
|
||||
{
|
||||
yield return Warning.Caution("Multiple output units in the same graph. Only one of them will be used.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Descriptor(typeof(GraphOutput))]
|
||||
public class GraphOutputDescriptor : UnitDescriptor<GraphOutput>
|
||||
{
|
||||
public GraphOutputDescriptor(GraphOutput unit) : base(unit) { }
|
||||
|
||||
protected override void DefinedPort(IUnitPort port, UnitPortDescription description)
|
||||
{
|
||||
base.DefinedPort(port, description);
|
||||
|
||||
var definition = unit.graph.validPortDefinitions.OfType<IUnitOutputPortDefinition>().SingleOrDefault(d => d.key == port.key);
|
||||
|
||||
if (definition != null)
|
||||
{
|
||||
description.label = definition.Label();
|
||||
description.summary = definition.summary;
|
||||
|
||||
if (definition.hideLabel)
|
||||
{
|
||||
description.showLabel = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,64 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Inspector(typeof(GraphOutput))]
|
||||
public class GraphOutputInspector : Inspector
|
||||
{
|
||||
public GraphOutputInspector(Metadata metadata) : base(metadata) { }
|
||||
|
||||
private Metadata graphMetadata => metadata[nameof(GraphOutput.graph)];
|
||||
private Metadata controlOutputDefinitionsMetadata => graphMetadata[nameof(FlowGraph.controlOutputDefinitions)];
|
||||
private Metadata valueOutputDefinitionsMetadata => graphMetadata[nameof(FlowGraph.valueOutputDefinitions)];
|
||||
|
||||
protected override float GetHeight(float width, GUIContent label)
|
||||
{
|
||||
var height = 0f;
|
||||
|
||||
if (graphMetadata.value != null)
|
||||
{
|
||||
height += GetControlOutputDefinitionsHeight(width);
|
||||
|
||||
height += EditorGUIUtility.standardVerticalSpacing;
|
||||
|
||||
height += GetValueOutputDefinitionsHeight(width);
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
protected override void OnGUI(Rect position, GUIContent label)
|
||||
{
|
||||
BeginLabeledBlock(metadata, position, label);
|
||||
|
||||
if (graphMetadata.value != null)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
LudiqGUI.Inspector(controlOutputDefinitionsMetadata, position.VerticalSection(ref y, GetControlOutputDefinitionsHeight(position.width)));
|
||||
|
||||
y += EditorGUIUtility.standardVerticalSpacing;
|
||||
|
||||
LudiqGUI.Inspector(valueOutputDefinitionsMetadata, position.VerticalSection(ref y, GetValueOutputDefinitionsHeight(position.width)));
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
((FlowGraph)graphMetadata.value).PortDefinitionsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
EndBlock(metadata);
|
||||
}
|
||||
|
||||
private float GetControlOutputDefinitionsHeight(float width)
|
||||
{
|
||||
return LudiqGUI.GetInspectorHeight(this, controlOutputDefinitionsMetadata, width);
|
||||
}
|
||||
|
||||
private float GetValueOutputDefinitionsHeight(float width)
|
||||
{
|
||||
return LudiqGUI.GetInspectorHeight(this, valueOutputDefinitionsMetadata, width);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Widget(typeof(GraphOutput))]
|
||||
public sealed class GraphOutputWidget : UnitWidget<GraphOutput>
|
||||
{
|
||||
public GraphOutputWidget(FlowCanvas canvas, GraphOutput unit) : base(canvas, unit) { }
|
||||
|
||||
protected override NodeColorMix baseColor => NodeColorMix.TealReadable;
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityObject = UnityEngine.Object;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Analyser(typeof(INesterUnit))]
|
||||
public class NesterUnitAnalyser<TNesterUnit> : UnitAnalyser<TNesterUnit> where TNesterUnit : class, INesterUnit
|
||||
{
|
||||
public NesterUnitAnalyser(GraphReference reference, TNesterUnit unit) : base(reference, unit) { }
|
||||
|
||||
protected override IEnumerable<Warning> Warnings()
|
||||
{
|
||||
foreach (var baseWarning in base.Warnings())
|
||||
{
|
||||
yield return baseWarning;
|
||||
}
|
||||
|
||||
if (unit.childGraph == null)
|
||||
{
|
||||
yield return Warning.Caution("Missing nested graph.");
|
||||
}
|
||||
|
||||
if (unit.nest.hasBackgroundEmbed)
|
||||
{
|
||||
yield return Warning.Caution("Background embed graph detected.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
using UnityObject = UnityEngine.Object;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Descriptor(typeof(INesterUnit))]
|
||||
public class NesterUnitDescriptor<TNesterUnit> : UnitDescriptor<TNesterUnit> where TNesterUnit : class, INesterUnit
|
||||
{
|
||||
public NesterUnitDescriptor(TNesterUnit unit) : base(unit) { }
|
||||
|
||||
[RequiresUnityAPI]
|
||||
protected override string DefinedTitle()
|
||||
{
|
||||
return GraphNesterDescriptor.Title(unit);
|
||||
}
|
||||
|
||||
[RequiresUnityAPI]
|
||||
protected override string DefinedSummary()
|
||||
{
|
||||
return GraphNesterDescriptor.Summary(unit);
|
||||
}
|
||||
|
||||
[RequiresUnityAPI]
|
||||
protected override string DefinedShortTitle()
|
||||
{
|
||||
return DefinedTitle();
|
||||
}
|
||||
|
||||
[RequiresUnityAPI]
|
||||
protected override string DefinedSurtitle()
|
||||
{
|
||||
var hasCurrentTitle = !StringUtility.IsNullOrWhiteSpace(unit.nest.graph?.title);
|
||||
var hasMacroTitle = unit.nest.source == GraphSource.Macro && (UnityObject)unit.nest.macro != null;
|
||||
|
||||
if (hasCurrentTitle || hasMacroTitle)
|
||||
{
|
||||
return unit.GetType().HumanName();
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Editor(typeof(INesterUnit))]
|
||||
public class NesterUnitEditor : UnitEditor
|
||||
{
|
||||
public NesterUnitEditor(Metadata metadata) : base(metadata) { }
|
||||
|
||||
private Metadata nestMetadata => metadata[nameof(INesterUnit.nest)];
|
||||
|
||||
private Metadata graphMetadata => nestMetadata[nameof(IGraphNest.graph)];
|
||||
|
||||
protected override GraphReference headerReference => reference.ChildReference((INesterUnit)metadata.value, false);
|
||||
|
||||
protected override Metadata headerTitleMetadata => graphMetadata[nameof(IGraph.title)];
|
||||
|
||||
protected override Metadata headerSummaryMetadata => graphMetadata[nameof(IGraph.summary)];
|
||||
|
||||
protected override float GetInspectorHeight(float width)
|
||||
{
|
||||
return LudiqGUI.GetEditorHeight(this, nestMetadata, width);
|
||||
}
|
||||
|
||||
protected override void OnInspectorGUI(Rect position)
|
||||
{
|
||||
LudiqGUI.Editor(nestMetadata, position);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
using UnityObject = UnityEngine.Object;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[FuzzyOption(typeof(INesterUnit))]
|
||||
public class NesterUnitOption<TNesterUnit> : UnitOption<TNesterUnit> where TNesterUnit : INesterUnit
|
||||
{
|
||||
public NesterUnitOption() : base() { }
|
||||
|
||||
public NesterUnitOption(TNesterUnit unit) : base(unit) { }
|
||||
|
||||
// TODO: Favoritable
|
||||
public override bool favoritable => false;
|
||||
|
||||
protected override string Label(bool human)
|
||||
{
|
||||
return UnityAPI.Await(() =>
|
||||
{
|
||||
var macro = (UnityObject)unit.nest.macro;
|
||||
|
||||
if (macro != null)
|
||||
{
|
||||
return macro.name;
|
||||
}
|
||||
else
|
||||
{
|
||||
return unit.GetType().HumanName();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class NestrerUnitWidget<TNesterUnit> : UnitWidget<TNesterUnit>
|
||||
where TNesterUnit : class, INesterUnit
|
||||
{
|
||||
public NestrerUnitWidget(FlowCanvas canvas, TNesterUnit unit) : base(canvas, unit) { }
|
||||
|
||||
protected override IEnumerable<DropdownOption> contextOptions
|
||||
{
|
||||
get
|
||||
{
|
||||
var childReference = reference.ChildReference(unit, false);
|
||||
|
||||
if (childReference != null)
|
||||
{
|
||||
yield return new DropdownOption((Action)(() => window.reference = childReference), "Open");
|
||||
yield return new DropdownOption((Action)(() => GraphWindow.OpenTab(childReference)), "Open in new window");
|
||||
}
|
||||
|
||||
foreach (var baseOption in base.contextOptions)
|
||||
{
|
||||
yield return baseOption;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDoubleClick()
|
||||
{
|
||||
if (unit.graph.zoom == 1)
|
||||
{
|
||||
var childReference = reference.ChildReference(unit, false);
|
||||
|
||||
if (childReference != null)
|
||||
{
|
||||
if (e.ctrlOrCmd)
|
||||
{
|
||||
GraphWindow.OpenTab(childReference);
|
||||
}
|
||||
else
|
||||
{
|
||||
window.reference = childReference;
|
||||
}
|
||||
}
|
||||
|
||||
e.Use();
|
||||
}
|
||||
else
|
||||
{
|
||||
base.OnDoubleClick();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Descriptor(typeof(SuperUnit))]
|
||||
public class SuperUnitDescriptor : NesterUnitDescriptor<SuperUnit>
|
||||
{
|
||||
public SuperUnitDescriptor(SuperUnit unit) : base(unit) { }
|
||||
|
||||
protected override void DefinedPort(IUnitPort port, UnitPortDescription description)
|
||||
{
|
||||
base.DefinedPort(port, description);
|
||||
|
||||
if (unit.graph == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var definition = unit.nest.graph.validPortDefinitions.SingleOrDefault(d => d.key == port.key);
|
||||
|
||||
if (definition != null)
|
||||
{
|
||||
description.label = definition.Label();
|
||||
description.summary = definition.summary;
|
||||
|
||||
if (definition.hideLabel)
|
||||
{
|
||||
description.showLabel = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Editor(typeof(SuperUnit))]
|
||||
public sealed class SuperUnitEditor : NesterUnitEditor
|
||||
{
|
||||
public SuperUnitEditor(Metadata metadata) : base(metadata) { }
|
||||
}
|
||||
}
|
@@ -0,0 +1,59 @@
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Widget(typeof(SuperUnit))]
|
||||
public class SuperUnitWidget : NestrerUnitWidget<SuperUnit>, IDragAndDropHandler
|
||||
{
|
||||
public SuperUnitWidget(FlowCanvas canvas, SuperUnit unit) : base(canvas, unit) { }
|
||||
|
||||
protected override NodeColorMix baseColor
|
||||
{
|
||||
get
|
||||
{
|
||||
// TODO: Move to descriptor for optimization
|
||||
using (var recursion = Recursion.New(1))
|
||||
{
|
||||
if (unit.nest.graph?.GetUnitsRecursive(recursion).OfType<IEventUnit>().Any() ?? false)
|
||||
{
|
||||
return NodeColor.Green;
|
||||
}
|
||||
}
|
||||
|
||||
return base.baseColor;
|
||||
}
|
||||
}
|
||||
|
||||
public DragAndDropVisualMode dragAndDropVisualMode => DragAndDropVisualMode.Generic;
|
||||
|
||||
public bool AcceptsDragAndDrop()
|
||||
{
|
||||
return DragAndDropUtility.Is<ScriptGraphAsset>() && FlowDragAndDropUtility.AcceptsScript(graph);
|
||||
}
|
||||
|
||||
public void PerformDragAndDrop()
|
||||
{
|
||||
UndoUtility.RecordEditedObject("Drag & Drop Macro");
|
||||
unit.nest.source = GraphSource.Macro;
|
||||
unit.nest.macro = DragAndDropUtility.Get<ScriptGraphAsset>();
|
||||
unit.nest.embed = null;
|
||||
unit.Define();
|
||||
GUI.changed = true;
|
||||
}
|
||||
|
||||
public void UpdateDragAndDrop()
|
||||
{
|
||||
}
|
||||
|
||||
public void DrawDragAndDropPreview()
|
||||
{
|
||||
GraphGUI.DrawDragAndDropPreviewLabel(new Vector2(edgePosition.x, outerPosition.yMax), "Replace with: " + DragAndDropUtility.Get<ScriptGraphAsset>().name, typeof(ScriptGraphAsset).Icon());
|
||||
}
|
||||
|
||||
public void ExitDragAndDrop()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,51 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public static class UnitPortDefinitionUtility
|
||||
{
|
||||
public static string Label(this IUnitPortDefinition definition)
|
||||
{
|
||||
return StringUtility.FallbackWhitespace(definition.label, definition.key?.Filter(symbols: false, punctuation: false).Prettify() ?? "?");
|
||||
}
|
||||
|
||||
public static IEnumerable<Warning> Warnings(FlowGraph graph, IEnumerable<IUnitPortDefinition> definitions = null)
|
||||
{
|
||||
if (definitions == null)
|
||||
{
|
||||
definitions = LinqUtility.Concat<IUnitPortDefinition>(graph.controlInputDefinitions,
|
||||
graph.controlOutputDefinitions,
|
||||
graph.valueInputDefinitions,
|
||||
graph.valueOutputDefinitions);
|
||||
}
|
||||
|
||||
var hasDuplicate = definitions.DistinctBy(d => d.key).Count() != definitions.Count();
|
||||
|
||||
if (hasDuplicate)
|
||||
{
|
||||
yield return Warning.Caution("Some port definitions with non-unique keys are currently ignored.");
|
||||
}
|
||||
|
||||
foreach (var definition in definitions)
|
||||
{
|
||||
if (!definition.isValid)
|
||||
{
|
||||
yield return InvalidWarning(definition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Warning InvalidWarning(IUnitPortDefinition definition)
|
||||
{
|
||||
if (!StringUtility.IsNullOrWhiteSpace(definition.label))
|
||||
{
|
||||
return Warning.Caution($"{definition.GetType().HumanName().ToLower().FirstCharacterToUpper()} '{definition.label}' is not properly configured and is currently ignored.");
|
||||
}
|
||||
else
|
||||
{
|
||||
return Warning.Caution($"A {definition.GetType().HumanName().ToLower()} with incomplete configuration is currently ignored.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Descriptor(typeof(WaitForFlow))]
|
||||
public class WaitForFlowDescriptor : UnitDescriptor<WaitForFlow>
|
||||
{
|
||||
public WaitForFlowDescriptor(WaitForFlow unit) : base(unit) { }
|
||||
|
||||
protected override void DefinedPort(IUnitPort port, UnitPortDescription description)
|
||||
{
|
||||
base.DefinedPort(port, description);
|
||||
|
||||
if (port is ControlInput && unit.awaitedInputs.Contains((ControlInput)port))
|
||||
{
|
||||
description.showLabel = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[FuzzyOption(typeof(GetVariable))]
|
||||
public class GetVariableOption : UnifiedVariableUnitOption<GetVariable>
|
||||
{
|
||||
[Obsolete(Serialization.ConstructorWarning)]
|
||||
public GetVariableOption() : base() { }
|
||||
|
||||
public GetVariableOption(VariableKind kind, string defaultName = null) : base(kind, defaultName) { }
|
||||
|
||||
protected override string NamedLabel(bool human)
|
||||
{
|
||||
return $"Get {name}";
|
||||
}
|
||||
|
||||
protected override string UnnamedLabel(bool human)
|
||||
{
|
||||
return $"Get {kind} Variable";
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[FuzzyOption(typeof(IsVariableDefined))]
|
||||
public class IsVariableDefinedOption : UnifiedVariableUnitOption<IsVariableDefined>
|
||||
{
|
||||
[Obsolete(Serialization.ConstructorWarning)]
|
||||
public IsVariableDefinedOption() : base() { }
|
||||
|
||||
public IsVariableDefinedOption(VariableKind kind, string defaultName = null) : base(kind, defaultName) { }
|
||||
|
||||
protected override string NamedLabel(bool human)
|
||||
{
|
||||
return $"{kind} Has {name} Variable";
|
||||
}
|
||||
|
||||
protected override string UnnamedLabel(bool human)
|
||||
{
|
||||
return $"{kind} Has Variable";
|
||||
}
|
||||
|
||||
public override string SearchResultLabel(string query)
|
||||
{
|
||||
return SearchUtility.HighlightQuery(haystack, query);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[FuzzyOption(typeof(GetVariableUnit))]
|
||||
public class GetVariableUnitOption<TVariableUnit> : VariableUnitOption<TVariableUnit> where TVariableUnit : GetVariableUnit
|
||||
{
|
||||
public GetVariableUnitOption() : base() { }
|
||||
|
||||
public GetVariableUnitOption(TVariableUnit unit) : base(unit) { }
|
||||
|
||||
public override string Kind()
|
||||
{
|
||||
return base.Kind().TrimStart("Get ");
|
||||
}
|
||||
|
||||
protected override string DefaultNameLabel()
|
||||
{
|
||||
return $"Get {unit.defaultName}";
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[FuzzyOption(typeof(IsVariableDefinedUnit))]
|
||||
public class IsVariableDefinedUnitOption<TVariableUnit> : VariableUnitOption<TVariableUnit> where TVariableUnit : IsVariableDefinedUnit
|
||||
{
|
||||
public IsVariableDefinedUnitOption() : base() { }
|
||||
|
||||
public IsVariableDefinedUnitOption(TVariableUnit unit) : base(unit) { }
|
||||
|
||||
public override string Kind()
|
||||
{
|
||||
return base.Kind().TrimStart("Is ").TrimEnd(" Defined");
|
||||
}
|
||||
|
||||
protected override string DefaultNameLabel()
|
||||
{
|
||||
return $"Is {unit.defaultName} Defined";
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[FuzzyOption(typeof(SetVariableUnit))]
|
||||
public class SetVariableUnitOption<TVariableUnit> : VariableUnitOption<TVariableUnit> where TVariableUnit : SetVariableUnit
|
||||
{
|
||||
public SetVariableUnitOption() : base() { }
|
||||
|
||||
public SetVariableUnitOption(TVariableUnit unit) : base(unit) { }
|
||||
|
||||
public override string Kind()
|
||||
{
|
||||
return base.Kind().TrimStart("Set ");
|
||||
}
|
||||
|
||||
protected override string DefaultNameLabel()
|
||||
{
|
||||
return $"Set {unit.defaultName}";
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
#pragma warning disable 618
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Descriptor(typeof(VariableUnit))]
|
||||
public class VariableUnitDescriptor<TVariableUnit> : UnitDescriptor<TVariableUnit> where TVariableUnit : VariableUnit
|
||||
{
|
||||
public VariableUnitDescriptor(TVariableUnit unit) : base(unit) { }
|
||||
|
||||
protected bool hasDefaultName => !string.IsNullOrEmpty(unit.defaultName);
|
||||
|
||||
protected override string DefinedSummary()
|
||||
{
|
||||
var summary = base.DefinedSummary();
|
||||
|
||||
if (hasDefaultName)
|
||||
{
|
||||
summary += $" (\"{unit.defaultName}\")";
|
||||
}
|
||||
|
||||
return summary;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,72 @@
|
||||
#pragma warning disable 618
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public interface IVariableUnitOption
|
||||
{
|
||||
string Kind();
|
||||
}
|
||||
|
||||
public abstract class VariableUnitOption<TVariableUnit> : UnitOption<TVariableUnit>, IVariableUnitOption where TVariableUnit : VariableUnit
|
||||
{
|
||||
protected VariableUnitOption() : base() { }
|
||||
|
||||
protected VariableUnitOption(TVariableUnit unit) : base(unit) { }
|
||||
|
||||
protected bool hasDefaultName => !string.IsNullOrEmpty(unit.defaultName);
|
||||
|
||||
protected override string FavoriteKey()
|
||||
{
|
||||
return $"{unit.GetType().FullName}${unit.defaultName}";
|
||||
}
|
||||
|
||||
private string DimmedKind()
|
||||
{
|
||||
return LudiqGUIUtility.DimString($" ({Kind()})");
|
||||
}
|
||||
|
||||
public virtual string Kind()
|
||||
{
|
||||
return unit.GetType().HumanName();
|
||||
}
|
||||
|
||||
protected virtual string DefaultNameLabel()
|
||||
{
|
||||
return unit.defaultName;
|
||||
}
|
||||
|
||||
protected override string Label(bool human)
|
||||
{
|
||||
if (hasDefaultName)
|
||||
{
|
||||
return DefaultNameLabel() + DimmedKind();
|
||||
}
|
||||
else
|
||||
{
|
||||
return base.Label(human);
|
||||
}
|
||||
}
|
||||
|
||||
protected override string Haystack(bool human)
|
||||
{
|
||||
if (hasDefaultName)
|
||||
{
|
||||
return DefaultNameLabel();
|
||||
}
|
||||
|
||||
return base.Haystack(human);
|
||||
}
|
||||
|
||||
public override string SearchResultLabel(string query)
|
||||
{
|
||||
if (hasDefaultName)
|
||||
{
|
||||
return base.SearchResultLabel(query) + DimmedKind();
|
||||
}
|
||||
else
|
||||
{
|
||||
return base.SearchResultLabel(query);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
#pragma warning disable 618
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Widget(typeof(VariableUnit))]
|
||||
public sealed class VariableUnitWidget : UnitWidget<VariableUnit>
|
||||
{
|
||||
public VariableUnitWidget(FlowCanvas canvas, VariableUnit unit) : base(canvas, unit) { }
|
||||
|
||||
protected override NodeColorMix baseColor => NodeColorMix.TealReadable;
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[FuzzyOption(typeof(SetVariable))]
|
||||
public class SetVariableOption : UnifiedVariableUnitOption<SetVariable>
|
||||
{
|
||||
[Obsolete(Serialization.ConstructorWarning)]
|
||||
public SetVariableOption() : base() { }
|
||||
|
||||
public SetVariableOption(VariableKind kind, string defaultName = null) : base(kind, defaultName) { }
|
||||
|
||||
protected override string NamedLabel(bool human)
|
||||
{
|
||||
return $"Set {name}";
|
||||
}
|
||||
|
||||
protected override string UnnamedLabel(bool human)
|
||||
{
|
||||
return $"Set {kind} Variable";
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Descriptor(typeof(UnifiedVariableUnit))]
|
||||
public class UnifiedVariableUnitDescriptor<TVariableUnit> : UnitDescriptor<TVariableUnit> where TVariableUnit : UnifiedVariableUnit
|
||||
{
|
||||
public UnifiedVariableUnitDescriptor(TVariableUnit unit) : base(unit) { }
|
||||
|
||||
protected override EditorTexture DefinedIcon()
|
||||
{
|
||||
return BoltCore.Icons.VariableKind(unit.kind);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public interface IUnifiedVariableUnitOption : IUnitOption
|
||||
{
|
||||
VariableKind kind { get; }
|
||||
string name { get; }
|
||||
}
|
||||
|
||||
public abstract class UnifiedVariableUnitOption<TVariableUnit> : UnitOption<TVariableUnit>, IUnifiedVariableUnitOption where TVariableUnit : UnifiedVariableUnit
|
||||
{
|
||||
[Obsolete(Serialization.ConstructorWarning)]
|
||||
protected UnifiedVariableUnitOption() : base() { }
|
||||
|
||||
protected UnifiedVariableUnitOption(VariableKind kind, string defaultName = null) : base()
|
||||
{
|
||||
this.kind = kind;
|
||||
this.name = defaultName;
|
||||
this.unit = (TVariableUnit)Activator.CreateInstance(typeof(TVariableUnit));
|
||||
FillFromUnit();
|
||||
}
|
||||
|
||||
public override void Deserialize(UnitOptionRow row)
|
||||
{
|
||||
base.Deserialize(row);
|
||||
|
||||
kind = (VariableKind)Enum.Parse(typeof(VariableKind), row.tag1);
|
||||
name = row.tag2;
|
||||
}
|
||||
|
||||
public override UnitOptionRow Serialize()
|
||||
{
|
||||
var row = base.Serialize();
|
||||
|
||||
row.tag1 = kind.ToString();
|
||||
row.tag2 = name;
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
public string name { get; private set; }
|
||||
|
||||
public VariableKind kind { get; private set; }
|
||||
|
||||
public bool hasName => !string.IsNullOrEmpty(name);
|
||||
|
||||
protected override string FavoriteKey()
|
||||
{
|
||||
return $"{unit.GetType().FullName}${name}";
|
||||
}
|
||||
|
||||
private string DimmedKind()
|
||||
{
|
||||
return LudiqGUIUtility.DimString($" ({kind})");
|
||||
}
|
||||
|
||||
protected abstract string NamedLabel(bool human);
|
||||
|
||||
protected abstract string UnnamedLabel(bool human);
|
||||
|
||||
protected override string Label(bool human)
|
||||
{
|
||||
if (hasName)
|
||||
{
|
||||
return NamedLabel(human);
|
||||
}
|
||||
else
|
||||
{
|
||||
return UnnamedLabel(human);
|
||||
}
|
||||
}
|
||||
|
||||
public override string SearchResultLabel(string query)
|
||||
{
|
||||
if (hasName)
|
||||
{
|
||||
return base.SearchResultLabel(query) + DimmedKind();
|
||||
}
|
||||
else
|
||||
{
|
||||
return base.SearchResultLabel(query);
|
||||
}
|
||||
}
|
||||
|
||||
protected override EditorTexture Icon()
|
||||
{
|
||||
return BoltCore.Icons.VariableKind(kind);
|
||||
}
|
||||
|
||||
public override void PreconfigureUnit(TVariableUnit unit)
|
||||
{
|
||||
unit.kind = kind;
|
||||
|
||||
if (hasName)
|
||||
{
|
||||
unit.name.SetDefaultValue(name);
|
||||
}
|
||||
|
||||
unit.Define(); // Force redefine, because we changed the kind
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Widget(typeof(UnifiedVariableUnit))]
|
||||
public sealed class UnifiedVariableUnitWidget : UnitWidget<UnifiedVariableUnit>
|
||||
{
|
||||
public UnifiedVariableUnitWidget(FlowCanvas canvas, UnifiedVariableUnit unit) : base(canvas, unit)
|
||||
{
|
||||
nameInspectorConstructor = (metadata) => new VariableNameInspector(metadata, GetNameSuggestions);
|
||||
}
|
||||
|
||||
protected override NodeColorMix baseColor => NodeColorMix.TealReadable;
|
||||
|
||||
private VariableNameInspector nameInspector;
|
||||
private Func<Metadata, VariableNameInspector> nameInspectorConstructor;
|
||||
|
||||
public override Inspector GetPortInspector(IUnitPort port, Metadata metadata)
|
||||
{
|
||||
if (port == unit.name)
|
||||
{
|
||||
// This feels so hacky. The real holy grail here would be to support attribute decorators like Unity does.
|
||||
InspectorProvider.instance.Renew(ref nameInspector, metadata, nameInspectorConstructor);
|
||||
|
||||
return nameInspector;
|
||||
}
|
||||
|
||||
return base.GetPortInspector(port, metadata);
|
||||
}
|
||||
|
||||
private IEnumerable<string> GetNameSuggestions()
|
||||
{
|
||||
return EditorVariablesUtility.GetVariableNameSuggestions(unit.kind, reference);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[FuzzyOption(typeof(VariableKind))]
|
||||
public class VariableKindOption : DocumentedOption<VariableKind>
|
||||
{
|
||||
public VariableKindOption(VariableKind kind)
|
||||
{
|
||||
value = kind;
|
||||
label = kind.HumanName();
|
||||
UnityAPI.Async(() => icon = BoltCore.Icons.VariableKind(kind));
|
||||
documentation = kind.Documentation();
|
||||
zoom = true;
|
||||
parentOnly = true;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user