DesignScriptEntity
using Autodesk.DesignScript.Geometry.Core;
using Autodesk.DesignScript.Geometry.Properties;
using Autodesk.DesignScript.Interfaces;
using Autodesk.DesignScript.Runtime;
using DynamoServices;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
namespace Autodesk.DesignScript.Geometry
{
[SupressImportIntoVM]
public abstract class DesignScriptEntity : IDisposable
{
private IDesignScriptEntity mEntity;
protected Func<IDesignScriptEntity> mConstructor;
private const double AsmModelerUpperExtent = 10000;
private const double AsmModelerLowerExtent = 0.0001;
internal int constructorThreadId;
internal bool disposedWrongThread;
[SupressImportIntoVM]
public EntityTags Tags = new EntityTags(null, null);
private int? mHashCode;
private static Dictionary<double, string> scaleRanges = new Dictionary<double, string> {
{
0.01,
"Small"
},
{
1,
"Medium"
},
{
100,
"Large"
},
{
10000,
"Extra Large"
}
};
internal bool IsDisposed { get; set; }
internal virtual IDesignScriptEntity HostImpl {
get {
if (mEntity == null && mConstructor != null)
InitEntity(mConstructor());
return mEntity;
}
}
public static double scaleFactor => HostFactory.Instance.ScaleFactor;
internal T Track<T>(T childGeometry) where T : DesignScriptEntity
{
childGeometry.Tags.Parent = this;
return childGeometry;
}
internal IEnumerable<T> Track<T>(IEnumerable<T> childGeometries) where T : DesignScriptEntity
{
return from x in childGeometries
select Track(x);
}
internal T[] Track<T>(T[] childGeometries) where T : DesignScriptEntity
{
return (from x in childGeometries
select Track(x)).ToArray();
}
internal DesignScriptEntity(Func<IDesignScriptEntity> constructor)
{
mConstructor = constructor;
constructorThreadId = Thread.CurrentThread.ManagedThreadId;
HostFactory.Instance.clearPendingDisposals();
}
internal DesignScriptEntity(IDesignScriptEntity entity, bool persist = true)
{
InitEntity(entity);
}
internal void InitEntity(IDesignScriptEntity entity)
{
if (entity == null)
throw new ArgumentNullException("host", Resources.NullIDesignScriptEntityException);
if (entity.get_Owner() != null)
throw new ArgumentException(Resources.OwnerExistingException, "host");
mEntity = entity;
mEntity.SetOwner((object)this);
constructorThreadId = Thread.CurrentThread.ManagedThreadId;
HostFactory.Instance.clearPendingDisposals();
}
public void Dispose()
{
if (Application.Instance.IsExecuting)
DisposeDisplayable();
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void DisposeDisplayable()
{
}
~DesignScriptEntity()
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
if (!IsDisposed) {
if (!disposing)
try {
HostFactory.Instance.MarkDSEntityForDisposal(this);
} catch (Exception) {
}
else {
if (constructorThreadId != Thread.CurrentThread.ManagedThreadId)
disposedWrongThread = true;
((IDisposable)mEntity).Dispose();
mEntity = null;
mConstructor = null;
IsDisposed = true;
}
}
}
public override string ToString()
{
return ((object)mEntity).ToString();
}
public sealed override int GetHashCode()
{
if (!mHashCode.HasValue)
mHashCode = ComputeHashCode();
return mHashCode.Value;
}
public sealed override bool Equals(object obj)
{
if (this == obj)
return true;
DesignScriptEntity designScriptEntity = obj as DesignScriptEntity;
if (designScriptEntity == null)
return false;
return Equals(designScriptEntity);
}
public void Tessellate(IRenderPackage package, TessellationParameters parameters)
{
IGraphicItem val = mEntity as IGraphicItem;
if (val != null) {
parameters.set_ScaleFactor(scaleFactor);
val.Tessellate(package, parameters);
}
}
private static Tuple<string, double, double> RecommendedScaleFactor(double input)
{
double num = 0;
double num2 = input / scaleFactor;
if (num2 >= 10000) {
double num3 = Math.Log10(input / 10000);
if (num3 % 1 == 0)
num3 += 1;
num = Math.Ceiling(num3);
} else if (num2 <= 0.0001) {
double num4 = Math.Log10(input / 0.0001);
if (num4 % 1 == 0)
num4 -= 1;
num = Math.Floor(num4);
}
if (num % 2 != 0)
num = ((num > 0) ? (num + 1) : (num - 1));
if (num < -2)
num = -2;
if (num > 4)
num = 4;
double num5 = Math.Pow(10, num);
return new Tuple<string, double, double>(scaleRanges[num5], num5 * 0.0001, num5 * 10000);
}
protected static void CheckArgsForAsmExtents(List<double> args)
{
double num = args.Max();
if (num / scaleFactor >= 10000) {
Tuple<string, double, double> tuple = RecommendedScaleFactor(num);
string empty = string.Empty;
if (tuple.Item2 > 100000000)
empty = Resources.ModelerExtentsExceeded;
else {
string upperModelerExtentExceeded = Resources.UpperModelerExtentExceeded;
string arg = tuple.Item1.ToString(CultureInfo.CurrentUICulture);
double num2 = tuple.Item2;
string arg2 = num2.ToString(CultureInfo.CurrentUICulture);
num2 = tuple.Item3;
empty = string.Format(upperModelerExtentExceeded, arg, arg2, num2.ToString("N0", CultureInfo.CurrentUICulture));
}
LogWarningMessageEvents.OnLogWarningMessage(empty);
}
}
protected virtual bool Equals(DesignScriptEntity dsentity)
{
if (mEntity == null)
return false;
if (mEntity == dsentity.mEntity)
return true;
return ((object)mEntity).GetHashCode() == ((object)dsentity.mEntity).GetHashCode();
}
protected virtual int ComputeHashCode()
{
int num = (mEntity != null) ? ((object)mEntity).GetHashCode() : 0;
if (num != 0)
return num;
return base.GetHashCode();
}
}
}