Initial Commit
This commit is contained in:
parent
53eb92e9af
commit
270ab7d11f
15341 changed files with 700234 additions and 0 deletions
|
@ -0,0 +1 @@
|
|||
# For dev package builds ignore the following
|
|
@ -0,0 +1,6 @@
|
|||
# For release package builds ignore the following
|
||||
Samples/**
|
||||
Samples.meta
|
||||
Samples~/**
|
||||
Samples~.meta
|
||||
.npmignore.dev
|
|
@ -0,0 +1,87 @@
|
|||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||
## [1.5.2] - 2021-05-05
|
||||
### Changed
|
||||
- User interface updated
|
||||
- Names in different UI elements made to be more consistent with new naming schemes
|
||||
|
||||
## [1.5.1] - 2021-02-23
|
||||
### Added
|
||||
- Warn the user when an Input System Package event is referencing an action of the wrong type for that event
|
||||
- A warning is raised when adding more than one Input unit in a SuperUnit
|
||||
- "Open" inspector button and double clicking a graph in the project browser now opens the visual scripting editor
|
||||
### Fixed
|
||||
- Fixed "Restore to Defaults" buttons in the Project Settings window
|
||||
- Fixed ThreadAbortException when entering Play Mode while searching in the Fuzzy Finder
|
||||
- Fixed Visual Scripting Preferences being searchable [BOLT-1218](https://issuetracker.unity3d.com/issues/visual-scripting-preferences-are-not-searchable-when-using-search-in-the-preferences-window)
|
||||
- Fixed ScalarAdd unit migration from 1.4.13 to 1.4.14 and above
|
||||
- Fixed Open the graph window no longer causes Unity UI stop processing mouse click [BOLT-1159](https://issuetracker.unity3d.com/product/unity/issues/guid/BOLT-1159),
|
||||
- Fixed Fuzzy finder no longer blinks when trying to add a node [BOLT-1157](https://issuetracker.unity3d.com/product/unity/issues/guid/BOLT-1157),
|
||||
- Fixed Fuzzy search no longer drops keyboard inputs and respond slowly [BOLT-1214](https://issuetracker.unity3d.com/product/unity/issues/guid/BOLT-1214),
|
||||
- Fixed Fuzzy finder search window no longer remains above all other windows [BOLT-1197](https://issuetracker.unity3d.com/product/unity/issues/guid/BOLT-1197)"
|
||||
- Fixed Dropdown icon is not clipped with TextField under "Get Variable"
|
||||
- Fixed Scale groups when zoom is not at 1x
|
||||
- Fixed graph getting corrupted when adding "Get Action Map" unit
|
||||
- Fixed node description being sometimes clipped
|
||||
- Fixed warnings overflow in the console when deleting and adding a boolean variable in the blackboard
|
||||
- Fixed warnings when entering play mode when the "Script Changes While Playing" is set to Recompile And Continue Playing
|
||||
- Fixed resize cursor rect on group when graph window is zoomed
|
||||
- Fixed VisualScripting.Generated folder is removed when removing the VisualScripting package.
|
||||
- Fixed error when executing "Fix Missing Scripts" in a HDRP project
|
||||
- Visual Scripting Preferences spacing has been adjusted to avoid overlaps
|
||||
- Fixed rendering of inactive ObjectFields
|
||||
- Fixed sidebar (graph inspector/blackboard) resize when a vertical scrollbar is needed
|
||||
- Fixed variable type reset to Enum when changing from Enum to GameObject when both Blackbaord and Variables inspector are displayed
|
||||
- Help button in the visual scripting Assets and Behaviours inspector now link to the package documentation.
|
||||
- FlowMachine type is now back in usable types.
|
||||
- Fixed GraphPointerException occurs when nesting graph within itself [BOLT-1257](https://issuetracker.unity3d.com/issues/visual-scripting-graphpointerexception-occurs-when-nesting-graph-within-itself)
|
||||
- Fixed RenamedFrom attribute does not function correctly on array references to a renamed type [BOLT-1149](https://issuetracker.unity3d.com/product/unity/issues/guid/BOLT-1149)
|
||||
- Fixed error message when custom inspectors are generated
|
||||
- Fixed missing succession for Cooldown. Output of Cooldown completed is treated as unentered. [BOLT-725](https://issuetracker.unity3d.com/issues/bolt-1-output-of-cooldown-completed-is-treated-as-unentered)
|
||||
- Fixed Object Variables tabs not updated when creating a Prefab
|
||||
- Fixed console errors when deleting a Prefab with a Visual Script
|
||||
- Fixed console errors when editing nested graphs during Play Mode
|
||||
|
||||
## [1.5.1-pre.3] - 2020-12-07
|
||||
### Added
|
||||
- Added Visual Scripting as built-in package as of Unity 2021.1
|
||||
- Added New Input System Support. You can import the Input System package, activate the back-end and regenerate units to use.
|
||||
- Added AOT Pre-Compile to automatically run when building AOT platforms
|
||||
- Improved UI for deprecated built-in nodes
|
||||
- Added automatic unit generation the first time the graph window is opened
|
||||
### Changed
|
||||
- Switched to delivering source instead of pre-built .NET 3/4 assemblies
|
||||
- Updated Documentation
|
||||
- Renamed assemblies to match Unity.VisualScripting naming scheme (Ex: Bolt.Core -> Unity.VisualScripting.Core)
|
||||
- Merged Ludiq.Core and Ludiq.Graphs into Unity.VisualScripting.Core
|
||||
- Moved Setup Wizard contents from pop-up on Editor startup to Player Settings. You can change the default settings from "Player Settings > Visual Scripting"
|
||||
- Renamed "Assembly Options" to "Node Library"
|
||||
- Renamed "Flow Graph" to "Script Graph"
|
||||
- Renamed "Flow Machine" to "Script Machine"
|
||||
- Renamed "Macro" graphs to "Graph" in machine source configuration and "GraphAsset" in Assets
|
||||
- Renamed "Control Input/Output" to "Trigger Input/Output"
|
||||
- Renamed "Value Input/Output" to "Data Input/Output"
|
||||
- Updated built-in nodes. The Fuzzy Finder still accepts earlier version names of nodes.
|
||||
- Renamed "Branch" node to "If"
|
||||
- Renamed "Self" node to "This"
|
||||
- Deprecated the previous Add unit. The Sum unit has been renamed to Add.
|
||||
- Updated Window Naming
|
||||
- Changed "Variables" window to "Blackboard"
|
||||
- Changed "Graph" window to "Script Graph" and "State Graph"
|
||||
- Updated Bolt Preferences
|
||||
- Renamed Bolt Preferences to "Visual Scripting"
|
||||
- Removed BoltEx
|
||||
- Moved settings previously accessed from "Window > Bolt" to preferences
|
||||
- Renamed Control Schemes from "Unity/Unreal" to "Default/Alternate" (Neither control scheme currently matches their respective editors' controls and will be updated in a future release)
|
||||
- Consolidated Graph editor, Blackboard and Graph Inspector into a single window
|
||||
- Updated Third-Party Notices
|
||||
### Fixed
|
||||
- Corrected UGUI event management to trickle down correctly when the hierarchy contains a Unity Message Listener [BOLT-2](https://issuetracker.unity3d.com/issues/bolt-1-unity-message-listener-blocks-proper-trickling-of-ugui-events-in-hierarchies)
|
||||
- Fixed backup failures with large projects [BOLT-10](https://issuetracker.unity3d.com/issues/bolt-1-backup-fails-to-complete)
|
||||
- Fixed "Null Reference" when opening the Graph Window for the first time [BOLT-996](https://issuetracker.unity3d.com/issues/nullreferenceexception-when-graph-window-is-opened-on-a-new-project)
|
||||
- Fixed IL2CPP build crash on startup [BOLT-1036](https://issuetracker.unity3d.com/issues/bolt-bolt-1-il2cpp-release-build-crashes-on-startup-when-there-is-at-least-1-node-present-in-a-graph)
|
||||
- Fixed IL2CPP issue around converting certain managed types [BOLT-8](https://issuetracker.unity3d.com/issues/bolt-1-il2cpp-encountered-a-managed-type-which-it-cannot-convert-ahead-of-time)
|
||||
- Fixed deserialization issues when undoing graphs with Wait nodes [BOLT-679](https://issuetracker.unity3d.com/issues/bolt-deserialization-error-and-nodes-missing-after-pressing-undo-when-update-coroutine-with-wait-node-is-present-in-graph)
|
||||
- Fixed "SelectOnEnum" node behaviour enums containing non-unique values e.g. "RuntimePlatform" [BOLT-688](https://issuetracker.unity3d.com/issues/select-on-enum-doesnt-work-with-the-runtimeplatform-enum)
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e943e3d5ede9d0848a8e889af1e6656c
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ee9f54d6cd5a17045a3f1c9877d4b7e6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
<<<<<<< HEAD:Package-Old/Bolt/Documentation/1. Introduction.meta
|
||||
guid: 3804c151c03f29547b6b564ccc05bde0
|
||||
=======
|
||||
guid: 3dfa3c8fac2134fdda65f882f5a1a014
|
||||
>>>>>>> [1010] Visual Script Project Settings UI Change:Packages/com.unity.bolt/VSSettingsProvider.meta
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,14 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class VSProjectSettingsProvider : Editor
|
||||
{
|
||||
[SettingsProvider]
|
||||
public static SettingsProvider CreateProjectSettingProvider()
|
||||
{
|
||||
return new VSProjectSettingsProviderView();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d6a0cc840e6084f62a3e3538f14bf3ce
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,97 @@
|
|||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
class VSProjectSettingsProviderView : SettingsProvider
|
||||
{
|
||||
private const string path = "Project/Visual Scripting";
|
||||
private const string title = "Visual Scripting";
|
||||
private const string titleGroup = "Generate Units";
|
||||
|
||||
VSSettingsAssembly vsSettingsAssembly;
|
||||
VSSettingsTypeOption vsSettingsTypeOption;
|
||||
VSSettingsCustomProperty vsSettingsCustomProperty;
|
||||
VSSettingsBackup vsSettingsBackup;
|
||||
VSSettingsScriptReferenceResolver vsSettingsScriptReferenceResolver;
|
||||
|
||||
VSSettingsUpdate vsSettingsUpdate;
|
||||
public VSProjectSettingsProviderView() : base(path, SettingsScope.Project)
|
||||
{
|
||||
label = title;
|
||||
}
|
||||
|
||||
private void CreateOptionsIfNeeded()
|
||||
{
|
||||
if (vsSettingsAssembly == null)
|
||||
{
|
||||
vsSettingsAssembly = new VSSettingsAssembly();
|
||||
}
|
||||
|
||||
if (vsSettingsTypeOption == null)
|
||||
{
|
||||
vsSettingsTypeOption = new VSSettingsTypeOption();
|
||||
}
|
||||
|
||||
if (vsSettingsCustomProperty == null)
|
||||
{
|
||||
vsSettingsCustomProperty = new VSSettingsCustomProperty();
|
||||
}
|
||||
|
||||
if (vsSettingsBackup == null)
|
||||
{
|
||||
vsSettingsBackup = new VSSettingsBackup();
|
||||
}
|
||||
|
||||
if (vsSettingsScriptReferenceResolver == null)
|
||||
{
|
||||
vsSettingsScriptReferenceResolver = new VSSettingsScriptReferenceResolver();
|
||||
}
|
||||
|
||||
if (vsSettingsUpdate == null)
|
||||
{
|
||||
vsSettingsUpdate = new VSSettingsUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGUI(string searchContext)
|
||||
{
|
||||
GUILayout.Space(5f);
|
||||
|
||||
GUILayout.Label(titleGroup, EditorStyles.boldLabel);
|
||||
|
||||
GUILayout.Space(10f);
|
||||
|
||||
// happens when opening unity with the settings window already opened. there's a delay until the singleton is assigned
|
||||
if (BoltCore.instance == null)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Loading Configuration...", MessageType.Info);
|
||||
return;
|
||||
}
|
||||
|
||||
CreateOptionsIfNeeded();
|
||||
|
||||
vsSettingsTypeOption.OnGUI();
|
||||
|
||||
GUILayout.Space(10f);
|
||||
|
||||
vsSettingsAssembly.OnGUI();
|
||||
|
||||
GUILayout.Space(10f);
|
||||
|
||||
vsSettingsCustomProperty.OnGUI();
|
||||
|
||||
GUILayout.Space(10f);
|
||||
|
||||
vsSettingsBackup.OnGUI();
|
||||
|
||||
GUILayout.Space(10f);
|
||||
|
||||
vsSettingsScriptReferenceResolver.OnGUI();
|
||||
|
||||
GUILayout.Space(10f);
|
||||
|
||||
vsSettingsUpdate.OnGUI();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4eea00f49056f4ee98c82b6923b44600
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,76 @@
|
|||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class VSSettingsAssembly
|
||||
{
|
||||
private const string completeLabel = "Regenerate Units";
|
||||
private PluginConfigurationItemMetadata assemblyOptionsMetadata;
|
||||
|
||||
private bool showAssembly = false;
|
||||
private const string titleAssembly = "Node Library";
|
||||
private const string descriptionAssembly = "Choose the assemblies in which you want to look for units.\n"
|
||||
+ "By default, all project and Unity assemblies are included.\n"
|
||||
+ "Unless you use a third-party plugin distributed as a DLL, you shouldn't need to change this.";
|
||||
public VSSettingsAssembly()
|
||||
{
|
||||
assemblyOptionsMetadata = BoltCore.Configuration.GetMetadata(nameof(BoltCoreConfiguration.assemblyOptions));
|
||||
}
|
||||
|
||||
static class Styles
|
||||
{
|
||||
public static readonly GUIStyle background;
|
||||
public static readonly GUIStyle defaultsButton;
|
||||
public static readonly float optionsWidth = 250;
|
||||
|
||||
static Styles()
|
||||
{
|
||||
background = new GUIStyle(LudiqStyles.windowBackground);
|
||||
background.padding = new RectOffset(20, 20, 20, 20);
|
||||
|
||||
defaultsButton = new GUIStyle("Button");
|
||||
defaultsButton.padding = new RectOffset(10, 10, 4, 4);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnGUI()
|
||||
{
|
||||
showAssembly = EditorGUILayout.Foldout(showAssembly, new GUIContent(titleAssembly, descriptionAssembly));
|
||||
|
||||
if (showAssembly)
|
||||
{
|
||||
GUILayout.BeginVertical(Styles.background, GUILayout.ExpandHeight(true));
|
||||
|
||||
float height = LudiqGUI.GetInspectorHeight(null, assemblyOptionsMetadata, Styles.optionsWidth, GUIContent.none);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
var position = GUILayoutUtility.GetRect(Styles.optionsWidth, height);
|
||||
|
||||
LudiqGUI.Inspector(assemblyOptionsMetadata, position, GUIContent.none);
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
assemblyOptionsMetadata.Save();
|
||||
Codebase.UpdateSettings();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Reset to Defaults", Styles.defaultsButton))
|
||||
{
|
||||
assemblyOptionsMetadata.Reset(true);
|
||||
assemblyOptionsMetadata.Save();
|
||||
}
|
||||
|
||||
LudiqGUI.EndVertical();
|
||||
}
|
||||
|
||||
if (GUILayout.Button(completeLabel, Styles.defaultsButton))
|
||||
{
|
||||
UnitBase.Rebuild();
|
||||
|
||||
EditorUtility.DisplayDialog("Visual Script", "Regenerate Units completed", "OK");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7cb1615bd41a3442a8aabbcb872046a3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,46 @@
|
|||
using System.Diagnostics;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class VSSettingsBackup
|
||||
{
|
||||
private const string title = "Backup Graphs";
|
||||
private const string buttonBackupLabel = "Create Backup";
|
||||
private const string buttonRestoreLabel = "Restore Backup";
|
||||
|
||||
public void OnGUI()
|
||||
{
|
||||
GUILayout.Space(5f);
|
||||
|
||||
GUILayout.Label(title, EditorStyles.boldLabel);
|
||||
|
||||
GUILayout.Space(5f);
|
||||
|
||||
if (GUILayout.Button(buttonBackupLabel, Styles.defaultsButton))
|
||||
{
|
||||
VSBackupUtility.Backup();
|
||||
|
||||
EditorUtility.DisplayDialog("Backup", "Backup completed successfully.", "OK");
|
||||
}
|
||||
|
||||
if (GUILayout.Button(buttonRestoreLabel, Styles.defaultsButton))
|
||||
{
|
||||
PathUtility.CreateDirectoryIfNeeded(Paths.backups);
|
||||
Process.Start(Paths.backups);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Styles
|
||||
{
|
||||
static Styles()
|
||||
{
|
||||
defaultsButton = new GUIStyle("Button");
|
||||
defaultsButton.padding = new RectOffset(10, 10, 4, 4);
|
||||
}
|
||||
|
||||
public static readonly GUIStyle defaultsButton;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
fileFormatVersion: 2
|
||||
<<<<<<< HEAD:Packages/com.unity.bolt/Editor/Bolt.Core/BoltGUI.cs.meta
|
||||
guid: 50455e66302b715488a9218e30b0ab24
|
||||
=======
|
||||
guid: 9b13d76d6b80b4b1ab4d0fac8c174df4
|
||||
>>>>>>> [1010] Visual Script Project Settings UI Change:Packages/com.unity.bolt/VSSettingsProvider/VSSettingsBackup.cs.meta
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,49 @@
|
|||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class VSSettingsCustomProperty
|
||||
{
|
||||
private const string title = "Custom Inspector Properties";
|
||||
private const string buttonLabel = "Generate";
|
||||
|
||||
public void OnGUI()
|
||||
{
|
||||
GUILayout.Space(5f);
|
||||
|
||||
GUILayout.Label(title, EditorStyles.boldLabel);
|
||||
|
||||
GUILayout.Space(5f);
|
||||
|
||||
string label = "Inspectors in Bolt plugins can handle many custom types besides Unity primites and objects. ";
|
||||
label += "However, to be compatible with your custom editor drawers, some additional property provider scripts must be generated. ";
|
||||
|
||||
GUILayout.BeginHorizontal(EditorStyles.helpBox);
|
||||
GUILayout.Label(EditorGUIUtility.IconContent("console.infoicon"), GUILayout.ExpandWidth(true));
|
||||
GUILayout.Box(label, EditorStyles.wordWrappedLabel);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (GUILayout.Button(buttonLabel, Styles.defaultsButton))
|
||||
{
|
||||
SerializedPropertyProviderProvider.instance.GenerateProviderScripts();
|
||||
EditorUtility.DisplayDialog("Custom Inspector Generation", "Custom inspector generation has completed successfully.", "OK");
|
||||
}
|
||||
}
|
||||
|
||||
public static class Styles
|
||||
{
|
||||
static Styles()
|
||||
{
|
||||
defaultsButton = new GUIStyle("Button");
|
||||
defaultsButton.padding = new RectOffset(10, 10, 4, 4);
|
||||
|
||||
regenerateLabel = new GUIStyle(EditorStyles.centeredGreyMiniLabel);
|
||||
regenerateLabel.wordWrap = true;
|
||||
}
|
||||
|
||||
public static readonly GUIStyle defaultsButton;
|
||||
public static readonly GUIStyle regenerateLabel;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7da9d8250917648728b856bfab5f1320
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "VSSettingsProvider",
|
||||
"references": [
|
||||
"Unity.VisualScripting.Core",
|
||||
"Unity.VisualScripting.Core.Editor",
|
||||
"Unity.VisualScripting.Flow",
|
||||
"Unity.VisualScripting.Flow.Editor",
|
||||
"Unity.VisualScripting.State"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2aa54ddaa48744e1caddee916e39805e
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,40 @@
|
|||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class VSSettingsScriptReferenceResolver
|
||||
{
|
||||
private const string title = "Script Reference Resolver";
|
||||
private const string buttonLabel = "Fix Missing Scripts";
|
||||
|
||||
public void OnGUI()
|
||||
{
|
||||
GUILayout.Space(5f);
|
||||
|
||||
GUILayout.Label(title, EditorStyles.boldLabel);
|
||||
|
||||
GUILayout.Space(5f);
|
||||
|
||||
if (GUILayout.Button(buttonLabel, Styles.defaultsButton))
|
||||
{
|
||||
ScriptReferenceResolver.Run();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Styles
|
||||
{
|
||||
static Styles()
|
||||
{
|
||||
defaultsButton = new GUIStyle("Button");
|
||||
defaultsButton.padding = new RectOffset(10, 10, 4, 4);
|
||||
|
||||
regenerateLabel = new GUIStyle(EditorStyles.centeredGreyMiniLabel);
|
||||
regenerateLabel.wordWrap = true;
|
||||
}
|
||||
|
||||
public static readonly GUIStyle defaultsButton;
|
||||
public static readonly GUIStyle regenerateLabel;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a8c0a3364f2ef4e42820eb87b5bdab69
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,68 @@
|
|||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class VSSettingsTypeOption
|
||||
{
|
||||
private readonly PluginConfigurationItemMetadata typeOptionsMetadata;
|
||||
|
||||
bool showTypeOption = false;
|
||||
private const string titleTypeOption = "Type Options";
|
||||
private const string descriptionTypeOption = "Choose the types you want to use for variables and units.\n"
|
||||
+ "MonoBehaviour types are always included.";
|
||||
static class Styles
|
||||
{
|
||||
public static readonly GUIStyle background;
|
||||
public static readonly GUIStyle defaultsButton;
|
||||
public static readonly float optionsWidth = 250;
|
||||
|
||||
static Styles()
|
||||
{
|
||||
background = new GUIStyle(LudiqStyles.windowBackground);
|
||||
background.padding = new RectOffset(20, 20, 20, 20);
|
||||
|
||||
defaultsButton = new GUIStyle("Button");
|
||||
defaultsButton.padding = new RectOffset(10, 10, 4, 4);
|
||||
}
|
||||
}
|
||||
|
||||
public VSSettingsTypeOption()
|
||||
{
|
||||
typeOptionsMetadata = BoltCore.Configuration.GetMetadata(nameof(BoltCoreConfiguration.typeOptions));
|
||||
}
|
||||
|
||||
public void OnGUI()
|
||||
{
|
||||
showTypeOption = EditorGUILayout.Foldout(showTypeOption, new GUIContent(titleTypeOption, descriptionTypeOption));
|
||||
|
||||
if (showTypeOption)
|
||||
{
|
||||
GUILayout.BeginVertical(Styles.background, GUILayout.ExpandHeight(true));
|
||||
|
||||
float height =
|
||||
LudiqGUI.GetInspectorHeight(null, typeOptionsMetadata, Styles.optionsWidth, GUIContent.none);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
var position = GUILayoutUtility.GetRect(Styles.optionsWidth, height);
|
||||
|
||||
LudiqGUI.Inspector(typeOptionsMetadata, position, GUIContent.none);
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
typeOptionsMetadata.Save();
|
||||
Codebase.UpdateSettings();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Reset to Defaults", Styles.defaultsButton))
|
||||
{
|
||||
typeOptionsMetadata.Reset(true);
|
||||
typeOptionsMetadata.Save();
|
||||
}
|
||||
|
||||
LudiqGUI.EndVertical();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f061d8e7ad514436d82f47b34306a22c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,170 @@
|
|||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class VSSettingsUpdate
|
||||
{
|
||||
private const string title = "Plugins Update";
|
||||
private const string buttonLabel = "Update";
|
||||
private readonly List<Plugin> plugins;
|
||||
|
||||
public VSSettingsUpdate()
|
||||
{
|
||||
IEnumerable<Plugin> allPlugins = PluginContainer.GetAllPlugins();
|
||||
|
||||
Ensure.That(nameof(allPlugins)).IsNotNull(allPlugins);
|
||||
|
||||
plugins = new List<Plugin>(allPlugins.OrderByDependencies());
|
||||
}
|
||||
|
||||
public void OnGUI()
|
||||
{
|
||||
GUILayout.Space(5f);
|
||||
|
||||
GUILayout.Label(title, EditorStyles.boldLabel);
|
||||
|
||||
GUILayout.Space(5f);
|
||||
|
||||
GUILayout.BeginVertical();
|
||||
|
||||
if (plugins.All(plugin => plugin.manifest.savedVersion == plugin.manifest.currentVersion))
|
||||
{
|
||||
string label = "All your plugins are up to date.";
|
||||
|
||||
GUILayout.BeginHorizontal(EditorStyles.helpBox);
|
||||
GUILayout.Label(EditorGUIUtility.IconContent("console.infoicon"), GUILayout.ExpandWidth(false));
|
||||
GUILayout.Box(label, EditorStyles.wordWrappedLabel);
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
GUILayout.Space(5f);
|
||||
|
||||
DrawPluginVersionTable(plugins);
|
||||
|
||||
GUILayout.Space(5f);
|
||||
|
||||
if (plugins.Any(plugin => plugin.manifest.savedVersion != plugin.manifest.currentVersion))
|
||||
{
|
||||
if (GUILayout.Button(buttonLabel, Styles.defaultsButton))
|
||||
{
|
||||
VSBackupUtility.Backup();
|
||||
|
||||
(new VSMigrationUtility()).OnUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
LudiqGUI.EndVertical();
|
||||
}
|
||||
|
||||
private static void DrawPluginVersionTable(IEnumerable<Plugin> plugins)
|
||||
{
|
||||
var savedColumnHeader = new GUIContent("Saved");
|
||||
var installedColumnHeader = new GUIContent("Installed");
|
||||
|
||||
var pluginsColumnWidth = 0f;
|
||||
var savedColumnWidth = Styles.columnHeader.CalcSize(savedColumnHeader).x;
|
||||
var installedColumnWidth = Styles.columnHeader.CalcSize(installedColumnHeader).x;
|
||||
var stateColumnWidth = 0f;
|
||||
|
||||
foreach (var plugin in plugins)
|
||||
{
|
||||
pluginsColumnWidth = Mathf.Max(pluginsColumnWidth, Styles.pluginName.CalcSize(new GUIContent(plugin.manifest.name)).x);
|
||||
savedColumnWidth = Mathf.Max(savedColumnWidth, Styles.version.CalcSize(new GUIContent(plugin.manifest.savedVersion.ToString())).x);
|
||||
installedColumnWidth = Mathf.Max(installedColumnWidth, Styles.version.CalcSize(new GUIContent(plugin.manifest.currentVersion.ToString())).x);
|
||||
stateColumnWidth = Mathf.Max(stateColumnWidth, Styles.state.CalcSize(VersionStateContent(plugin)).x);
|
||||
}
|
||||
|
||||
LudiqGUI.BeginVertical();
|
||||
|
||||
// Header row
|
||||
LudiqGUI.BeginHorizontal();
|
||||
LudiqGUI.FlexibleSpace();
|
||||
GUILayout.Label(GUIContent.none, Styles.columnHeader, GUILayout.Width(pluginsColumnWidth));
|
||||
LudiqGUI.Space(Styles.columnSpacing);
|
||||
GUILayout.Label(savedColumnHeader, Styles.columnHeader, GUILayout.Width(savedColumnWidth));
|
||||
LudiqGUI.Space(Styles.columnSpacing);
|
||||
GUILayout.Label(installedColumnHeader, Styles.columnHeader, GUILayout.Width(installedColumnWidth));
|
||||
LudiqGUI.Space(Styles.columnSpacing);
|
||||
GUILayout.Label(GUIContent.none, Styles.state, GUILayout.Width(stateColumnWidth));
|
||||
LudiqGUI.FlexibleSpace();
|
||||
LudiqGUI.EndHorizontal();
|
||||
|
||||
// Plugin rows
|
||||
foreach (var plugin in plugins)
|
||||
{
|
||||
LudiqGUI.Space(Styles.rowSpacing);
|
||||
|
||||
LudiqGUI.BeginHorizontal();
|
||||
LudiqGUI.FlexibleSpace();
|
||||
GUILayout.Label(new GUIContent(plugin.manifest.name), Styles.pluginName, GUILayout.Width(pluginsColumnWidth));
|
||||
LudiqGUI.Space(Styles.columnSpacing);
|
||||
GUILayout.Label(new GUIContent(plugin.manifest.savedVersion.ToString()), Styles.version, GUILayout.Width(savedColumnWidth));
|
||||
LudiqGUI.Space(Styles.columnSpacing);
|
||||
GUILayout.Label(new GUIContent(plugin.manifest.currentVersion.ToString()), Styles.version, GUILayout.Width(installedColumnWidth));
|
||||
LudiqGUI.Space(Styles.columnSpacing);
|
||||
GUILayout.Label(VersionStateContent(plugin), Styles.state, GUILayout.Width(stateColumnWidth));
|
||||
LudiqGUI.FlexibleSpace();
|
||||
LudiqGUI.EndHorizontal();
|
||||
}
|
||||
|
||||
LudiqGUI.EndVertical();
|
||||
}
|
||||
|
||||
private static GUIContent VersionStateContent(Plugin plugin)
|
||||
{
|
||||
if (plugin.manifest.savedVersion < plugin.manifest.currentVersion)
|
||||
{
|
||||
return new GUIContent("New version", BoltCore.Icons.upgrade?[IconSize.Small]);
|
||||
}
|
||||
else if (plugin.manifest.savedVersion == plugin.manifest.currentVersion)
|
||||
{
|
||||
return new GUIContent("Up to date", BoltCore.Icons.upToDate?[IconSize.Small]);
|
||||
}
|
||||
else if (plugin.manifest.savedVersion > plugin.manifest.currentVersion)
|
||||
{
|
||||
return new GUIContent("Downgrade", BoltCore.Icons.downgrade?[IconSize.Small]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new GUIContent("Unknown");
|
||||
}
|
||||
}
|
||||
|
||||
public static class Styles
|
||||
{
|
||||
static Styles()
|
||||
{
|
||||
defaultsButton = new GUIStyle("Button");
|
||||
defaultsButton.padding = new RectOffset(10, 10, 4, 4);
|
||||
|
||||
pluginName = new GUIStyle(EditorStyles.label);
|
||||
pluginName.alignment = TextAnchor.MiddleRight;
|
||||
|
||||
version = new GUIStyle(EditorStyles.label);
|
||||
version.alignment = TextAnchor.MiddleCenter;
|
||||
|
||||
columnHeader = new GUIStyle(EditorStyles.label);
|
||||
columnHeader.alignment = TextAnchor.LowerCenter;
|
||||
columnHeader.fontStyle = FontStyle.Bold;
|
||||
|
||||
state = new GUIStyle();
|
||||
state.fixedWidth = IconSize.Small;
|
||||
state.fixedHeight = IconSize.Small;
|
||||
state.imagePosition = ImagePosition.ImageOnly;
|
||||
state.alignment = TextAnchor.MiddleCenter;
|
||||
}
|
||||
|
||||
public static readonly GUIStyle defaultsButton;
|
||||
public static readonly GUIStyle pluginName;
|
||||
public static readonly GUIStyle columnHeader;
|
||||
public static readonly GUIStyle version;
|
||||
public static readonly GUIStyle state;
|
||||
|
||||
public static readonly float columnSpacing = 10;
|
||||
public static readonly float rowSpacing = 10;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b36c743f1860dd1458d16127e0c98fe8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7abb56c9dd89a544a9995a060ab55368
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a0a037cc0a236493996d666b0ab8690c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,27 @@
|
|||
namespace Unity.VisualScripting
|
||||
{
|
||||
public abstract class Analyser<TTarget, TAnalysis> : Assigner<TTarget, TAnalysis>, IAnalyser
|
||||
where TAnalysis : class, IAnalysis, new()
|
||||
{
|
||||
protected Analyser(GraphReference reference, TTarget target) : base(target, new TAnalysis())
|
||||
{
|
||||
Ensure.That(nameof(reference)).IsNotNull(reference);
|
||||
|
||||
this.reference = reference;
|
||||
|
||||
// HACK: It makes more sense to think of analysis as reference-bound,
|
||||
// however in practice they are context-bound and therefore it is safe
|
||||
// (and more importantly faster) to cache the context once for recursive
|
||||
// analyses.
|
||||
this.context = reference.Context();
|
||||
}
|
||||
|
||||
public TAnalysis analysis => assignee;
|
||||
|
||||
IAnalysis IAnalyser.analysis => analysis;
|
||||
|
||||
protected IGraphContext context { get; }
|
||||
|
||||
public GraphReference reference { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7cf3624e65e804bfb9dd35ee9884f519
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
|
||||
public sealed class AnalyserAttribute : Attribute, IDecoratorAttribute
|
||||
{
|
||||
public AnalyserAttribute(Type type)
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Type type { get; private set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b7663ba3a43454ba48fd2c7c17a0ae75
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,89 @@
|
|||
using System;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public sealed class AnalyserProvider : SingleDecoratorProvider<object, IAnalyser, AnalyserAttribute>
|
||||
{
|
||||
protected override bool cache => true;
|
||||
|
||||
public GraphReference reference { get; }
|
||||
|
||||
public AnalyserProvider(GraphReference reference)
|
||||
{
|
||||
this.reference = reference;
|
||||
}
|
||||
|
||||
protected override IAnalyser CreateDecorator(Type decoratorType, object decorated)
|
||||
{
|
||||
return (IAnalyser)decoratorType.Instantiate(true, reference, decorated);
|
||||
}
|
||||
|
||||
public override bool IsValid(object analyzed)
|
||||
{
|
||||
return !analyzed.IsUnityNull();
|
||||
}
|
||||
|
||||
public void Analyze(object analyzed)
|
||||
{
|
||||
GetDecorator(analyzed).isDirty = true;
|
||||
}
|
||||
|
||||
public void AnalyzeAll()
|
||||
{
|
||||
foreach (var analyser in decorators.Values)
|
||||
{
|
||||
analyser.isDirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class XAnalyserProvider
|
||||
{
|
||||
// Analysis are conceptually reference-bound, but practically context-bound,
|
||||
// so it's faster to avoid the reference-to-context lookup if we can avoid it.
|
||||
|
||||
public static IAnalyser Analyser(this object target, IGraphContext context)
|
||||
{
|
||||
return context.analyserProvider.GetDecorator(target);
|
||||
}
|
||||
|
||||
public static TAnalyser Analyser<TAnalyser>(this object target, IGraphContext context) where TAnalyser : IAnalyser
|
||||
{
|
||||
return context.analyserProvider.GetDecorator<TAnalyser>(target);
|
||||
}
|
||||
|
||||
public static IAnalysis Analysis(this object target, IGraphContext context)
|
||||
{
|
||||
var analyser = target.Analyser(context);
|
||||
analyser.Validate();
|
||||
return analyser.analysis;
|
||||
}
|
||||
|
||||
public static TAnalysis Analysis<TAnalysis>(this object target, IGraphContext context) where TAnalysis : IAnalysis
|
||||
{
|
||||
return (TAnalysis)target.Analysis(context);
|
||||
}
|
||||
|
||||
// Shortcuts, but the above are faster because Context doesn't have to be looked up
|
||||
|
||||
public static IAnalyser Analyser(this object target, GraphReference reference)
|
||||
{
|
||||
return target.Analyser(reference.Context());
|
||||
}
|
||||
|
||||
public static TAnalyser Analyser<TAnalyser>(this object target, GraphReference reference) where TAnalyser : IAnalyser
|
||||
{
|
||||
return target.Analyser<TAnalyser>(reference.Context());
|
||||
}
|
||||
|
||||
public static IAnalysis Analysis(this object target, GraphReference reference)
|
||||
{
|
||||
return target.Analysis(reference.Context());
|
||||
}
|
||||
|
||||
public static TAnalysis Analysis<TAnalysis>(this object target, GraphReference reference) where TAnalysis : IAnalysis
|
||||
{
|
||||
return target.Analysis<TAnalysis>(reference.Context());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8c1743061b8e147ff9c808d137b1014e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,6 @@
|
|||
namespace Unity.VisualScripting
|
||||
{
|
||||
public abstract class Analysis : IAnalysis
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f01a1ac261c724daca990596c32f7f10
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,9 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class GraphElementAnalysis : IGraphElementAnalysis
|
||||
{
|
||||
public List<Warning> warnings { get; set; } = new List<Warning>();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1ac0dd11da2f64fc5b55b1b8a1d36b55
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,11 @@
|
|||
namespace Unity.VisualScripting
|
||||
{
|
||||
public interface IAnalyser
|
||||
{
|
||||
IAnalysis analysis { get; }
|
||||
|
||||
bool isDirty { get; set; }
|
||||
|
||||
void Validate();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b1eb0e9411d1e4ed880da3147ac22dc8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,6 @@
|
|||
namespace Unity.VisualScripting
|
||||
{
|
||||
public interface IAnalysis
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4fb36d0252722495cbe1fddf45ba9185
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,9 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public interface IGraphElementAnalysis : IAnalysis
|
||||
{
|
||||
List<Warning> warnings { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: bf7f2015398494d498495147f2028b49
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: fae0344df02e74e0988c577297cc556d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,55 @@
|
|||
using UnityEditor;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public sealed class UsageAnalytics
|
||||
{
|
||||
const int k_MaxEventsPerHour = 1000;
|
||||
const int k_MaxNumberOfElements = 1000;
|
||||
const string k_VendorKey = "unity.bolt";
|
||||
const string k_EventName = "BoltUsage";
|
||||
static bool isRegistered = false;
|
||||
|
||||
public static void CollectAndSend()
|
||||
{
|
||||
if (!EditorAnalytics.enabled)
|
||||
return;
|
||||
|
||||
if (!RegisterEvent())
|
||||
return;
|
||||
|
||||
var data = CollectData();
|
||||
|
||||
EditorAnalytics.SendEventWithLimit(k_EventName, data);
|
||||
}
|
||||
|
||||
private static bool RegisterEvent()
|
||||
{
|
||||
if (!isRegistered)
|
||||
{
|
||||
var result = EditorAnalytics.RegisterEventWithLimit(k_EventName, k_MaxEventsPerHour, k_MaxNumberOfElements, k_VendorKey);
|
||||
if (result == UnityEngine.Analytics.AnalyticsResult.Ok)
|
||||
{
|
||||
isRegistered = true;
|
||||
}
|
||||
}
|
||||
|
||||
return isRegistered;
|
||||
}
|
||||
|
||||
private static UsageAnalyticsData CollectData()
|
||||
{
|
||||
var data = new UsageAnalyticsData
|
||||
{
|
||||
productVersion = BoltProduct.instance.version.ToString(),
|
||||
};
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private struct UsageAnalyticsData
|
||||
{
|
||||
public string productVersion;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
fileFormatVersion: 2
|
||||
<<<<<<< HEAD:Packages/com.unity.bolt/Editor/Bolt.Core/Analytics/Analytics.cs.meta
|
||||
guid: 59718df20b933421a9c465fcbeff7836
|
||||
=======
|
||||
guid: b26c0afd728514b08ae2eb47fdd61013
|
||||
>>>>>>> [1010] Visual Script Project Settings UI Change:Packages/com.unity.bolt/VSSettingsProvider/VSBackupUtility.cs.meta
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 662cc5e740e0841e1bb91853ab803f33
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,72 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public abstract class Assigner<TTarget, TAssignee> : IAssigner
|
||||
where TAssignee : class
|
||||
{
|
||||
protected Assigner(TTarget target, TAssignee assignee)
|
||||
{
|
||||
Ensure.That(nameof(target)).IsNotNull(target);
|
||||
Ensure.That(nameof(assignee)).IsNotNull(assignee);
|
||||
|
||||
this.target = target;
|
||||
this.assignee = assignee;
|
||||
|
||||
var assignerType = GetType();
|
||||
|
||||
if (!_assignments.ContainsKey(assignerType))
|
||||
{
|
||||
_assignments.Add(assignerType, Assignment.Fetch(assignerType, typeof(TAssignee)).ToArray());
|
||||
_transientAssignments.Add(assignerType, _assignments[assignerType].Where(a => !a.cache).ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
public TTarget target { get; }
|
||||
|
||||
public TAssignee assignee { get; }
|
||||
|
||||
public bool isDirty { get; set; } = true;
|
||||
|
||||
public void Validate()
|
||||
{
|
||||
if (isDirty)
|
||||
{
|
||||
AssignAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
AssignTransient();
|
||||
}
|
||||
}
|
||||
|
||||
protected void AssignAll()
|
||||
{
|
||||
isDirty = false;
|
||||
|
||||
foreach (var assignment in assignments)
|
||||
{
|
||||
assignment.Run(this, assignee);
|
||||
}
|
||||
}
|
||||
|
||||
protected void AssignTransient()
|
||||
{
|
||||
foreach (var assignment in transientAssignments)
|
||||
{
|
||||
assignment.Run(this, assignee);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ValueChanged() { }
|
||||
|
||||
public Assignment[] assignments => _assignments[GetType()];
|
||||
public Assignment[] transientAssignments => _transientAssignments[GetType()];
|
||||
|
||||
private static readonly Dictionary<Type, Assignment[]> _assignments = new Dictionary<Type, Assignment[]>();
|
||||
|
||||
private static readonly Dictionary<Type, Assignment[]> _transientAssignments = new Dictionary<Type, Assignment[]>();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e82979a3184424cf390bc7483f03771c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,69 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public sealed class Assignment
|
||||
{
|
||||
public Assignment(Member assigner, Type assigneeType)
|
||||
{
|
||||
Ensure.That(nameof(assigneeType)).IsNotNull(assigneeType);
|
||||
|
||||
this.assigner = assigner;
|
||||
|
||||
var assignsAttribute = assigner.info.GetAttribute<AssignsAttribute>();
|
||||
assignee = new Member(assigneeType, assignsAttribute?.memberName ?? assigner.name.FirstCharacterToLower());
|
||||
requiresAPI = assigner.info.HasAttribute<RequiresUnityAPIAttribute>();
|
||||
cache = assignsAttribute?.cache ?? true;
|
||||
|
||||
assigner.Prewarm();
|
||||
assignee.Prewarm();
|
||||
}
|
||||
|
||||
public Member assigner { get; }
|
||||
public Member assignee { get; }
|
||||
public bool requiresAPI { get; }
|
||||
public bool cache { get; }
|
||||
|
||||
public void Run(object assigner, object assignee)
|
||||
{
|
||||
if (requiresAPI)
|
||||
{
|
||||
UnityAPI.Async(() => _Run(assigner, assignee));
|
||||
}
|
||||
else
|
||||
{
|
||||
_Run(assigner, assignee);
|
||||
}
|
||||
}
|
||||
|
||||
private void _Run(object assigner, object assignee)
|
||||
{
|
||||
var oldValue = this.assignee.Get(assignee);
|
||||
var newValue = ConversionUtility.Convert(this.assigner.Invoke(assigner), this.assignee.type);
|
||||
|
||||
this.assignee.Set(assignee, newValue);
|
||||
|
||||
if (!Equals(oldValue, newValue))
|
||||
{
|
||||
if (assigner is IAssigner _assigner)
|
||||
{
|
||||
_assigner.ValueChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<Assignment> Fetch(Type descriptorType, Type descriptionType)
|
||||
{
|
||||
var bindingFlags = BindingFlags.Instance |
|
||||
BindingFlags.Public |
|
||||
BindingFlags.NonPublic;
|
||||
|
||||
return descriptorType.GetMethods(bindingFlags)
|
||||
.Where(m => m.HasAttribute<AssignsAttribute>())
|
||||
.Select(m => new Assignment(m.ToManipulator(descriptorType), descriptionType));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 505852ed4622a47088bd0f2f07041314
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
|
||||
public sealed class AssignsAttribute : Attribute
|
||||
{
|
||||
public AssignsAttribute() { }
|
||||
|
||||
public AssignsAttribute(string memberName)
|
||||
{
|
||||
this.memberName = memberName;
|
||||
}
|
||||
|
||||
public string memberName { get; }
|
||||
|
||||
public bool cache { get; set; } = true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d195fcaa7976240d09b19fccb42c2068
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,7 @@
|
|||
namespace Unity.VisualScripting
|
||||
{
|
||||
public interface IAssigner
|
||||
{
|
||||
void ValueChanged();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c1fabba6ac68944be828b41a0b09b932
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,51 @@
|
|||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEvent = UnityEngine.Event;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public static class BoltGUI
|
||||
{
|
||||
private static UnityEvent e => UnityEvent.current;
|
||||
|
||||
public static float GetVariableFieldHeight(GUIContent label, string value, ActionDirection direction)
|
||||
{
|
||||
return EditorGUIUtility.singleLineHeight;
|
||||
}
|
||||
|
||||
public static string VariableField(Rect position, GUIContent label, string value, ActionDirection direction)
|
||||
{
|
||||
position = EditorGUI.PrefixLabel(position, label);
|
||||
var style = direction != ActionDirection.Any ? BoltStyles.variableFieldWithDirectionIndicator : BoltStyles.variableFieldWithoutDirectionIndicator;
|
||||
value = EditorGUI.TextField(position, GUIContent.none, value, style);
|
||||
|
||||
var iconPosition = new Rect
|
||||
(
|
||||
position.x + 3,
|
||||
position.y + 2,
|
||||
12,
|
||||
12
|
||||
);
|
||||
|
||||
GUI.DrawTexture(iconPosition, BoltCore.Icons.variable?[IconSize.Small]);
|
||||
|
||||
if (direction != ActionDirection.Any)
|
||||
{
|
||||
var arrowPosition = new Rect
|
||||
(
|
||||
iconPosition.xMax + (direction == ActionDirection.Get ? 12 : -2),
|
||||
position.y + 2,
|
||||
12 * (direction == ActionDirection.Get ? -1 : 1),
|
||||
12
|
||||
);
|
||||
|
||||
if (e.type == EventType.Repaint)
|
||||
{
|
||||
BoltStyles.variableFieldDirectionIndicator.Draw(arrowPosition, false, false, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
fileFormatVersion: 2
|
||||
<<<<<<< HEAD:Packages/com.unity.bolt/Editor/Bolt.Core/BoltGUI.cs.meta
|
||||
guid: 0c9b7e151c1f64d48b39eca8d419c2b5
|
||||
=======
|
||||
guid: 9b13d76d6b80b4b1ab4d0fac8c174df4
|
||||
>>>>>>> [1010] Visual Script Project Settings UI Change:Packages/com.unity.bolt/VSSettingsProvider/VSSettingsBackup.cs.meta
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,103 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[Product(ID)]
|
||||
public sealed class BoltProduct : Product
|
||||
{
|
||||
public BoltProduct() { }
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
logo = BoltCore.Resources.LoadTexture("Logos/LogoBolt.png", CreateTextureOptions.Scalable)?.Single();
|
||||
}
|
||||
|
||||
public override string configurationPanelLabel => "Bolt";
|
||||
|
||||
public override string name => "Bolt";
|
||||
public override string description => "";
|
||||
public override string authorLabel => "Designed & Developed by ";
|
||||
public override string author => "";
|
||||
public override string copyrightHolder => "Unity";
|
||||
public override SemanticVersion version => "1.5.1";
|
||||
public override string publisherUrl => "";
|
||||
public override string websiteUrl => "";
|
||||
public override string supportUrl => "";
|
||||
public override string manualUrl => "https://docs.unity3d.com/Packages/com.unity.bolt@latest";
|
||||
public override string assetStoreUrl => "http://u3d.as/1Md2";
|
||||
|
||||
public const string ID = "Bolt";
|
||||
|
||||
#if VISUAL_SCRIPT_INTERNAL
|
||||
public const int ToolsMenuPriority = -990000;
|
||||
public const int DeveloperToolsMenuPriority = ToolsMenuPriority + 1000;
|
||||
#endif
|
||||
|
||||
public static BoltProduct instance => (BoltProduct)ProductContainer.GetProduct(ID);
|
||||
|
||||
[SettingsProvider]
|
||||
private static SettingsProvider BoltSettingsProvider()
|
||||
{
|
||||
return new VSEditorSettingsProviderView();
|
||||
}
|
||||
|
||||
private static bool PrepareForRelease()
|
||||
{
|
||||
if (!EditorUtility.DisplayDialog("Delete Generated Files", "This action will delete all generated files, including those containing user data.\n\nAre you sure you want to continue?", "Confirm", "Cancel"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
PluginConfiguration.DeleteAllProjectSettings();
|
||||
|
||||
foreach (var plugin in PluginContainer.plugins)
|
||||
{
|
||||
PathUtility.DeleteDirectoryIfExists(plugin.paths.persistentGenerated);
|
||||
PathUtility.DeleteDirectoryIfExists(plugin.paths.transientGenerated);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if VISUAL_SCRIPT_INTERNAL
|
||||
[MenuItem("Tools/Bolt/Internal/Export Release Asset Package...", priority = DeveloperToolsMenuPriority + 102)]
|
||||
#endif
|
||||
private static void ExportReleasePackage()
|
||||
{
|
||||
if (!PrepareForRelease())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var exportPath = EditorUtility.SaveFilePanel("Export Release Package",
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
|
||||
"Bolt_" + instance.version.ToString().Replace(".", "_").Replace(" ", "_"),
|
||||
"unitypackage");
|
||||
|
||||
if (exportPath == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var packageDirectory = Path.GetDirectoryName(exportPath);
|
||||
|
||||
var paths = new List<string>()
|
||||
{
|
||||
PathUtility.GetPackageRootPath()
|
||||
};
|
||||
|
||||
AssetDatabase.ExportPackage(paths.ToArray(), exportPath, ExportPackageOptions.Recurse);
|
||||
|
||||
if (EditorUtility.DisplayDialog("Export Release Package", "Release package export complete.\nOpen containing folder?", "Open Folder", "Close"))
|
||||
{
|
||||
Process.Start(packageDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d800ad61ae46243a0bc7d8d834b1bf3f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,24 @@
|
|||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public static class BoltStyles
|
||||
{
|
||||
static BoltStyles()
|
||||
{
|
||||
// Variables
|
||||
|
||||
variableFieldDirectionIndicator = "AC LeftArrow";
|
||||
variableFieldWithoutDirectionIndicator = new GUIStyle(EditorStyles.textField);
|
||||
variableFieldWithoutDirectionIndicator.padding.left = IconSize.Small;
|
||||
variableFieldWithDirectionIndicator = new GUIStyle(variableFieldWithoutDirectionIndicator);
|
||||
variableFieldWithDirectionIndicator.padding.left = 24;
|
||||
}
|
||||
|
||||
// Variables
|
||||
public static readonly GUIStyle variableFieldDirectionIndicator;
|
||||
public static readonly GUIStyle variableFieldWithDirectionIndicator;
|
||||
public static readonly GUIStyle variableFieldWithoutDirectionIndicator;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2a3cd7080fc4042768e4e591975cfbc5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 31d3bc055420f4ee59008eb8996d7df2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,35 @@
|
|||
namespace Unity.VisualScripting
|
||||
{
|
||||
public enum AlignOperation
|
||||
{
|
||||
/// <summary>
|
||||
/// Align the left edges of the selected elements.
|
||||
/// </summary>
|
||||
AlignLeftEdges,
|
||||
|
||||
/// <summary>
|
||||
/// Align the horizontal centers of the selected elements.
|
||||
/// </summary>
|
||||
AlignCenters,
|
||||
|
||||
/// <summary>
|
||||
/// Align the right edges of the selected elements.
|
||||
/// </summary>
|
||||
AlignRightEdges,
|
||||
|
||||
/// <summary>
|
||||
/// Align the top edges of the selected elements.
|
||||
/// </summary>
|
||||
AlignTopEdges,
|
||||
|
||||
/// <summary>
|
||||
/// Align the vertical middles of the selected elements.
|
||||
/// </summary>
|
||||
AlignMiddles,
|
||||
|
||||
/// <summary>
|
||||
/// Align the bottom edges of the selected elements.
|
||||
/// </summary>
|
||||
AlignBottomEdges
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 57d833ea26c9149528d23f0ec150b1d2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
|
||||
public sealed class CanvasAttribute : Attribute, IDecoratorAttribute
|
||||
{
|
||||
public CanvasAttribute(Type type)
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Type type { get; private set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4d719ba635ebc49c5a2132cc199b06d3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
namespace Unity.VisualScripting
|
||||
{
|
||||
public enum CanvasControlScheme
|
||||
{
|
||||
Unity,
|
||||
Unreal
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c47a48caf94f0400ebbbbbe83ae13c45
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,52 @@
|
|||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class CanvasProvider : SingleDecoratorProvider<IGraph, ICanvas, CanvasAttribute>
|
||||
{
|
||||
static CanvasProvider()
|
||||
{
|
||||
instance = new CanvasProvider();
|
||||
}
|
||||
|
||||
public static CanvasProvider instance { get; }
|
||||
|
||||
protected override bool cache => true;
|
||||
|
||||
public override bool IsValid(IGraph graph)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class XCanvasProvider
|
||||
{
|
||||
public static ICanvas Canvas(this IGraph graph)
|
||||
{
|
||||
return CanvasProvider.instance.GetDecorator(graph);
|
||||
}
|
||||
|
||||
public static TCanvas Canvas<TCanvas>(this IGraph graph) where TCanvas : ICanvas
|
||||
{
|
||||
return CanvasProvider.instance.GetDecorator<TCanvas>(graph);
|
||||
}
|
||||
|
||||
public static IWidget Widget(this ICanvas context, IGraphItem item)
|
||||
{
|
||||
return context.widgetProvider.GetDecorator(item);
|
||||
}
|
||||
|
||||
public static TWidget Widget<TWidget>(this ICanvas context, IGraphItem item) where TWidget : IWidget
|
||||
{
|
||||
return context.widgetProvider.GetDecorator<TWidget>(item);
|
||||
}
|
||||
|
||||
public static IGraphElementWidget Widget(this ICanvas context, IGraphElement element)
|
||||
{
|
||||
return (IGraphElementWidget)context.widgetProvider.GetDecorator(element);
|
||||
}
|
||||
|
||||
public static TWidget Widget<TWidget>(this ICanvas context, IGraphElement element) where TWidget : IGraphElementWidget
|
||||
{
|
||||
return context.widgetProvider.GetDecorator<TWidget>(element);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b32061678e736470f9787cdd51b40816
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,53 @@
|
|||
namespace Unity.VisualScripting
|
||||
{
|
||||
public enum DistributeOperation
|
||||
{
|
||||
/// <summary>
|
||||
/// Distribute the selected elements so that the left edges
|
||||
/// are at equal distance of one another.
|
||||
/// </summary>
|
||||
DistributeLeftEdges,
|
||||
|
||||
/// <summary>
|
||||
/// Distribute the selected elements so that the horizontal centers
|
||||
/// are at equal distance of one another.
|
||||
/// </summary>
|
||||
DistributeCenters,
|
||||
|
||||
/// <summary>
|
||||
/// Distribute the selected elements so that the right edges
|
||||
/// are at equal distance of one another.
|
||||
/// </summary>
|
||||
DistributeRightEdges,
|
||||
|
||||
/// <summary>
|
||||
/// Distribute the selected elements so that the horizontal gaps
|
||||
/// are all of equal size.
|
||||
/// </summary>
|
||||
DistributeHorizontalGaps,
|
||||
|
||||
/// <summary>
|
||||
/// Distribute the selected elements so that the top edges
|
||||
/// are at equal distance of one another.
|
||||
/// </summary>
|
||||
DistributeTopEdges,
|
||||
|
||||
/// <summary>
|
||||
/// Distribute the selected elements so that the vertical middles
|
||||
/// are at equal distance of one another.
|
||||
/// </summary>
|
||||
DistributeMiddles,
|
||||
|
||||
/// <summary>
|
||||
/// Distribute the selected elements so that the bottom edges
|
||||
/// are at equal distance of one another.
|
||||
/// </summary>
|
||||
DistributeBottomEdges,
|
||||
|
||||
/// <summary>
|
||||
/// Distribute the selected elements so that the vertical gaps
|
||||
/// are all of equal size.
|
||||
/// </summary>
|
||||
DistributeVerticalGaps
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 734135440ea3f4d6297720ac1b3be02b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,173 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public interface ICanvas : IDisposable, IDragAndDropHandler
|
||||
{
|
||||
void Cache();
|
||||
|
||||
#region Model
|
||||
|
||||
ICanvasWindow window { get; set; }
|
||||
|
||||
IGraph graph { get; }
|
||||
|
||||
WidgetProvider widgetProvider { get; }
|
||||
|
||||
GraphSelection selection { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Widgets
|
||||
|
||||
IEnumerable<IWidget> widgets { get; }
|
||||
|
||||
void Recollect();
|
||||
|
||||
void CacheWidgetCollections();
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Hovering
|
||||
|
||||
IWidget hoveredWidget { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Deleting
|
||||
|
||||
void DeleteSelection();
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Clipboard
|
||||
|
||||
void ShrinkCopyGroup(HashSet<IGraphElement> copyGroup);
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Lifecycle
|
||||
|
||||
void RegisterControls();
|
||||
|
||||
void Open();
|
||||
|
||||
void Close();
|
||||
|
||||
void Update();
|
||||
|
||||
void BeforeFrame();
|
||||
|
||||
void OnGUI();
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Viewing
|
||||
|
||||
float zoom { get; }
|
||||
|
||||
Vector2 pan { get; }
|
||||
|
||||
void UpdateViewport();
|
||||
|
||||
Rect viewport { get; set; }
|
||||
|
||||
Vector2 mousePosition { get; }
|
||||
|
||||
bool isMouseOver { get; }
|
||||
|
||||
bool isMouseOverBackground { get; }
|
||||
|
||||
void ViewElements(IEnumerable<IGraphElement> elements);
|
||||
|
||||
bool IsVisible(IWidget widget);
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Positioning
|
||||
|
||||
void CacheWidgetPositions();
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Lassoing
|
||||
|
||||
bool isLassoing { get; }
|
||||
|
||||
Rect lassoArea { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Selecting
|
||||
|
||||
bool isSelecting { get; }
|
||||
|
||||
Rect selectionArea { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Grouping
|
||||
|
||||
bool isGrouping { get; }
|
||||
|
||||
Rect groupArea { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Dragging
|
||||
|
||||
bool isDragging { get; }
|
||||
|
||||
void BeginDrag(EventWrapper e);
|
||||
|
||||
void Drag(EventWrapper e);
|
||||
|
||||
void EndDrag(EventWrapper e);
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Layout
|
||||
|
||||
void Align(AlignOperation operation);
|
||||
|
||||
void Distribute(DistributeOperation operation);
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Timing
|
||||
|
||||
float frameDeltaTime { get; }
|
||||
|
||||
float eventDeltaTime { get; }
|
||||
|
||||
float repaintDeltaTime { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Window
|
||||
|
||||
void OnToolbarGUI();
|
||||
|
||||
event Action delayCall;
|
||||
|
||||
Queue<Action> delayedCalls { get; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: efc35be9d817e474abdbae4ad8bcce69
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,9 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public interface IGraphContextExtension : IDragAndDropHandler
|
||||
{
|
||||
IEnumerable<GraphContextMenuItem> contextMenuItems { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3fc8c30ce61444945ab84043028247dc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d1483dfd529fe4aeeaba721add9fceb5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,134 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
/// <summary>
|
||||
/// A list of widgets that can be safely iterated over even if the collection changes during iteration.
|
||||
/// </summary>
|
||||
public class WidgetList<TWidget> : Collection<TWidget>, IEnumerable<TWidget> where TWidget : class, IWidget
|
||||
{
|
||||
private uint version;
|
||||
|
||||
private readonly ICanvas canvas;
|
||||
|
||||
public WidgetList(ICanvas canvas)
|
||||
{
|
||||
Ensure.That(nameof(canvas)).IsNotNull(canvas);
|
||||
|
||||
this.canvas = canvas;
|
||||
}
|
||||
|
||||
protected override void InsertItem(int index, TWidget item)
|
||||
{
|
||||
base.InsertItem(index, item);
|
||||
version++;
|
||||
}
|
||||
|
||||
protected override void RemoveItem(int index)
|
||||
{
|
||||
base.RemoveItem(index);
|
||||
version++;
|
||||
}
|
||||
|
||||
protected override void ClearItems()
|
||||
{
|
||||
base.ClearItems();
|
||||
version++;
|
||||
}
|
||||
|
||||
public new Enumerator GetEnumerator()
|
||||
{
|
||||
return new Enumerator(this);
|
||||
}
|
||||
|
||||
IEnumerator<TWidget> IEnumerable<TWidget>.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public struct Enumerator : IEnumerator<TWidget>
|
||||
{
|
||||
private readonly WidgetList<TWidget> list;
|
||||
|
||||
private int index;
|
||||
|
||||
private TWidget current;
|
||||
|
||||
private bool invalid;
|
||||
|
||||
private readonly uint version;
|
||||
|
||||
private IGraph graph;
|
||||
|
||||
public Enumerator(WidgetList<TWidget> list) : this()
|
||||
{
|
||||
this.list = list;
|
||||
version = list.version;
|
||||
|
||||
// Micro optim
|
||||
graph = list.canvas.graph;
|
||||
}
|
||||
|
||||
public void Dispose() { }
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
// Stop if the list changed
|
||||
if (version != list.version)
|
||||
{
|
||||
current = null;
|
||||
invalid = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Micro optim
|
||||
var count = list.Count;
|
||||
|
||||
// Find the next element that is within the graph
|
||||
while (index < count)
|
||||
{
|
||||
current = list[index];
|
||||
index++;
|
||||
|
||||
if (current.item.graph == graph)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Expleted the list
|
||||
current = null;
|
||||
invalid = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public TWidget Current => current;
|
||||
|
||||
object IEnumerator.Current
|
||||
{
|
||||
get
|
||||
{
|
||||
if (invalid)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
return Current;
|
||||
}
|
||||
}
|
||||
|
||||
void IEnumerator.Reset()
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f799a0c75a66440bd87f44b34a197d9c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d95a4548a35ec4b78ad08d0210b776ec
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,321 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[InitializeAfterPlugins]
|
||||
public static class GraphClipboard
|
||||
{
|
||||
static GraphClipboard()
|
||||
{
|
||||
singleClipboard = new Clipboard();
|
||||
groupClipboard = new Clipboard();
|
||||
|
||||
GraphWindow.activeContextChanged += OnContextChange;
|
||||
}
|
||||
|
||||
private static Event e => Event.current;
|
||||
|
||||
private static void OnContextChange(IGraphContext context)
|
||||
{
|
||||
GraphClipboard.context = context;
|
||||
}
|
||||
|
||||
private static IGraphContext context;
|
||||
|
||||
#region Context Shortcuts
|
||||
|
||||
private static GraphReference reference => context.reference;
|
||||
|
||||
private static IGraph graph => context.graph;
|
||||
|
||||
private static ICanvas canvas => context.canvas;
|
||||
|
||||
private static GraphSelection selection => context.selection;
|
||||
|
||||
#endregion
|
||||
|
||||
public static Clipboard singleClipboard { get; }
|
||||
|
||||
public static Clipboard groupClipboard { get; }
|
||||
|
||||
public static bool canCopySelection => selection.Count > 0;
|
||||
|
||||
public static bool canPaste
|
||||
{
|
||||
get
|
||||
{
|
||||
if (selection.Count == 1 && CanPasteInside(selection.Single()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return canPasteOutside;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool canPasteOutside => groupClipboard.containsData && GetPasteGroup().Any();
|
||||
|
||||
public static bool canDuplicateSelection => GetCopyGroup(selection).Count > 0;
|
||||
|
||||
private static HashSet<IGraphElement> GetCopyGroup(IEnumerable<IGraphElement> elements)
|
||||
{
|
||||
var copyGroup = new HashSet<IGraphElement>();
|
||||
|
||||
foreach (var element in elements)
|
||||
{
|
||||
copyGroup.Add(element);
|
||||
|
||||
canvas.Widget(element).ExpandCopyGroup(copyGroup);
|
||||
}
|
||||
|
||||
canvas.ShrinkCopyGroup(copyGroup);
|
||||
|
||||
return copyGroup;
|
||||
}
|
||||
|
||||
private static List<IGraphElement> GetPasteGroup()
|
||||
{
|
||||
return groupClipboard.Paste<HashSet<IGraphElement>>()
|
||||
.Where(e => graph.elements.Includes(e.GetType()))
|
||||
.OrderBy(e => e.dependencyOrder)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public static void CopyElement(IGraphElement element)
|
||||
{
|
||||
Ensure.That(nameof(element)).IsNotNull(element);
|
||||
|
||||
singleClipboard.Copy(element);
|
||||
groupClipboard.Copy(GetCopyGroup(element.Yield()));
|
||||
}
|
||||
|
||||
public static void CopySelection()
|
||||
{
|
||||
if (!canCopySelection)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
if (selection.Count == 1)
|
||||
{
|
||||
CopyElement(selection.Single());
|
||||
}
|
||||
else
|
||||
{
|
||||
singleClipboard.Clear();
|
||||
groupClipboard.Copy(GetCopyGroup(selection));
|
||||
}
|
||||
|
||||
e?.TryUse();
|
||||
}
|
||||
|
||||
public static void Paste(Vector2? position = null)
|
||||
{
|
||||
if (!canPaste)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
if (selection.Count == 1 && CanPasteInside(selection.Single()))
|
||||
{
|
||||
PasteInside(selection.Single());
|
||||
}
|
||||
else
|
||||
{
|
||||
PasteOutside(true, position);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool CanPasteInside(IGraphElement element)
|
||||
{
|
||||
Ensure.That(nameof(element)).IsNotNull(element);
|
||||
|
||||
// TODO: A solid PasteInside implementation would work like ReplaceUnit:
|
||||
// Implement an IPreservable interface, preserve, remove, recreate, apply.
|
||||
// This would make entirely sure that all OnAdd/OnRemove handlers get called,
|
||||
// and wouldn't require any per-element implementation. Plus, it would
|
||||
// allow pasting across element types while preserving connections/transitions!
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void PasteInside(IGraphElement element)
|
||||
{
|
||||
Ensure.That(nameof(element)).IsNotNull(element);
|
||||
|
||||
if (!CanPasteInside(element))
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
UndoUtility.RecordEditedObject("Paste Graph Element");
|
||||
|
||||
throw new NotImplementedException();
|
||||
|
||||
//GUI.changed = true;
|
||||
//e?.TryUse();
|
||||
}
|
||||
|
||||
public static void PasteOutside(bool reposition, Vector2? position = null)
|
||||
{
|
||||
if (!canPasteOutside)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
UndoUtility.RecordEditedObject("Paste Graph Elements");
|
||||
|
||||
var pastedElements = GetPasteGroup();
|
||||
|
||||
// Assign new GUIDs
|
||||
|
||||
foreach (var pastedElement in pastedElements)
|
||||
{
|
||||
pastedElement.guid = Guid.NewGuid();
|
||||
}
|
||||
|
||||
// Add elements to graph and selection
|
||||
|
||||
selection.Clear();
|
||||
|
||||
foreach (var pastedElement in pastedElements)
|
||||
{
|
||||
if (!pastedElement.HandleDependencies())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
graph.elements.Add(pastedElement);
|
||||
|
||||
selection.Add(pastedElement);
|
||||
}
|
||||
|
||||
canvas.Cache();
|
||||
|
||||
foreach (var pastedElement in pastedElements)
|
||||
{
|
||||
var pastedWidget = canvas.Widget(pastedElement);
|
||||
pastedWidget.BringToFront();
|
||||
}
|
||||
|
||||
var pastedWidgets = pastedElements.Select(e => canvas.Widget(e)).ToList();
|
||||
|
||||
// Recenter elements in graph view
|
||||
|
||||
if (reposition)
|
||||
{
|
||||
var area = GraphGUI.CalculateArea(pastedWidgets.Where(widget => widget.canDrag));
|
||||
|
||||
Vector2 delta;
|
||||
|
||||
if (position.HasValue)
|
||||
{
|
||||
delta = position.Value - area.position;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = graph.pan - area.center;
|
||||
}
|
||||
|
||||
foreach (var pastedWidget in pastedWidgets)
|
||||
{
|
||||
if (pastedWidget.canDrag)
|
||||
{
|
||||
pastedWidget.position = new Rect(pastedWidget.position.position + delta, pastedWidget.position.size).PixelPerfect();
|
||||
pastedWidget.Reposition();
|
||||
pastedWidget.CachePositionFirstPass();
|
||||
pastedWidget.CachePosition();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Space out overlapping elements
|
||||
|
||||
foreach (var pastedWidget in pastedWidgets)
|
||||
{
|
||||
if (pastedWidget.canDrag)
|
||||
{
|
||||
var distanciation = 20;
|
||||
var timeout = 100;
|
||||
var timeoutIndex = 0;
|
||||
|
||||
while (GraphGUI.PositionOverlaps(canvas, pastedWidget, 5))
|
||||
{
|
||||
// Space the widget out
|
||||
pastedWidget.position = new Rect(pastedWidget.position.position + new Vector2(distanciation, distanciation), pastedWidget.position.size).PixelPerfect();
|
||||
|
||||
// Calculate the resulting position immediately
|
||||
pastedWidget.CachePositionFirstPass();
|
||||
pastedWidget.CachePosition();
|
||||
|
||||
// Mark it as invalid still so dependencies like ports will be recached
|
||||
pastedWidget.Reposition();
|
||||
|
||||
// Failsafe to keep the editor from freezing
|
||||
if (++timeoutIndex > timeout)
|
||||
{
|
||||
Debug.LogWarning($"Failed to space out pasted element: {pastedWidget.element}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
canvas.Cache();
|
||||
|
||||
GUI.changed = true;
|
||||
|
||||
e?.TryUse();
|
||||
}
|
||||
|
||||
public static void CutSelection()
|
||||
{
|
||||
UndoUtility.RecordEditedObject("Cut Graph Element Selection");
|
||||
CopySelection();
|
||||
canvas.DeleteSelection();
|
||||
}
|
||||
|
||||
public static void DuplicateSelection()
|
||||
{
|
||||
object singleClipboardRestore = null;
|
||||
object groupClipboardRestore = null;
|
||||
|
||||
if (singleClipboard.containsData)
|
||||
{
|
||||
singleClipboardRestore = singleClipboard.Paste();
|
||||
}
|
||||
|
||||
if (groupClipboard.containsData)
|
||||
{
|
||||
groupClipboardRestore = groupClipboard.Paste();
|
||||
}
|
||||
|
||||
UndoUtility.RecordEditedObject("Duplicate Graph Element Selection");
|
||||
CopySelection();
|
||||
PasteOutside(false);
|
||||
|
||||
if (singleClipboardRestore != null)
|
||||
{
|
||||
singleClipboard.Copy(singleClipboardRestore);
|
||||
}
|
||||
else
|
||||
{
|
||||
singleClipboard.Clear();
|
||||
}
|
||||
|
||||
if (groupClipboardRestore != null)
|
||||
{
|
||||
groupClipboard.Copy(groupClipboardRestore);
|
||||
}
|
||||
else
|
||||
{
|
||||
groupClipboard.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c89d16b46444140d3bbbc42881903a35
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,114 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityObject = UnityEngine.Object;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public abstract class GraphContext<TGraph, TCanvas> : IGraphContext
|
||||
where TGraph : class, IGraph
|
||||
where TCanvas : class, ICanvas
|
||||
{
|
||||
protected GraphContext(GraphReference reference)
|
||||
{
|
||||
Ensure.That(nameof(reference)).IsNotNull(reference);
|
||||
Ensure.That(nameof(reference.graph)).IsOfType<TGraph>(reference.graph);
|
||||
|
||||
this.reference = reference;
|
||||
|
||||
analyserProvider = new AnalyserProvider(reference);
|
||||
graphMetadata = Metadata.Root().StaticObject(reference.graph);
|
||||
extensions = this.Extensions().ToList().AsReadOnly();
|
||||
sidebarPanels = SidebarPanels().ToList().AsReadOnly();
|
||||
}
|
||||
|
||||
public GraphReference reference { get; }
|
||||
|
||||
public AnalyserProvider analyserProvider { get; }
|
||||
|
||||
public TCanvas canvas => (TCanvas)graph.Canvas();
|
||||
|
||||
ICanvas IGraphContext.canvas => canvas;
|
||||
|
||||
public GraphSelection selection => canvas.selection;
|
||||
|
||||
public TGraph graph => (TGraph)reference.graph;
|
||||
|
||||
IGraph IGraphContext.graph => graph;
|
||||
|
||||
public Metadata graphMetadata { get; }
|
||||
|
||||
public Metadata selectionMetadata => selection.Count == 1 ? ElementMetadata(selection.Single()) : null;
|
||||
|
||||
public Metadata ElementMetadata(IGraphElement element)
|
||||
{
|
||||
// Static object is faster than indexer
|
||||
// return graphMetadata[nameof(IGraph.elements)].Indexer(element.guid).Cast(element.GetType());
|
||||
return graphMetadata[nameof(IGraph.elements)].StaticObject(element);
|
||||
}
|
||||
|
||||
public ReadOnlyCollection<IGraphContextExtension> extensions { get; }
|
||||
|
||||
IEnumerable<IGraphContextExtension> IGraphContext.extensions => extensions;
|
||||
|
||||
public virtual string windowTitle => "Graph";
|
||||
|
||||
protected virtual IEnumerable<ISidebarPanelContent> SidebarPanels() => Enumerable.Empty<ISidebarPanelContent>();
|
||||
|
||||
public ReadOnlyCollection<ISidebarPanelContent> sidebarPanels { get; }
|
||||
|
||||
IEnumerable<ISidebarPanelContent> IGraphContext.sidebarPanels => sidebarPanels;
|
||||
|
||||
public bool isPrefabInstance => reference.serializedObject?.IsConnectedPrefabInstance() ?? false;
|
||||
|
||||
#region Lifecycle
|
||||
|
||||
public virtual void Dispose()
|
||||
{
|
||||
// Manually free the providers so that the
|
||||
// disposable decorators free their event handlers
|
||||
|
||||
analyserProvider?.FreeAll();
|
||||
}
|
||||
|
||||
public void BeginEdit(bool disablePrefabInstance = true)
|
||||
{
|
||||
LudiqEditorUtility.editedObject.BeginOverride(reference.serializedObject);
|
||||
LudiqGraphsEditorUtility.editedContext.BeginOverride(this);
|
||||
EditorGUI.BeginDisabledGroup(disablePrefabInstance && isPrefabInstance);
|
||||
EditorGUI.BeginChangeCheck();
|
||||
}
|
||||
|
||||
public void EndEdit()
|
||||
{
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
DescribeAndAnalyze();
|
||||
}
|
||||
|
||||
EditorGUI.EndDisabledGroup();
|
||||
LudiqGraphsEditorUtility.editedContext.EndOverride();
|
||||
LudiqEditorUtility.editedObject.EndOverride();
|
||||
}
|
||||
|
||||
public void DescribeAndAnalyze()
|
||||
{
|
||||
foreach (var element in graph.elements)
|
||||
{
|
||||
if (element.HasDescriptor())
|
||||
{
|
||||
element.Describe();
|
||||
}
|
||||
}
|
||||
|
||||
graph.Describe();
|
||||
|
||||
analyserProvider.AnalyzeAll();
|
||||
|
||||
reference.parent.Describe();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ca981340ac4c94929b5263c2e31a0d6c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
|
||||
public sealed class GraphContextAttribute : Attribute, IDecoratorAttribute
|
||||
{
|
||||
public GraphContextAttribute(Type type)
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Type type { get; private set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 159639efa590a4849a09879979cbba8b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,46 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public abstract class GraphContextExtension<TGraphContext> : IGraphContextExtension
|
||||
where TGraphContext : IGraphContext
|
||||
{
|
||||
protected GraphContextExtension(TGraphContext context)
|
||||
{
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public TGraphContext context { get; }
|
||||
|
||||
#region Context Shortcuts
|
||||
|
||||
protected GraphReference reference => context.reference;
|
||||
|
||||
protected IGraph graph => context.graph;
|
||||
|
||||
protected ICanvas canvas => context.canvas;
|
||||
|
||||
protected GraphSelection selection => context.selection;
|
||||
|
||||
#endregion
|
||||
|
||||
public virtual IEnumerable<GraphContextMenuItem> contextMenuItems => Enumerable.Empty<GraphContextMenuItem>();
|
||||
|
||||
public virtual DragAndDropVisualMode dragAndDropVisualMode => DragAndDropVisualMode.Generic;
|
||||
|
||||
public virtual bool AcceptsDragAndDrop() => false;
|
||||
|
||||
public virtual void PerformDragAndDrop() { }
|
||||
|
||||
public virtual void UpdateDragAndDrop() { }
|
||||
|
||||
public virtual void DrawDragAndDropPreview() { }
|
||||
|
||||
public virtual void ExitDragAndDrop() { }
|
||||
|
||||
protected static Event e => Event.current;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 075261282385d497b8b191d4e752d49b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,18 @@
|
|||
using System;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
|
||||
public sealed class GraphContextExtensionAttribute : Attribute, IDecoratorAttribute
|
||||
{
|
||||
public GraphContextExtensionAttribute(Type type)
|
||||
{
|
||||
Ensure.That(nameof(type)).IsNotNull(type);
|
||||
Ensure.That(nameof(type)).IsOfType(type, typeof(IGraphContext));
|
||||
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Type type { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2353beb7f92634ac5b080bc12887c8c6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,22 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class GraphContextExtensionProvider : MultiDecoratorProvider<IGraphContext, IGraphContextExtension, GraphContextExtensionAttribute>
|
||||
{
|
||||
static GraphContextExtensionProvider()
|
||||
{
|
||||
instance = new GraphContextExtensionProvider();
|
||||
}
|
||||
|
||||
public static GraphContextExtensionProvider instance { get; }
|
||||
}
|
||||
|
||||
public static class XCanvasExtensionProvider
|
||||
{
|
||||
public static IEnumerable<IGraphContextExtension> Extensions(this IGraphContext context)
|
||||
{
|
||||
return GraphContextExtensionProvider.instance.GetDecorators(context);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2badc2f72eb6f4a8d8e6f42746b39cfa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public struct GraphContextMenuItem
|
||||
{
|
||||
public Action<Vector2> action { get; }
|
||||
public string label { get; }
|
||||
|
||||
public GraphContextMenuItem(Action<Vector2> action, string label)
|
||||
{
|
||||
this.action = action;
|
||||
this.label = label;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7e1184a2de015411bada583d3be55328
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class GraphContextProvider : SingleDecoratorProvider<GraphReference, IGraphContext, GraphContextAttribute>
|
||||
{
|
||||
static GraphContextProvider()
|
||||
{
|
||||
instance = new GraphContextProvider();
|
||||
}
|
||||
|
||||
public static GraphContextProvider instance { get; }
|
||||
|
||||
protected override bool cache => true;
|
||||
|
||||
protected override Type GetDecoratedType(GraphReference reference)
|
||||
{
|
||||
return reference.graph.GetType();
|
||||
}
|
||||
|
||||
public override bool IsValid(GraphReference reference)
|
||||
{
|
||||
return reference.isValid;
|
||||
}
|
||||
}
|
||||
|
||||
public static class XGraphContextProvider
|
||||
{
|
||||
public static IGraphContext Context(this GraphReference reference)
|
||||
{
|
||||
return GraphContextProvider.instance.GetDecorator(reference);
|
||||
}
|
||||
|
||||
public static T Context<T>(this GraphReference reference) where T : IGraphContext
|
||||
{
|
||||
return GraphContextProvider.instance.GetDecorator<T>(reference);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: da3da30b6a9874cf29f6c915e750a225
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,227 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public sealed class GraphSelection : ISet<IGraphElement>
|
||||
{
|
||||
public GraphSelection() : base()
|
||||
{
|
||||
set = new HashSet<IGraphElement>();
|
||||
}
|
||||
|
||||
public event Action changed;
|
||||
|
||||
private readonly HashSet<IGraphElement> set;
|
||||
|
||||
public int Count => set.Count;
|
||||
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
private void OnChange()
|
||||
{
|
||||
changed?.Invoke();
|
||||
}
|
||||
|
||||
IEnumerator<IGraphElement> IEnumerable<IGraphElement>.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public HashSet<IGraphElement>.Enumerator GetEnumerator()
|
||||
{
|
||||
return set.GetEnumerator();
|
||||
}
|
||||
|
||||
public void Select(IGraphElement item)
|
||||
{
|
||||
Clear();
|
||||
Add(item);
|
||||
}
|
||||
|
||||
public void Select(IEnumerable<IGraphElement> items)
|
||||
{
|
||||
Clear();
|
||||
UnionWith(items);
|
||||
}
|
||||
|
||||
public bool Contains(IGraphElement item)
|
||||
{
|
||||
Ensure.That(nameof(item)).IsNotNull(item);
|
||||
|
||||
return set.Contains(item);
|
||||
}
|
||||
|
||||
public bool Add(IGraphElement item)
|
||||
{
|
||||
Ensure.That(nameof(item)).IsNotNull(item);
|
||||
|
||||
if (set.Add(item))
|
||||
{
|
||||
OnChange();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Remove(IGraphElement item)
|
||||
{
|
||||
Ensure.That(nameof(item)).IsNotNull(item);
|
||||
|
||||
if (set.Remove(item))
|
||||
{
|
||||
OnChange();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
if (set.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
set.Clear();
|
||||
OnChange();
|
||||
}
|
||||
|
||||
#region Set Logic
|
||||
|
||||
public void ExceptWith(IEnumerable<IGraphElement> other)
|
||||
{
|
||||
var countBefore = set.Count;
|
||||
|
||||
set.ExceptWith(other);
|
||||
|
||||
if (countBefore != set.Count)
|
||||
{
|
||||
OnChange();
|
||||
}
|
||||
}
|
||||
|
||||
public void IntersectWith(IEnumerable<IGraphElement> other)
|
||||
{
|
||||
var countBefore = set.Count;
|
||||
|
||||
set.IntersectWith(other);
|
||||
|
||||
if (countBefore != set.Count)
|
||||
{
|
||||
OnChange();
|
||||
}
|
||||
}
|
||||
|
||||
public void SymmetricExceptWith(IEnumerable<IGraphElement> other)
|
||||
{
|
||||
var countBefore = set.Count;
|
||||
|
||||
set.SymmetricExceptWith(other);
|
||||
|
||||
if (countBefore != set.Count)
|
||||
{
|
||||
OnChange();
|
||||
}
|
||||
}
|
||||
|
||||
public void UnionWith(IEnumerable<IGraphElement> other)
|
||||
{
|
||||
var countBefore = set.Count;
|
||||
|
||||
set.UnionWith(other);
|
||||
|
||||
if (countBefore != set.Count)
|
||||
{
|
||||
OnChange();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsProperSubsetOf(IEnumerable<IGraphElement> other)
|
||||
{
|
||||
return set.IsProperSubsetOf(other);
|
||||
}
|
||||
|
||||
public bool IsProperSupersetOf(IEnumerable<IGraphElement> other)
|
||||
{
|
||||
return set.IsProperSupersetOf(other);
|
||||
}
|
||||
|
||||
public bool IsSubsetOf(IEnumerable<IGraphElement> other)
|
||||
{
|
||||
return set.IsSubsetOf(other);
|
||||
}
|
||||
|
||||
public bool IsSupersetOf(IEnumerable<IGraphElement> other)
|
||||
{
|
||||
return set.IsSupersetOf(other);
|
||||
}
|
||||
|
||||
public bool Overlaps(IEnumerable<IGraphElement> other)
|
||||
{
|
||||
return set.Overlaps(other);
|
||||
}
|
||||
|
||||
public bool SetEquals(IEnumerable<IGraphElement> other)
|
||||
{
|
||||
return set.SetEquals(other);
|
||||
}
|
||||
|
||||
public int RemoveWhere(Predicate<IGraphElement> match)
|
||||
{
|
||||
return set.RemoveWhere(match);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ICollection
|
||||
|
||||
void ICollection<IGraphElement>.Add(IGraphElement item)
|
||||
{
|
||||
if (set.Add(item))
|
||||
{
|
||||
OnChange();
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public void CopyTo(IGraphElement[] array, int arrayIndex)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(array));
|
||||
}
|
||||
|
||||
if (arrayIndex < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(arrayIndex));
|
||||
}
|
||||
|
||||
if (array.Length - arrayIndex < Count)
|
||||
{
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
var i = 0;
|
||||
|
||||
foreach (var item in this)
|
||||
{
|
||||
array[i + arrayIndex] = item;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3bc7e638b15234ae8a1cf72b3fbc18da
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,38 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public interface IGraphContext : IDisposable
|
||||
{
|
||||
GraphReference reference { get; }
|
||||
|
||||
IEnumerable<IGraphContextExtension> extensions { get; }
|
||||
|
||||
IGraph graph { get; }
|
||||
|
||||
ICanvas canvas { get; }
|
||||
|
||||
GraphSelection selection { get; }
|
||||
|
||||
Metadata graphMetadata { get; }
|
||||
|
||||
Metadata selectionMetadata { get; }
|
||||
|
||||
Metadata ElementMetadata(IGraphElement element);
|
||||
|
||||
AnalyserProvider analyserProvider { get; }
|
||||
|
||||
string windowTitle { get; }
|
||||
|
||||
IEnumerable<ISidebarPanelContent> sidebarPanels { get; }
|
||||
|
||||
bool isPrefabInstance { get; }
|
||||
|
||||
void BeginEdit(bool disablePrefabInstance = true);
|
||||
|
||||
void EndEdit();
|
||||
|
||||
void DescribeAndAnalyze();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 69bdd2cb2fe1e4971b4013934b9098d6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue