ProjectDDD/Assets/_Datas/SLShared/SLSystem/SLEntity/SLEntity.cs
2025-06-17 20:47:57 +09:00

941 lines
23 KiB (Stored with Git LFS)
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Superlazy
{
public abstract class SLEntity : IEnumerable<SLEntity>, IComparable<SLEntity>
{
public abstract bool IsNumeric { get; }
public abstract bool IsValue { get; }
public abstract string ID { get; }
public abstract bool IsModified(string child);
public abstract void EndModified();
public abstract bool HasChild(string attributeKey);
internal abstract object GetObj();
internal abstract int GetInt();
internal abstract double GetDouble();
internal abstract string GetString();
internal abstract bool IsExist();
protected abstract int GetEntityHashCode();
internal static IEnumerable<SLEntity> emptyEnumerable = Enumerable.Empty<SLEntity>();
public abstract IEnumerator<SLEntity> GetEnumerator();
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public SLEntity this[SLEntity attributeKey]
{
get
{
if (attributeKey.IsNullOrFalse())
{
SLLog.Warn($"attributeKey shouldn't null obj {ToString()}, {ID}");
#if SERVER && LOCALTEST
throw new Exception();
#endif
return Empty;
}
return this[attributeKey.ToString()];
}
set
{
if (attributeKey.IsNullOrFalse())
{
SLLog.Warn($"attributeKey shouldn't null obj {ToString()}, {ID}");
#if SERVER && LOCALTEST
throw new Exception();
#endif
return;
}
this[attributeKey.ToString()] = value;
}
}
public abstract SLEntity this[string attributeKey]
{
get;
set;
}
public abstract SLEntity Clone();
public abstract SLEntity Link();
public abstract SLEntity Override();
public static SLEntity Empty => new SLContainer(null, null, null);
public static implicit operator double(SLEntity v)
{
return v.GetDouble();
}
public static implicit operator float(SLEntity v)
{
return (float)v.GetDouble();
}
public static implicit operator int(SLEntity v)
{
return v.GetInt();
}
public static implicit operator string(SLEntity v)
{
return v.GetString();
}
public static implicit operator bool(SLEntity v)
{
return v != default(SLEntity) && v.IsExist();
}
//public static implicit operator Vector2(SLEntity v)
//{
// return new Vector2(v["X"], v["Y"]);
//}
public static bool operator <(SLEntity lhs, SLEntity rhs)
{
if (lhs == null && rhs == null)
{
return 0 < 0;
}
else if (lhs.IsNullOrFalse())
{
return 0 < rhs.GetDouble();
}
else if (rhs.IsNullOrFalse())
{
return lhs.GetDouble() < 0;
}
else
{
return lhs.GetDouble() < rhs.GetDouble();
}
}
public static bool operator >(SLEntity lhs, SLEntity rhs)
{
if (lhs == null && rhs == null)
{
return 0 > 0;
}
else if (lhs.IsNullOrFalse())
{
return 0 > rhs.GetDouble();
}
else if (rhs.IsNullOrFalse())
{
return lhs.GetDouble() > 0;
}
return lhs.GetDouble() > rhs.GetDouble();
}
public static bool operator <=(SLEntity lhs, SLEntity rhs)
{
if (lhs == null && rhs == null)
{
return 0 <= 0;
}
else if (lhs.IsNullOrFalse())
{
return 0 <= rhs.GetDouble();
}
else if (rhs.IsNullOrFalse())
{
return lhs.GetDouble() <= 0;
}
else
{
return lhs.GetDouble() <= rhs.GetDouble();
}
}
public static bool operator >=(SLEntity lhs, SLEntity rhs)
{
if (lhs == null && rhs == null)
{
return 0 >= 0;
}
else if (lhs.IsNullOrFalse())
{
return 0 >= rhs.GetDouble();
}
else if (rhs.IsNullOrFalse())
{
return lhs.GetDouble() >= 0;
}
else
{
return lhs.GetDouble() >= rhs.GetDouble();
}
}
public static SLEntity operator +(SLEntity single)
{
return single;
}
public static SLEntity operator -(SLEntity single)
{
if (single.IsNullOrFalse())
{
return 0;
}
return -single.GetDouble();
}
public static SLEntity operator +(SLEntity lhs, SLEntity rhs)
{
if (lhs.IsNullOrFalse())
{
return rhs;
}
if (rhs.IsNullOrFalse())
{
return lhs;
}
if (lhs.IsNumeric && rhs.IsNumeric)
return lhs.GetDouble() + rhs.GetDouble();
return lhs.ToString() + rhs.ToString();
}
public static double operator +(double lhs, SLEntity rhs)
{
if (rhs.IsNullOrFalse())
{
return lhs;
}
if (rhs.IsNumeric)
return lhs + rhs.GetDouble();
return lhs;
}
public static double operator +(SLEntity lhs, double rhs)
{
if (lhs.IsNullOrFalse())
{
return rhs;
}
if (lhs.IsNumeric)
return lhs.GetDouble() + rhs;
return rhs;
}
public static float operator +(float lhs, SLEntity rhs)
{
if (rhs.IsNullOrFalse())
{
return lhs;
}
if (rhs.IsNumeric)
return lhs + (float)rhs.GetDouble();
return lhs;
}
public static float operator +(SLEntity lhs, float rhs)
{
if (lhs.IsNullOrFalse())
{
return rhs;
}
if (lhs.IsNumeric)
return (float)lhs.GetDouble() + rhs;
return rhs;
}
public static int operator +(SLEntity lhs, int rhs)
{
if (lhs.IsNullOrFalse())
{
return rhs;
}
if (lhs.IsNumeric)
return lhs.GetInt() + rhs;
return rhs;
}
public static int operator +(int lhs, SLEntity rhs)
{
if (rhs.IsNullOrFalse())
{
return lhs;
}
if (rhs.IsNumeric)
return lhs + rhs.GetInt();
return lhs;
}
public static SLEntity operator -(SLEntity lhs, SLEntity rhs)
{
if (lhs.IsNullOrFalse())
{
if (rhs == default(SLEntity)) return 0;
return -rhs.GetDouble();
}
if (rhs.IsNullOrFalse())
{
return lhs;
}
return lhs.GetDouble() - rhs.GetDouble();
}
public static double operator -(double lhs, SLEntity rhs)
{
if (rhs.IsNullOrFalse())
{
return lhs;
}
if (rhs.IsNumeric)
return lhs - rhs.GetDouble();
return lhs;
}
public static double operator -(SLEntity lhs, double rhs)
{
if (lhs.IsNullOrFalse())
{
return -rhs;
}
if (lhs.IsNumeric)
return lhs.GetDouble() - rhs;
return -rhs;
}
public static float operator -(float lhs, SLEntity rhs)
{
if (rhs.IsNullOrFalse())
{
return lhs;
}
if (rhs.IsNumeric)
return lhs - (float)rhs.GetDouble();
return lhs;
}
public static float operator -(SLEntity lhs, float rhs)
{
if (lhs.IsNullOrFalse())
{
return -rhs;
}
if (lhs.IsNumeric)
return (float)lhs.GetDouble() - rhs;
return -rhs;
}
public static int operator -(SLEntity lhs, int rhs)
{
if (lhs.IsNullOrFalse())
{
return -rhs;
}
if (lhs.IsNumeric)
return lhs.GetInt() - rhs;
return rhs;
}
public static int operator -(int lhs, SLEntity rhs)
{
if (rhs.IsNullOrFalse())
{
return lhs;
}
if (rhs.IsNumeric)
return lhs - rhs.GetInt();
return lhs;
}
public static SLEntity operator *(SLEntity lhs, SLEntity rhs)
{
if (lhs.IsNullOrFalse())
{
return 0;
}
if (rhs.IsNullOrFalse())
{
return 0;
}
if (lhs.IsNumeric && rhs.IsNumeric)
return lhs.GetDouble() * rhs.GetDouble();
return 0;
}
public static double operator *(double lhs, SLEntity rhs)
{
if (rhs.IsNullOrFalse())
{
return 0;
}
if (rhs.IsNumeric)
return lhs * rhs.GetDouble();
return 0;
}
public static double operator *(SLEntity lhs, double rhs)
{
if (lhs.IsNullOrFalse())
{
return 0;
}
if (lhs.IsNumeric)
return lhs.GetDouble() * rhs;
return 0;
}
public static float operator *(float lhs, SLEntity rhs)
{
if (rhs.IsNullOrFalse())
{
return 0;
}
if (rhs.IsNumeric)
return lhs * (float)rhs.GetDouble();
return 0;
}
public static float operator *(SLEntity lhs, float rhs)
{
if (lhs.IsNullOrFalse())
{
return 0;
}
if (lhs.IsNumeric)
return (float)lhs.GetDouble() * rhs;
return 0;
}
public static int operator *(SLEntity lhs, int rhs)
{
if (lhs.IsNullOrFalse())
{
return 0;
}
if (lhs.IsNumeric)
return lhs.GetInt() * rhs;
return 0;
}
public static int operator *(int lhs, SLEntity rhs)
{
if (rhs.IsNullOrFalse())
{
return 0;
}
if (rhs.IsNumeric)
return lhs * rhs.GetInt();
return 0;
}
public static SLEntity operator /(SLEntity lhs, SLEntity rhs)
{
if (rhs.IsNullOrFalse())
{
SLLog.Warn($"Divide by 0 {lhs?.GetDouble() ?? 0} / 0");
if (lhs.IsNullOrFalse()) return 0;
else return Math.Sign(lhs.GetDouble()) * double.PositiveInfinity;
}
if (lhs.IsNullOrFalse())
{
return 0;
}
if (rhs.IsNumeric == false || rhs == 0.0)
{
SLLog.Warn($"Divide by 0 {lhs.GetDouble()} / 0");
return Math.Sign(lhs.GetDouble()) * double.PositiveInfinity;
}
return lhs.GetDouble() / rhs.GetDouble();
}
public static double operator /(double lhs, SLEntity rhs)
{
if (rhs.IsNullOrFalse())
{
SLLog.Warn($"Divide by 0 {lhs} / 0");
return Math.Sign(lhs) * double.PositiveInfinity;
}
if (rhs.IsNumeric == false || rhs == 0.0)
{
SLLog.Warn($"Divide by 0 {lhs} / 0");
return Math.Sign(lhs) * double.PositiveInfinity;
}
return lhs / rhs.GetDouble();
}
public static double operator /(SLEntity lhs, double rhs)
{
if (lhs.IsNullOrFalse())
{
return 0;
}
if (rhs == 0.0)
{
SLLog.Warn($"Divide by 0 {lhs.GetDouble()} / 0");
return Math.Sign(lhs.GetDouble()) * double.PositiveInfinity;
}
return lhs.GetDouble() / rhs;
}
public static float operator /(float lhs, SLEntity rhs)
{
if (rhs.IsNullOrFalse())
{
SLLog.Warn($"Divide by 0 {lhs} / 0");
return Math.Sign(lhs) * float.PositiveInfinity;
}
if (rhs.IsNumeric == false || rhs == 0.0)
{
SLLog.Warn($"Divide by 0 {lhs} / 0");
return Math.Sign(lhs) * float.PositiveInfinity;
}
return lhs / (float)rhs.GetDouble();
}
public static float operator /(SLEntity lhs, float rhs)
{
if (lhs.IsNullOrFalse())
{
return 0;
}
if (rhs == 0.0)
{
SLLog.Warn($"Divide by 0 {lhs.GetDouble()} / 0");
return Math.Sign(lhs.GetDouble()) * float.PositiveInfinity;
}
return (float)lhs.GetDouble() / rhs;
}
public static int operator /(int lhs, SLEntity rhs)
{
if (rhs.IsNullOrFalse())
{
SLLog.Warn($"Divide by 0 {lhs} / 0");
return lhs > 0 ? int.MaxValue : int.MinValue;
}
if (rhs.IsNumeric == false || rhs == 0.0)
{
SLLog.Warn($"Divide by 0 {lhs} / 0");
return lhs > 0 ? int.MaxValue : int.MinValue;
}
return lhs / rhs.GetInt();
}
public static int operator /(SLEntity lhs, int rhs)
{
if (lhs.IsNullOrFalse())
{
return 0;
}
if (rhs == 0)
{
SLLog.Warn($"Divide by 0 {lhs.GetInt()} / 0");
return lhs.GetInt() > 0 ? int.MaxValue : int.MinValue;
}
return lhs.GetInt() / rhs;
}
public static int operator %(SLEntity lhs, SLEntity rhs)
{
if (lhs.IsNullOrFalse())
{
return 0;
}
if (rhs.IsNullOrFalse())
{
SLLog.Warn($"Divide by 0 {lhs} / 0");
return lhs;
}
return lhs.GetInt() % rhs.GetInt();
}
public static int operator %(SLEntity lhs, int rhs)
{
if (lhs.IsNullOrFalse())
{
return 0;
}
if (rhs == 0)
{
SLLog.Warn($"Divide by 0 {lhs} / 0");
return lhs;
}
return lhs.GetInt() % rhs;
}
public static int operator %(int lhs, SLEntity rhs)
{
if (lhs == 0)
{
return 0;
}
if (rhs.IsNullOrFalse() || rhs.GetInt() == 0)
{
SLLog.Warn($"Divide by 0 {lhs} / 0");
return lhs;
}
return lhs % rhs.GetInt();
}
public static bool operator ==(SLEntity lhs, bool rhs)
{
if (lhs.IsNullOrFalse()) return !rhs;
else return lhs.IsExist() == rhs;
}
public static bool operator !=(SLEntity lhs, bool rhs)
{
return !(lhs == rhs);
}
public static bool operator ==(bool lhs, SLEntity rhs)
{
if (rhs.IsNullOrFalse()) return !lhs;
else return rhs.IsExist() == rhs;
}
public static bool operator !=(bool lhs, SLEntity rhs)
{
return !(rhs == lhs);
}
//public static bool operator ==(SLEntity lhs, string rhs)
//{
// return (string)lhs == rhs;
//}
//public static bool operator !=(SLEntity lhs, string rhs)
//{
// return !(lhs == rhs);
//}
//public static bool operator ==(string lhs, SLEntity rhs)
//{
// return rhs == lhs;
//}
//public static bool operator !=(string lhs, SLEntity rhs)
//{
// return !(rhs == lhs);
//}
public static bool operator ==(SLEntity lhs, int rhs)
{
return lhs.GetInt() == rhs;
}
public static bool operator !=(SLEntity lhs, int rhs)
{
return !(lhs == rhs);
}
public static bool operator ==(int lhs, SLEntity rhs)
{
return rhs == lhs;
}
public static bool operator !=(int lhs, SLEntity rhs)
{
return !(rhs == lhs);
}
public static bool operator ==(SLEntity lhs, double rhs)
{
return lhs.GetDouble() == rhs;
}
public static bool operator !=(SLEntity lhs, double rhs)
{
return !(lhs == rhs);
}
public static bool operator ==(double lhs, SLEntity rhs)
{
return rhs == lhs;
}
public static bool operator !=(double lhs, SLEntity rhs)
{
return !(rhs == lhs);
}
public static bool operator ==(SLEntity lhs, float rhs)
{
return lhs.GetDouble() == rhs;
}
public static bool operator !=(SLEntity lhs, float rhs)
{
return !(lhs == rhs);
}
public static bool operator ==(float lhs, SLEntity rhs)
{
return rhs == lhs;
}
public static bool operator !=(float lhs, SLEntity rhs)
{
return !(rhs == lhs);
}
//public static bool operator ==(SLEntity lhs, SLVector2 rhs)
//{
// return lhs["X"] == rhs.X && lhs["Y"] == rhs.Y;
//}
//public static bool operator !=(SLEntity lhs, SLVector2 rhs)
//{
// return lhs["X"] != rhs.X || lhs["Y"] != rhs.Y;
//}
public static bool operator ==(SLEntity lhs, SLEntity rhs)
{
if (ReferenceEquals(lhs, rhs))// 동일 객체
{
return true;
}
else if (lhs is null || lhs.IsExist() == false) // 빈객체
{
return rhs is null || rhs.IsExist() == false;
}
else if (rhs is null || rhs.IsExist() == false)
{
return lhs is null || lhs.IsExist() == false;
}
else if (lhs.IsValue && rhs.IsValue) // 값비교
{
if (lhs.IsNumeric == false || rhs.IsNumeric == false)
{
return lhs.GetString().Equals(rhs.GetString());
}
else
{
return lhs.GetDouble() == rhs.GetDouble();
}
}
else if (lhs.IsValue == false && rhs.IsValue == false) // 리스트
{
var lhsCount = lhs.Count();
var rhsCount = rhs.Count();
if (lhsCount != rhsCount)
{
return false;
}
foreach (var l in lhs)
{
if (rhs.HasChild(l.ID) == false)
{
return false;
}
if (l != rhs[l.ID])
{
return false;
}
}
return true;
}
return false;
}
public static bool operator !=(SLEntity lhs, SLEntity rhs)
{
return !(lhs == rhs);
}
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if ((obj is SLEntity) == false)
{
return obj.Equals(GetObj());
}
return (obj as SLEntity) == this;
}
public override int GetHashCode()
{
return GetEntityHashCode();
}
public static implicit operator SLEntity(string v)
{
if (v == null || v == string.Empty) return Empty;
else return new SLValueString(v);
}
public static implicit operator SLEntity(int v)
{
return new SLValueInt(v);
}
public static implicit operator SLEntity(double v)
{
return new SLValueDouble(v);
}
private static SLEntity boolTrue = new SLValueString("True");
//private static SLEntity boolFalse = new SLContainer(null, null, null);
public static implicit operator SLEntity(bool v)
{
if (v)
{
if (boolTrue.ID != null) boolTrue = new SLValueString("True");
return boolTrue;
}
else
{
return new SLContainer(null, null, null); // TODO: 성능상 수정 필요
//if (boolFalse || boolFalse.ID != null) boolFalse = new SLContainer(null, null, null);
//boolFalse.test = true;
//return boolFalse;
}
}
//public static implicit operator SLEntity(SLVector2 v)
//{
// var ret = new SLContainer(null);
// ret["X"] = v.X;
// ret["Y"] = v.Y;
// return ret;
//}
public override string ToString()
{
return GetString();
}
public int CompareTo(SLEntity other)
{
if (IsValue == false || other.IsValue == false)
{
// TODO: 리스트 비교 필요
return GetHashCode().CompareTo(other.GetHashCode());
}
if (IsNumeric && other.IsNumeric)
{
return GetDouble().CompareTo(other.GetDouble());
}
var thisSTR = GetString();
var otherSTR = other.GetString();
return thisSTR.CompareTo(otherSTR);
}
internal abstract SLEntity ToChild(SLContainerBase parent, string id);
internal abstract void Move(SLEntity parent, string id);
public static bool Changed(SLEntity lhs, SLEntity rhs)
{
if (lhs is null && rhs is null) return false;
if (lhs.IsNullOrFalse()) return rhs;
if (rhs.IsNullOrFalse()) return lhs;
if (lhs.IsValue && rhs.IsValue)
{
return lhs != rhs;
}
return false;
}
}
}