using System; namespace Unity.Pipeline.Editor.Commands.Animation { /// /// Presence guard for the optional com.unity.timeline package (CLI-214, Group C). /// /// The Editor assembly deliberately does NOT reference Unity.Timeline (an asmdef reference /// would break compilation in any project that doesn't have the package installed). Instead, the /// Timeline commands reach the package via reflection, and this guard reports whether the package's /// core type is loadable — the optional-package guard pattern for commands backed by a package that /// may not be present. /// /// The guard caches its result for the lifetime of the domain; a package add/remove triggers a /// domain reload, which resets the cache. /// public static class TimelineGuard { /// The package id, surfaced in the not-installed error message. public const string PackageId = "com.unity.timeline"; /// Assembly-qualified name of the package's root asset type. public const string TimelineAssetTypeName = "UnityEngine.Timeline.TimelineAsset, Unity.Timeline"; private static bool? s_Installed; /// /// True when the Timeline package is installed (its TimelineAsset type resolves). /// public static bool IsInstalled() { if (s_Installed.HasValue) return s_Installed.Value; s_Installed = ResolveTimelineAssetType() != null; return s_Installed.Value; } /// /// The UnityEngine.Timeline.TimelineAsset , or null if the package is /// absent. Callers use this as the entry point for further reflection. /// public static Type ResolveTimelineAssetType() => Type.GetType(TimelineAssetTypeName, throwOnError: false); /// /// The structured "package not installed" error (HTTP 200, no exception) that every Timeline /// command returns when is false. /// public static ErrorResult NotInstalledError() => ErrorResult.PackageStyle("package_not_found", $"{PackageId} is not installed"); } }