update exceptions

This commit is contained in:
Mikhail 2023-06-26 01:57:50 +08:00
parent 4b7649e80c
commit f07a489d96
9 changed files with 132 additions and 100 deletions

View File

@ -2,7 +2,7 @@
using DCFApixels.DragonECS.RunnersCore;
using System;
using System.Linq;
using System.Runtime.CompilerServices;
using static DCFApixels.DragonECS.EcsThrowHalper;
namespace DCFApixels.DragonECS
{
@ -59,12 +59,10 @@ namespace DCFApixels.DragonECS
private EcsBaseTypeInjectRunner _baseTypeInjectRunner;
void IEcsInject<T>.Inject(T obj)
{
if (obj == null) ThrowArgumentNullException();
if (obj == null) Throw.ArgumentNull();
_baseTypeInjectRunner.Inject(obj);
foreach (var item in targets) item.Inject(obj);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ThrowArgumentNullException() => throw new ArgumentNullException();
protected override void OnSetup()
{
Type baseType = typeof(T).BaseType;
@ -112,7 +110,7 @@ namespace DCFApixels.DragonECS
void IEcsInject<PreInitInjectController>.Inject(PreInitInjectController obj) => _injectController = obj;
public InjectSystem(T injectedData)
{
if (injectedData == null) throw new ArgumentNullException();
if (injectedData == null) Throw.ArgumentNull();
_injectedData = injectedData;
}
public void PreInit(EcsPipeline pipeline)
@ -149,7 +147,7 @@ namespace DCFApixels.DragonECS
{
public static EcsPipeline.Builder Inject<T>(this EcsPipeline.Builder self, T data)
{
if (data == null) throw new ArgumentNullException();
if (data == null) Throw.ArgumentNull();
return self.Add(new InjectSystem<T>(data));
}
public static EcsPipeline.Builder Inject<A, B>(this EcsPipeline.Builder self, A a, B b)

View File

@ -6,14 +6,13 @@ using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using static DCFApixels.DragonECS.EcsThrowHalper;
namespace DCFApixels.DragonECS
{
public abstract class EcsAspect
{
[EditorBrowsable(EditorBrowsableState.Always)]
internal EcsWorld source;
[EditorBrowsable(EditorBrowsableState.Always)]
internal EcsMask mask;
private bool _isInit;
@ -85,7 +84,7 @@ namespace DCFApixels.DragonECS
{
int id = _world.GetComponentID(type);
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (_inc.Contains(id) || _exc.Contains(id)) throw new EcsFrameworkException($"{type.Name} already in constraints list.");
if (_inc.Contains(id) || _exc.Contains(id)) Throw.ConstraintIsAlreadyContainedInMask(type);
#endif
_inc.Add(id);
}
@ -93,7 +92,7 @@ namespace DCFApixels.DragonECS
{
int id = _world.GetComponentID(type);
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (_inc.Contains(id) || _exc.Contains(id)) throw new EcsFrameworkException($"{type.Name} already in constraints list.");
if (_inc.Contains(id) || _exc.Contains(id)) Throw.ConstraintIsAlreadyContainedInMask(type);
#endif
_exc.Add(id);
}
@ -279,14 +278,6 @@ namespace DCFApixels.DragonECS
public override string ToString() => CreateLogString(worldTypeID, included, excluded);
}
#endregion
#region ThrowHelper
internal static class ThrowHelper
{
[MethodImpl(MethodImplOptions.NoInlining)]
public static void ThrowArgumentDifferentWorldsException() => throw new ArgumentException("The groups belong to different worlds.");
}
#endregion
}
#endregion

View File

@ -6,7 +6,7 @@ using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
using static DCFApixels.DragonECS.EcsGroup.ThrowHelper;
using static DCFApixels.DragonECS.EcsThrowHalper;
#endif
namespace DCFApixels.DragonECS
@ -151,7 +151,7 @@ namespace DCFApixels.DragonECS
get
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (index < 0 || index >= Count) ThrowArgumentOutOfRange();
if (index < 0 || index >= Count) Throw.ArgumentOutOfRange();
#endif
return _dense[++index];
}
@ -200,7 +200,7 @@ namespace DCFApixels.DragonECS
internal void AddInternal(int entityID)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (Has(entityID)) ThrowAlreadyContains(entityID);
if (Has(entityID)) Throw.Group_AlreadyContains(entityID);
#endif
if (++_count >= _dense.Length)
Array.Resize(ref _dense, _dense.Length << 1);
@ -218,7 +218,7 @@ namespace DCFApixels.DragonECS
internal void RemoveInternal(int entityID)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (!Has(entityID)) ThrowDoesNotContain(entityID);
if (!Has(entityID)) Throw.Group_DoesNotContain(entityID);
#endif
_dense[_sparse[entityID]] = _dense[_count];
_sparse[_dense[_count--]] = _sparse[entityID];
@ -287,7 +287,7 @@ namespace DCFApixels.DragonECS
public ReadOnlySpan<int> ToSpan(int start, int length)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (start + length > _count) ThrowArgumentOutOfRangeException();
if (start + length > _count) Throw.ArgumentOutOfRange();
#endif
return new ReadOnlySpan<int>(_dense, start, length);
}
@ -301,7 +301,7 @@ namespace DCFApixels.DragonECS
public void UnionWith(EcsGroup group)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (_source != group.World) ThrowArgumentDifferentWorldsException();
if (_source != group.World) Throw.Group_ArgumentDifferentWorldsException();
#endif
foreach (var item in group)
if (!Has(item))
@ -315,7 +315,7 @@ namespace DCFApixels.DragonECS
public void ExceptWith(EcsGroup group)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (_source != group.World) ThrowArgumentDifferentWorldsException();
if (_source != group.World) Throw.Group_ArgumentDifferentWorldsException();
#endif
foreach (var item in this)
if (group.Has(item))
@ -329,7 +329,7 @@ namespace DCFApixels.DragonECS
public void IntersectWith(EcsGroup group)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (World != group.World) ThrowArgumentDifferentWorldsException();
if (World != group.World) Throw.Group_ArgumentDifferentWorldsException();
#endif
foreach (var item in this)
if (!group.Has(item))
@ -343,7 +343,7 @@ namespace DCFApixels.DragonECS
public void SymmetricExceptWith(EcsGroup group)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (_source != group.World) ThrowArgumentDifferentWorldsException();
if (_source != group.World) Throw.Group_ArgumentDifferentWorldsException();
#endif
foreach (var item in group)
if (Has(item))
@ -367,7 +367,7 @@ namespace DCFApixels.DragonECS
public static EcsGroup Union(EcsGroup a, EcsGroup b)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (a._source != b._source) ThrowArgumentDifferentWorldsException();
if (a._source != b._source) Throw.Group_ArgumentDifferentWorldsException();
#endif
EcsGroup result = a._source.GetFreeGroup();
foreach (var item in a)
@ -381,7 +381,7 @@ namespace DCFApixels.DragonECS
public static EcsGroup Except(EcsGroup a, EcsGroup b)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (a._source != b._source) ThrowArgumentDifferentWorldsException();
if (a._source != b._source) Throw.Group_ArgumentDifferentWorldsException();
#endif
EcsGroup result = a._source.GetFreeGroup();
foreach (var item in a)
@ -394,7 +394,7 @@ namespace DCFApixels.DragonECS
public static EcsGroup Intersect(EcsGroup a, EcsGroup b)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (a._source != b._source) ThrowArgumentDifferentWorldsException();
if (a._source != b._source) Throw.Group_ArgumentDifferentWorldsException();
#endif
EcsGroup result = a._source.GetFreeGroup();
foreach (var item in a)
@ -408,7 +408,7 @@ namespace DCFApixels.DragonECS
public static EcsGroup SymmetricExcept(EcsGroup a, EcsGroup b)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (a._source != b._source) ThrowArgumentDifferentWorldsException();
if (a._source != b._source) Throw.Group_ArgumentDifferentWorldsException();
#endif
EcsGroup result = a._source.GetFreeGroup();
foreach (var item in a)
@ -519,24 +519,6 @@ namespace DCFApixels.DragonECS
}
#endregion
#region ThrowHalper
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
internal static class ThrowHelper
{
[MethodImpl(MethodImplOptions.NoInlining)]
public static void ThrowAlreadyContains(int entityID) => throw new EcsFrameworkException($"This group already contains entity {entityID}.");
[MethodImpl(MethodImplOptions.NoInlining)]
public static void ThrowArgumentOutOfRange() => throw new ArgumentOutOfRangeException($"index is less than 0 or is equal to or greater than Count.");
[MethodImpl(MethodImplOptions.NoInlining)]
public static void ThrowDoesNotContain(int entityID) => throw new EcsFrameworkException($"This group does not contain entity {entityID}.");
[MethodImpl(MethodImplOptions.NoInlining)]
public static void ThrowArgumentOutOfRangeException() => throw new ArgumentOutOfRangeException();
[MethodImpl(MethodImplOptions.NoInlining)]
public static void ThrowArgumentDifferentWorldsException() => throw new ArgumentException("The groups belong to different worlds.");
}
#endif
#endregion
#region DebuggerProxy
internal class DebuggerProxy
{

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Runtime.CompilerServices;
using static DCFApixels.DragonECS.EcsThrowHalper;
namespace DCFApixels.DragonECS
{
@ -86,19 +87,19 @@ namespace DCFApixels.DragonECS
public void Run()
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
CheckBeforeInitForMethod(nameof(Run));
CheckAfterDestroyForMethod(nameof(Run));
if (_isInit) Throw.Pipeline_MethodCalledBeforeInitialisation(nameof(Run));
if (_isDestoryed) Throw.Pipeline_MethodCalledAfterDestruction(nameof(Run));
#endif
_runRunnerCache.Run(this);
}
public void Destroy()
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
CheckBeforeInitForMethod(nameof(Run));
if (_isInit) Throw.Pipeline_MethodCalledBeforeInitialisation(nameof(Destroy));
#endif
if (_isDestoryed == true)
{
EcsDebug.Print("[Warning]", $"This {nameof(EcsPipeline)} has already been destroyed");
EcsDebug.PrintWarning($"This {nameof(EcsPipeline)} has already been destroyed");
return;
}
_isDestoryed = true;
@ -106,26 +107,6 @@ namespace DCFApixels.DragonECS
}
#endregion
#region StateChecks
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
private void CheckBeforeInitForMethod(string methodName)
{
if (!_isInit)
throw new MethodAccessException($"It is forbidden to call {methodName}, before initialization {nameof(EcsPipeline)}");
}
private void CheckAfterInitForMethod(string methodName)
{
if (_isInit)
throw new MethodAccessException($"It is forbidden to call {methodName}, after initialization {nameof(EcsPipeline)}");
}
private void CheckAfterDestroyForMethod(string methodName)
{
if (_isDestoryed)
throw new MethodAccessException($"It is forbidden to call {methodName}, after destroying {nameof(EcsPipeline)}");
}
#endif
#endregion
#region Builder
public static Builder New() => new Builder();
public class Builder

View File

@ -73,8 +73,7 @@ namespace DCFApixels.DragonECS
}
if (delayedExceptions.Count > 0)
{
foreach (var item in delayedExceptions) EcsDebug.Print(EcsConsts.DEBUG_ERROR_TAG, item.Message);
throw delayedExceptions[0];
throw new AggregateException(delayedExceptions);
}
}

View File

@ -3,6 +3,7 @@ using DCFApixels.DragonECS.Utils;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using static DCFApixels.DragonECS.EcsThrowHalper;
namespace DCFApixels.DragonECS
{
@ -301,7 +302,7 @@ namespace DCFApixels.DragonECS
var count = --_componentCounts[entityID];
if (count == 0 && _allEntites.Has(entityID)) DelEntity(entityID);
#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS
if (count < 0) throw new EcsFrameworkException("нарушен баланс инкремента/декремента компонентов");
if (count < 0) Throw.World_InvalidIncrementComponentsBalance();
#endif
}
#endregion
@ -322,8 +323,7 @@ namespace DCFApixels.DragonECS
internal void ReleaseGroup(EcsGroup group)
{
#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS
if (group.World != this)
throw new ArgumentException("groupFilter.WorldIndex != this");
if (group.World != this) Throw.World_GroupDoesNotBelongWorld();
#endif
group._isReleased = true;
group.Clear();
@ -365,8 +365,6 @@ namespace DCFApixels.DragonECS
#endregion
}
internal sealed class EcsNullWorld : EcsWorld { }
#region Callbacks Interface
public interface IEcsWorldEventListener
{

View File

@ -97,4 +97,5 @@ namespace DCFApixels.DragonECS
}
}
}
internal sealed class EcsNullWorld : EcsWorld { }
}

