using System; using System.Collections.Generic; using System.Linq; using UnityEngine; namespace OM { /// /// Central manager for handling object copy-paste functionality using JSON serialization. /// public static class OM_CopyPasteManager { private static readonly Dictionary CopyPasteInstances = new(); /// /// Gets the copy-paste instance for a specific type. /// public static OM_CopyPasteInstance GetCopyPasteInstance() { if (CopyPasteInstances.TryGetValue(typeof(T), out var instance)) return instance; var newInstance = new OM_CopyPasteInstance(); CopyPasteInstances.Add(typeof(T), newInstance); return newInstance; } /// /// Creates a deep duplicate of the object using JSON serialization. /// public static T Duplicate(T toConvert) { var asJson = new OM_AsJson { JsonText = JsonUtility.ToJson(toConvert), Type = toConvert.GetType() }; return (T)JsonUtility.FromJson(asJson.JsonText, asJson.Type); } /// /// Copies a single object to the internal clipboard. /// public static void Copy(T toCopyObject) { GetCopyPasteInstance().Copy(toCopyObject); } /// /// Copies a list of objects to the internal clipboard. /// public static void CopyList(List toCopyObjects) { GetCopyPasteInstance().CopyList(toCopyObjects); } /// /// Pastes all copied objects as a list of the given type. /// public static List Paste() { return GetCopyPasteInstance().Paste(); } /// /// Checks if there is a valid paste buffer for a given type. /// public static bool CanPaste() { return GetCopyPasteInstance().CanPaste(); } /// /// Gets whether the current buffer contains one or multiple objects. /// public static OM_CopyType GetCopyType() { return GetCopyPasteInstance().GetCopyType(); } } /// /// Struct representing a serialized object along with its type. /// public struct OM_AsJson { public Type Type; public string JsonText; public override string ToString() { return $"Type: {Type} Json: {JsonText}"; } } /// /// Enum indicating if a copy action involved a single or multiple objects. /// public enum OM_CopyType { Single, Multiple, } /// /// Represents a single copy-paste instance for a specific type. /// public class OM_CopyPasteInstance { public event Action OnCopyPasteCallback; private List _copiedObjects = new(); /// /// Copies a single object to the buffer. /// public void Copy(T toCopyObject) { if (toCopyObject == null) return; _copiedObjects ??= new List(); _copiedObjects.Clear(); _copiedObjects.Add(GetAsJson(toCopyObject)); OnCopyPasteCallback?.Invoke(true, OM_CopyType.Single); } /// /// Copies a list of objects to the buffer. /// public void CopyList(List toCopyObjects) { if (toCopyObjects == null || toCopyObjects.Count == 0) return; _copiedObjects ??= new List(); _copiedObjects.Clear(); foreach (var copy in toCopyObjects) { _copiedObjects.Add(GetAsJson(copy)); } OnCopyPasteCallback?.Invoke(true, OM_CopyType.Multiple); } /// /// Pastes all copied objects as a list. /// public List Paste() { if (_copiedObjects == null) return null; var toPasteList = _copiedObjects.Select(GetObjectFromJson).ToList(); _copiedObjects = null; OnCopyPasteCallback?.Invoke(false, toPasteList.Count > 1 ? OM_CopyType.Multiple : OM_CopyType.Single); return toPasteList; } /// /// Returns the number of copied objects currently stored. /// public int GetCopyCount() => _copiedObjects?.Count ?? 0; /// /// Checks if pasting is possible. /// public bool CanPaste() => _copiedObjects is { Count: > 0 }; /// /// Returns the copy type: single or multiple. /// public OM_CopyType GetCopyType() => _copiedObjects == null || _copiedObjects.Count <= 1 ? OM_CopyType.Single : OM_CopyType.Multiple; private static OM_AsJson GetAsJson(object o) { return new OM_AsJson { Type = o.GetType(), JsonText = JsonUtility.ToJson(o) }; } private static T GetObjectFromJson(OM_AsJson asJson) { try { return (T)JsonUtility.FromJson(asJson.JsonText, asJson.Type); } catch (Exception e) { Debug.LogError(e); throw; } } } }