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;
}
}
}
}