View File

@ -1,8 +1,104 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
namespace DCFApixels.DragonECS
{
public class EcsThrowHalper
{
public static readonly EcsThrowHalper Throw = new EcsThrowHalper();
private EcsThrowHalper() { }
}
public static class EcsThrowHalper_Core
{
[MethodImpl(MethodImplOptions.NoInlining)]
public static void Pool_AlreadyHasComponent<T>(this EcsThrowHalper _, int entityID)
{
throw new EcsFrameworkException($"Entity({entityID}) already has component {EcsDebugUtility.GetGenericTypeName<T>()}.");
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static void Pool_NotHaveComponent<T>(this EcsThrowHalper _, int entityID)
{
throw new EcsFrameworkException($"Entity({entityID}) has no component {EcsDebugUtility.GetGenericTypeName<T>()}.");
}
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void ArgumentNull(this EcsThrowHalper _)
{
throw new ArgumentNullException();
}
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void ConstraintIsAlreadyContainedInMask(this EcsThrowHalper _, Type type)
{
throw new EcsFrameworkException($"The {EcsDebugUtility.GetGenericTypeName(type)} constraint is already contained in the mask.");
}
//[MethodImpl(MethodImplOptions.NoInlining)]
//public static void ArgumentDifferentWorldsException()
//{
// throw new ArgumentException("The groups belong to different worlds.");
//}
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void ArgumentOutOfRange(this EcsThrowHalper _)
{
throw new ArgumentOutOfRangeException($"index is less than 0 or is equal to or greater than Count.");
}
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void Group_AlreadyContains(this EcsThrowHalper _, int entityID)
{
throw new EcsFrameworkException($"This group already contains entity {entityID}.");
}
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void Group_DoesNotContain(this EcsThrowHalper _, int entityID)
{
throw new EcsFrameworkException($"This group does not contain entity {entityID}.");
}
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void Group_ArgumentDifferentWorldsException(this EcsThrowHalper _)
{
throw new ArgumentException("The groups belong to different worlds.");
}
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void Pipeline_MethodCalledAfterInitialisation(this EcsThrowHalper _, string methodName)
{
throw new MethodAccessException($"It is forbidden to call {methodName}, after initialization {nameof(EcsPipeline)}.");
}
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void Pipeline_MethodCalledBeforeInitialisation(this EcsThrowHalper _, string methodName)
{
throw new MethodAccessException($"It is forbidden to call {methodName}, before initialization {nameof(EcsPipeline)}.");
}
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void Pipeline_MethodCalledAfterDestruction(this EcsThrowHalper _, string methodName)
{
throw new MethodAccessException($"It is forbidden to call {methodName}, after destroying {nameof(EcsPipeline)}.");
}
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void World_InvalidIncrementComponentsBalance(this EcsThrowHalper _)
{
throw new MethodAccessException("Invalid increment components balance.");
}
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void World_GroupDoesNotBelongWorld(this EcsThrowHalper _)
{
throw new MethodAccessException("The Group does not belong in this world.");
}
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void Ent_ThrowIsNotAlive(this EcsThrowHalper _, entlong entity)
{
if (entity.IsNull)
throw new EcsFrameworkException($"The {entity} is null.");
else
throw new EcsFrameworkException($"The {entity} is not alive.");
}
}
[Serializable]
public class EcsFrameworkException : Exception
{

View File

@ -4,7 +4,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using static DCFApixels.DragonECS.entlong.ThrowHalper;
using static DCFApixels.DragonECS.EcsThrowHalper;
namespace DCFApixels.DragonECS
{
@ -33,7 +33,7 @@ namespace DCFApixels.DragonECS
public bool IsNull
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => full == 0l;
get => full == 0L;
}
public int ID
{
@ -41,7 +41,7 @@ namespace DCFApixels.DragonECS
get
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (!IsAlive) ThrowIsNotAlive(this);
if (!IsAlive) Throw.Ent_ThrowIsNotAlive(this);
#endif
return id;
}
@ -52,7 +52,7 @@ namespace DCFApixels.DragonECS
get
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (!IsAlive) ThrowIsNotAlive(this);
if (!IsAlive) Throw.Ent_ThrowIsNotAlive(this);
#endif
return gen;
}
@ -63,7 +63,7 @@ namespace DCFApixels.DragonECS
get
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (!IsAlive) ThrowIsNotAlive(this);
if (!IsAlive) Throw.Ent_ThrowIsNotAlive(this);
#endif
return EcsWorld.GetWorld(world);
}
@ -74,7 +74,7 @@ namespace DCFApixels.DragonECS
get
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (!IsAlive) ThrowIsNotAlive(this);
if (!IsAlive) Throw.Ent_ThrowIsNotAlive(this);
#endif
return world;
}
@ -143,20 +143,6 @@ namespace DCFApixels.DragonECS
public static explicit operator entlong(in long a) => new entlong(a);
#endregion
#region ThrowHalper
internal static class ThrowHalper
{
[MethodImpl(MethodImplOptions.NoInlining)]
public static void ThrowIsNotAlive(entlong entity)
{
if (entity.IsNull)
throw new EcsFrameworkException($"The {entity} is null.");
else
throw new EcsFrameworkException($"The {entity} is not alive.");
}
}
#endregion
#region DebuggerProxy
internal class DebuggerProxy
{