```
chore(bridge): 删除桥接包的提交记录和Git属性配置 删除了 .codely-bridge-commit 文件中存储的提交哈希值 移除了 .gitattributes 文件中的行结束符配置规则 ```
This commit is contained in:
1 parent
d26d323912
commit
13d0c80335
392 files changed
+1784
-1865
No files matched your search
@@ -0,0 +1 @@
|
||||
47f3110000c95eee5cd83c827e0f1f11585f7ae1
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+2
@@ -30,6 +30,8 @@ namespace UnityTcp.Editor.Helpers
|
||||
|
||||
static BridgeUpdateRestartPrompt()
|
||||
{
|
||||
if (EditorAutomationGuard.ShouldSkipBridgeAutoStart()) return;
|
||||
|
||||
EditorApplication.delayCall += TryShowPendingPrompt;
|
||||
}
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+2
@@ -113,6 +113,8 @@ namespace UnityTcp.Editor.Helpers
|
||||
|
||||
static DialogWatcher()
|
||||
{
|
||||
if (EditorAutomationGuard.ShouldSkipBridgeAutoStart()) return;
|
||||
|
||||
// Force main-thread-only static init NOW, on this ([InitializeOnLoad]) thread,
|
||||
// before any watcher thread exists: the Windows watcher thread reads
|
||||
// UnityTcpBridge.IsRunning in Notify, and if that were the bridge's first touch its
|
||||
File renamed without changes.
+34
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace UnityTcp.Editor.Helpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Restricts bridge auto-start to the main Editor process and supported automation runs.
|
||||
/// Set <see cref="AllowBridgeInBatchEnvVar"/> to opt in when integration tests need the bridge.
|
||||
/// </summary>
|
||||
internal static class EditorAutomationGuard
|
||||
{
|
||||
internal const string AllowBridgeInBatchEnvVar = "UNITY_TCP_ALLOW_BATCH";
|
||||
|
||||
internal static bool IsAutomatedEditorRun()
|
||||
=> Application.isBatchMode
|
||||
|| SystemInfo.graphicsDeviceType == GraphicsDeviceType.Null;
|
||||
|
||||
internal static bool ShouldSkipBridgeAutoStart()
|
||||
=> EditorProcessGuard.ShouldSkipEditorAutoStart()
|
||||
|| (IsAutomatedEditorRun()
|
||||
&& string.IsNullOrWhiteSpace(
|
||||
Environment.GetEnvironmentVariable(AllowBridgeInBatchEnvVar)));
|
||||
|
||||
internal static bool ShouldSkipBridgeAutoStart(
|
||||
bool isAssetImportWorker,
|
||||
bool isSecondaryEditor,
|
||||
bool isAutomatedEditorRun,
|
||||
bool allowBridgeInBatch)
|
||||
=> isAssetImportWorker
|
||||
|| isSecondaryEditor
|
||||
|| (isAutomatedEditorRun && !allowBridgeInBatch);
|
||||
}
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+135
@@ -0,0 +1,135 @@
|
||||
using System.Linq;
|
||||
using Codely.Newtonsoft.Json.Linq;
|
||||
using UnityEditor;
|
||||
#if UNITY_2021_2_OR_NEWER
|
||||
using UnityEditor.SceneManagement;
|
||||
#else
|
||||
using UnityEditor.Experimental.SceneManagement;
|
||||
#endif
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityTcp.Editor.Helpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Builds the standard Unity selection payload shared by
|
||||
/// <see cref="UnityTcp.Editor.Notifier.SelectionChangedNotifier"/> and
|
||||
/// <see cref="UnityTcp.Editor.Tools.ManageEditor"/>'s get_selection action,
|
||||
/// keeping the two callers in sync without duplicating logic.
|
||||
/// </summary>
|
||||
public static class SelectionPayloadBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructs a <see cref="JObject"/> describing the current Unity Editor selection.
|
||||
/// The caller is responsible for wrapping the result (e.g. in
|
||||
/// <see cref="Response.Success"/> or directly broadcasting it as a notification).
|
||||
/// </summary>
|
||||
public static JObject Build()
|
||||
{
|
||||
var assetGUIDs = Selection.assetGUIDs;
|
||||
var assetPaths = assetGUIDs?.Select(AssetDatabase.GUIDToAssetPath).ToArray();
|
||||
|
||||
string activeAssetPath = Selection.activeObject != null
|
||||
? AssetDatabase.GetAssetPath(Selection.activeObject)
|
||||
: null;
|
||||
string activeAsset = string.IsNullOrEmpty(activeAssetPath)
|
||||
? null
|
||||
: activeAssetPath.Replace('\\', '/');
|
||||
|
||||
bool isSubAsset = Selection.activeObject != null
|
||||
&& AssetDatabase.IsSubAsset(Selection.activeObject);
|
||||
string activeAssetFileId = string.IsNullOrEmpty(activeAsset)
|
||||
? null
|
||||
: Selection.activeObject.FormatLocalFileId();
|
||||
string activeAssetGuid = string.IsNullOrEmpty(activeAsset)
|
||||
? null
|
||||
: Selection.activeObject.GetAssetGuid();
|
||||
|
||||
var activeGo = Selection.activeGameObject;
|
||||
var goSource = activeGo != null && activeGo.scene.IsValid()
|
||||
? PrefabUtility.GetCorrespondingObjectFromSource(activeGo)
|
||||
: null;
|
||||
string sourcePrefabGuid = goSource != null
|
||||
? AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(goSource))
|
||||
: null;
|
||||
|
||||
var payload = new
|
||||
{
|
||||
activeObject = Selection.activeObject?.name,
|
||||
activeObjectKind = Selection.activeObject.GetKind(),
|
||||
activeAsset = activeAsset,
|
||||
// Decimal string: Tuanjie fileIDs can exceed JS Number / Int32.
|
||||
activeAssetLocalId = activeAssetFileId,
|
||||
activeAssetGuid = activeAssetGuid,
|
||||
activeSelectedSubAsset = isSubAsset && !string.IsNullOrEmpty(activeAssetFileId)
|
||||
? (object)new
|
||||
{
|
||||
type = Selection.activeObject.GetType().Name,
|
||||
name = Selection.activeObject.name,
|
||||
fileId = activeAssetFileId,
|
||||
}
|
||||
: null,
|
||||
activeGameObject = activeGo?.name,
|
||||
activeGameObjectScenePath = GetSceneOrPrefabPath(activeGo),
|
||||
// instanceID always refers to the GameObject, never Transform/component.
|
||||
// Decimal string: Unity 6.5 EntityId can exceed JS Number / 2^53.
|
||||
activeInstanceID = activeGo.FormatStableInstanceId() ?? "0",
|
||||
activeGameObjectFileId = activeGo.FormatLocalFileId(),
|
||||
activeGameObjectGuid = activeGo.FormatGlobalObjectGuid(),
|
||||
// Prefab instance children: fileId is the source-prefab local id,
|
||||
// not a scene YAML id. Pair with these to grep the prefab file.
|
||||
activeGameObjectIsPrefabInstanceChild = goSource != null,
|
||||
activeGameObjectSourcePrefabGuid = string.IsNullOrEmpty(sourcePrefabGuid) ? null : sourcePrefabGuid,
|
||||
activeGameObjectSourcePrefabFileId = goSource.FormatLocalFileId(),
|
||||
activeTransform = Selection.activeTransform?.name,
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
count = Selection.count,
|
||||
#else
|
||||
count = Selection.objects?.Length ?? 0,
|
||||
#endif
|
||||
objects = Selection.objects
|
||||
.Where(obj => obj != null)
|
||||
.Select(obj => new
|
||||
{
|
||||
name = obj.name,
|
||||
type = obj.GetType().FullName,
|
||||
instanceID = obj.FormatStableInstanceId(),
|
||||
})
|
||||
.ToList(),
|
||||
gameObjects = Selection.gameObjects
|
||||
.Where(go => go != null)
|
||||
.Select(go => new
|
||||
{
|
||||
name = go.name,
|
||||
path = go.GetHierarchyPathWithIndex(),
|
||||
instanceID = go.FormatStableInstanceId(),
|
||||
kind = go.GetKind(),
|
||||
fileId = go.FormatLocalFileId(),
|
||||
guid = go.FormatGlobalObjectGuid(),
|
||||
componentNames = go.GetComponentTypeNames(),
|
||||
})
|
||||
.ToList(),
|
||||
assetGUIDs = assetGUIDs,
|
||||
assetPaths = assetPaths,
|
||||
};
|
||||
|
||||
return JObject.FromObject(payload);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the scene or prefab asset path that owns <paramref name="go"/>,
|
||||
/// normalised to forward-slashes. Returns <c>null</c> for null input.
|
||||
/// </summary>
|
||||
public static string GetSceneOrPrefabPath(GameObject go)
|
||||
{
|
||||
if (go == null) return null;
|
||||
if (go.scene.IsValid() && !string.IsNullOrEmpty(go.scene.path))
|
||||
return go.scene.path.Replace('\\', '/');
|
||||
string stagePath = InstanceIdExtensions.GetPrefabStageAssetPath(
|
||||
PrefabStageUtility.GetPrefabStage(go));
|
||||
if (!string.IsNullOrEmpty(stagePath))
|
||||
return stagePath.Replace('\\', '/');
|
||||
string assetPath = AssetDatabase.GetAssetPath(go);
|
||||
return string.IsNullOrEmpty(assetPath) ? null : assetPath.Replace('\\', '/');
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 00ca19b90d0118744b3dae38cfcd149f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+16
-3
@@ -143,9 +143,22 @@ namespace UnityTcp.Editor.Helpers
|
||||
// Set from any thread when state changed outside the tick (a cross-thread detach);
|
||||
// consumed by Tick on the main thread, which owns persistence.
|
||||
private static volatile bool _saveRequested;
|
||||
private static bool _initialized;
|
||||
|
||||
static StepJobRunner()
|
||||
{
|
||||
if (EditorAutomationGuard.ShouldSkipBridgeAutoStart()) return;
|
||||
|
||||
EnsureInitialized();
|
||||
}
|
||||
|
||||
// Main-thread only. Explicit bridge/job starts need restoration too, even
|
||||
// when InitializeOnLoad deliberately skipped auto-start in this domain.
|
||||
internal static void EnsureInitialized()
|
||||
{
|
||||
if (_initialized) return;
|
||||
// Set before Load: a restored job's OnRestored may enroll another job.
|
||||
_initialized = true;
|
||||
Load();
|
||||
// Pending markers persist but only step jobs survive the reload; retire the rest so no
|
||||
// client is left polling a job that no longer exists.
|
||||
@@ -171,6 +184,7 @@ namespace UnityTcp.Editor.Helpers
|
||||
bool detached = false)
|
||||
{
|
||||
if (job == null) throw new ArgumentNullException(nameof(job));
|
||||
EnsureInitialized();
|
||||
|
||||
var ctx = new JobContext(requestId, name, detached);
|
||||
var entry = new Entry
|
||||
@@ -490,9 +504,8 @@ namespace UnityTcp.Editor.Helpers
|
||||
{
|
||||
Save();
|
||||
_entries.Clear();
|
||||
Load();
|
||||
DetachedJobs.ReconcilePending(
|
||||
_entries.Where(e => e.Detached).Select(e => e.JobId).ToList());
|
||||
_initialized = false;
|
||||
EnsureInitialized();
|
||||
}
|
||||
|
||||
private static void Load()
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+1
-8
@@ -55,24 +55,17 @@ namespace UnityTcp.Editor.Helpers
|
||||
"create",
|
||||
"modify",
|
||||
"delete",
|
||||
"add_component",
|
||||
"remove_component",
|
||||
"set_component_property"
|
||||
},
|
||||
["manage_asset"] = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
"import",
|
||||
"ensure_prefab_variant",
|
||||
"create",
|
||||
"modify",
|
||||
"delete",
|
||||
"duplicate",
|
||||
"move"
|
||||
"modify"
|
||||
},
|
||||
["manage_scene"] = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
"ensure_scene_open",
|
||||
"ensure_scene_saved",
|
||||
"create",
|
||||
"load",
|
||||
"save"
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
+16
@@ -0,0 +1,16 @@
|
||||
namespace UnityTcp.Editor.Native
|
||||
{
|
||||
// Managed code only enables the feature; native window probes decide when to show.
|
||||
internal static class EditorBusyProxy
|
||||
{
|
||||
internal const bool BusyWindowEnabled = true;
|
||||
|
||||
internal static void Refresh()
|
||||
{
|
||||
#if UNITY_EDITOR_WIN
|
||||
try { NativeUnityTcpBridgeAPI.NTB_SetEditorBusyProxyEnabled?.Invoke(BusyWindowEnabled ? 1 : 0); }
|
||||
catch { /* Optional UI must not interrupt bridge startup. */ }
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ff8b1598a9bb4fbd8067e7245bc1f68d
|
||||
+28
-1
@@ -169,6 +169,13 @@ namespace UnityTcp.Editor.Native
|
||||
|
||||
static NativeDllLoader()
|
||||
{
|
||||
if (EditorAutomationGuard.ShouldSkipBridgeAutoStart()) return;
|
||||
|
||||
RegisterCleanupHandlers();
|
||||
}
|
||||
|
||||
private static void RegisterCleanupHandlers()
|
||||
{
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
UnityEditor.PackageManager.Events.registeringPackages -= OnPackagesRegistering;
|
||||
UnityEditor.PackageManager.Events.registeringPackages += OnPackagesRegistering;
|
||||
@@ -264,6 +271,8 @@ namespace UnityTcp.Editor.Native
|
||||
private static void RegisterLogCallback()
|
||||
{
|
||||
if (!IsLoaded) return;
|
||||
// Explicit starts need cleanup too, even when bridge auto-start is disabled.
|
||||
RegisterCleanupHandlers();
|
||||
try
|
||||
{
|
||||
_logCallback = (level, message) =>
|
||||
@@ -351,6 +360,8 @@ namespace UnityTcp.Editor.Native
|
||||
{
|
||||
if (_handle == IntPtr.Zero) return;
|
||||
OnUnload?.Invoke(reason);
|
||||
// Stop/join native workers even when no managed bridge subscribed to OnUnload.
|
||||
NativeUnityTcpBridgeHost.StopServer(reason);
|
||||
UnregisterLogCallback();
|
||||
PlatformFree(_handle);
|
||||
_handle = IntPtr.Zero;
|
||||
@@ -369,6 +380,7 @@ namespace UnityTcp.Editor.Native
|
||||
NativeUnityTcpBridgeAPI.NTB_ResumeManagedCommandProcessing = null;
|
||||
NativeUnityTcpBridgeAPI.NTB_NotifyAll = null;
|
||||
NativeUnityTcpBridgeAPI.NTB_SetStreamPort = null;
|
||||
NativeUnityTcpBridgeAPI.NTB_SetEditorBusyProxyEnabled = null;
|
||||
SetLogCallback = null;
|
||||
SessionState.EraseString(HandleKey);
|
||||
}
|
||||
@@ -405,7 +417,7 @@ namespace UnityTcp.Editor.Native
|
||||
{
|
||||
if (!CheckAbiVersion()) return false;
|
||||
|
||||
return
|
||||
bool resolved =
|
||||
Resolve("NTB_StartBridge", ref NativeUnityTcpBridgeAPI.NTB_StartBridge) &&
|
||||
Resolve("NTB_StopWithReason", ref NativeUnityTcpBridgeAPI.NTB_StopWithReason) &&
|
||||
Resolve("NTB_Stop", ref NativeUnityTcpBridgeAPI.NTB_Stop) &&
|
||||
@@ -421,6 +433,13 @@ namespace UnityTcp.Editor.Native
|
||||
Resolve("NTB_NotifyAll", ref NativeUnityTcpBridgeAPI.NTB_NotifyAll) &&
|
||||
Resolve("NTB_SetStreamPort", ref NativeUnityTcpBridgeAPI.NTB_SetStreamPort) &&
|
||||
Resolve("Log_SetCallback", ref SetLogCallback);
|
||||
if (!resolved) return false;
|
||||
|
||||
#if UNITY_EDITOR_WIN
|
||||
// The busy-Editor proxy is optional; failure to bind it must not disable commands.
|
||||
ResolveOptional("NTB_SetEditorBusyProxyEnabled", ref NativeUnityTcpBridgeAPI.NTB_SetEditorBusyProxyEnabled);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool CheckAbiVersion()
|
||||
@@ -464,6 +483,14 @@ namespace UnityTcp.Editor.Native
|
||||
return true;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR_WIN
|
||||
private static void ResolveOptional<T>(string symbol, ref T del) where T : Delegate
|
||||
{
|
||||
IntPtr ptr = GetProcAddress(_handle, symbol);
|
||||
del = ptr == IntPtr.Zero ? null : Marshal.GetDelegateForFunctionPointer<T>(ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
private static string PluginPathUnder(string packageRoot)
|
||||
{
|
||||
if (string.IsNullOrEmpty(packageRoot)) return null;
|
||||
File renamed without changes.
+4
@@ -61,6 +61,9 @@ namespace UnityTcp.Editor.Native
|
||||
// NTB_StartBridge — safe to call at any time.
|
||||
internal delegate void SetStreamPortDelegate(int streamPort);
|
||||
|
||||
// Optional Windows busy-Editor proxy; unavailable UI must not block commands.
|
||||
internal delegate void SetEditorBusyProxyEnabledDelegate(int enabled);
|
||||
|
||||
internal static GetAbiVersionDelegate NTB_GetAbiVersion;
|
||||
internal static StartBridgeDelegate NTB_StartBridge;
|
||||
internal static StopDelegate NTB_Stop;
|
||||
@@ -76,6 +79,7 @@ namespace UnityTcp.Editor.Native
|
||||
internal static ResumeManagedCommandProcessingDelegate NTB_ResumeManagedCommandProcessing;
|
||||
internal static NotifyAllDelegate NTB_NotifyAll;
|
||||
internal static SetStreamPortDelegate NTB_SetStreamPort;
|
||||
internal static SetEditorBusyProxyEnabledDelegate NTB_SetEditorBusyProxyEnabled;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
File renamed without changes.
+1
@@ -52,6 +52,7 @@ namespace UnityTcp.Editor.Native
|
||||
try
|
||||
{
|
||||
#if UNITY_EDITOR_WIN || UNITY_EDITOR_OSX || UNITY_EDITOR_LINUX
|
||||
EditorBusyProxy.Refresh();
|
||||
// After a domain reload the managed side restarts but the native server
|
||||
// remains bound to its existing port. Probe first so we attach to the
|
||||
// existing listener instead of relying solely on NTB_StartBridge's idempotency.
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loaded 100 of 392 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user