// Copyright 2018 RED Software, LLC. All Rights Reserved.
using System;
using System.Collections.Generic;
namespace IgniteEngine
{
///
/// Class for objects that can be referenced.
///
public class Object : IDisposable
{
///
/// The name of the object.
///
public string Name => GetName();
///
/// Keeps track of the number of all object types.
///
private static readonly Dictionary TypeCounts = new Dictionary();
///
/// An object to lock for TypeCounts access.
///
private static readonly object TypeCountsLock = new object();
///
/// Creates a new instance of the class.
///
public Object()
{
var type = GetType();
EnsureTypeExists(type);
lock (TypeCountsLock)
{
TypeCounts[type]++;
}
}
///
/// This method is called whenever an is deconstructed.
///
~Object()
{
var type = GetType();
EnsureTypeExists(type);
lock (TypeCountsLock)
{
TypeCounts[type]--;
}
}
///
/// Destroys the object.
///
/// The object to destroy.
public static void Destroy(Object obj)
{
obj.Dispose();
}
///
/// Determines if the object exists.
///
/// The object to check.
public static implicit operator bool(Object obj)
{
return obj != null;
}
///
/// Ensures that the TypeCounts dictionary contains the type.
/// If the type is not found, it is added to the dictionary with a count of 0.
///
/// The type to check for.
private static void EnsureTypeExists(Type type)
{
lock (TypeCountsLock)
{
if (!TypeCounts.ContainsKey(type))
{
TypeCounts.Add(type, 0);
}
}
}
///
/// Use the static method Object.Destroy() instead.
///
public void Dispose()
{
Destroy();
}
///
/// Gets the name of the object instance. The name is based on how
/// many instances of the object there are.
///
/// The name of the object.
public string GetName()
{
var type = GetType();
EnsureTypeExists(type);
lock (TypeCountsLock)
{
return $"{type.Name} {TypeCounts[type]}";
}
}
///
/// Returns the name of the object.
///
/// The name of the object.
public override string ToString()
{
return Name;
}
///
/// This method does nothing unless it is overidded by the top-level
/// implementation of the class.
///
protected virtual void Destroy()
{
}
}
}