using System;
using System.Linq;
using UnityEngine;
namespace MoreMountains.Tools
{
///
/// A base class implementing the IMMPersistent interface, designed to be extended
/// This mostly takes care of the GUID generation and validation
///
[AddComponentMenu("")]
public class MMPersistentBase : MonoBehaviour, IMMPersistent
{
[Header("Save")]
/// whether or not this object should be saved
[Tooltip("whether or not this object should be saved")]
public bool SaveActive = true;
[Header("ID")]
/// an optional suffix to add to the GUID, to make it more readable
[Tooltip("an optional suffix to add to the GUID, to make it more readable")]
public string UniqueIDSuffix;
/// the object's unique ID
[Tooltip("the object's unique ID")]
[SerializeField]
[MMReadOnly]
protected string _guid;
/// a debug button used to force a new GUI generation
[MMInspectorButton("GenerateGuid")]
public bool GenerateGuidButton;
///
/// On validate, we make sure the object gets a valid GUID
///
protected virtual void OnValidate()
{
ValidateGuid();
}
///
/// Returns the object's GUID
///
///
public virtual string GetGuid() => _guid;
///
/// Lets you set the object's GUID
///
///
public virtual void SetGuid(string newGUID) => _guid = newGUID;
///
/// On save, does nothing, meant to be extended
///
///
public virtual string OnSave()
{
return string.Empty;
}
///
/// On load, does nothing, meant to be extended
///
///
public virtual void OnLoad(string data)
{
}
///
/// Lets the persistency manager know whether or not the object should be saved
///
///
public virtual bool ShouldBeSaved()
{
return SaveActive;
}
///
/// Generates a unique ID for the object, using the scene name, the object name, and a GUID
///
///
public virtual string GenerateGuid()
{
string newGuid = Guid.NewGuid().ToString();
string guid =
this.gameObject.scene.name
+ "-"
+ this.gameObject.name
+ "-"
+ newGuid;
if (!string.IsNullOrEmpty(UniqueIDSuffix))
{
guid += "-" + UniqueIDSuffix;
}
this.SetGuid(guid);
return guid;
}
///
/// Checks if the object's ID is unique or not
///
///
///
public virtual bool GuidIsUnique(string guid)
{
return Resources.FindObjectsOfTypeAll().Count(x => x.GetGuid() == guid) == 1;
}
///
/// Validates the object's GUID, and generates a new one if needed, until a unique one is found
///
public virtual void ValidateGuid()
{
if (!this.gameObject.scene.IsValid())
{
_guid = string.Empty;
return;
}
int maxCount = 1000;
int i = 0;
while ( (string.IsNullOrEmpty(_guid) || !GuidIsUnique(_guid) ) && (i < maxCount) )
{
GenerateGuid();
i++;
}
if (i == maxCount)
{
Debug.LogWarning(this.gameObject.name + " couldn't generate a unique GUID after " + maxCount + " tries, you should probably change its UniqueIDSuffix");
}
}
}
}