Compare commits

...

35 Commits

Author SHA1 Message Date
DCFApixels
03212094d9 Update README-RU.md 2025-03-29 16:39:19 +08:00
DCFApixels
a061004b32 Update README-RU.md 2025-03-29 16:25:29 +08:00
DCFApixels
fe651fe64b up version to 0.5.11 2025-03-29 16:19:36 +08:00
DCFApixels
6241688d64 fix ref repairer ui 2025-03-25 10:21:36 +08:00
DCFApixels
a990d90c07 fix manual save for so 2025-03-24 21:24:30 +08:00
DCFApixels
697d731e46 fix SparseArray 2025-03-24 21:24:12 +08:00
DCFApixels
822b231a47 update EcsEntityConnect 2025-03-24 20:12:07 +08:00
DCFApixels
b91b012add add getters/setters for entity templates 2025-03-24 19:39:28 +08:00
DCFApixels
a50a1f79fa add subtemplates for ScriptableEntityTemplate 2025-03-24 19:32:41 +08:00
DCFApixels
f9596752bb Update Config.cs 2025-03-24 13:52:09 +08:00
DCFApixels
1620484297 rework UnityDebugService initialization 2025-03-24 13:51:44 +08:00
DCFApixels
9bae371c25 impl IClonable for ComponentTemplateBase 2025-03-24 13:51:02 +08:00
DCFApixels
67677f6a57 fix disabled domain reload 2025-03-24 10:00:02 +08:00
DCFApixels
789a16ab29 fix asset processor 2025-03-23 21:15:37 +08:00
DCFApixels
22747a4a22 add inheriting for meta color & group 2025-03-23 19:21:36 +08:00
DCFApixels
948b026299 separate UnityComponentTemplates 2025-03-23 10:36:18 +08:00
DCFApixels
261c29578d Update ComponentTemplateBase.cs 2025-03-21 20:24:34 +08:00
DCFApixels
e59fc21491 fix domain reload 2025-03-21 19:59:23 +08:00
DCFApixels
b03e212c6d fixes/add define 2025-03-21 19:04:50 +08:00
DCFApixels
3ae210b4bc stash 2025-03-21 17:02:27 +08:00
DCFApixels
dd328432f1 impl strip console stacktrace 2025-03-21 16:51:03 +08:00
DCFApixels
f068c22661 stash 2025-03-21 14:32:50 +08:00
DCFApixels
2642510c89 Update UnityComponent.cs 2025-03-20 14:35:32 +08:00
DCFApixels
22326335c3 Update UnityComponent.cs 2025-03-20 14:34:16 +08:00
DCFApixels
e4d53c7825 fix/refactoring RefRepairer 2025-03-20 14:15:38 +08:00
DCFApixels
98190ae382 add Manually serialize button for so 2025-03-20 11:05:29 +08:00
DCFApixels
7f11e90aa5 add HideInCallstack for DebugService 2025-03-20 10:55:05 +08:00
DCFApixels
75be984bdc fix functionality of using MetaID 2025-03-20 10:34:20 +08:00
DCFApixels
f05767a795 Update UnityComponent.cs 2025-03-20 10:33:07 +08:00
DCFApixels
b345fde97d update MetaIDs 2025-03-19 16:31:32 +08:00
DCFApixels
1c64d32831 Update ComponentTemplateBase.cs 2025-03-19 09:34:27 +08:00
DCFApixels
d4e4ec7a66 refactoring 2025-03-18 18:51:14 +08:00
DCFApixels
3fd97cce1f rename path 2025-03-17 16:10:33 +08:00
DCFApixels
7fdd4cc7cc Update GameObjectConnect.cs 2025-03-17 16:03:55 +08:00
DCFApixels
a39c07e642 Update UnityComponent.cs 2025-03-17 16:00:55 +08:00
66 changed files with 1103 additions and 479 deletions

View File

@ -41,6 +41,10 @@
> Проект в стадии разработки. API может меняться. > Проект в стадии разработки. API может меняться.
> Readme еще не завершен, если есть не ясные моменты, вопросы можно задать тут [Обратная связь](https://github.com/DCFApixels/DragonECS/blob/main/README-RU.md#%D0%BE%D0%B1%D1%80%D0%B0%D1%82%D0%BD%D0%B0%D1%8F-%D1%81%D0%B2%D1%8F%D0%B7%D1%8C) > Readme еще не завершен, если есть не ясные моменты, вопросы можно задать тут [Обратная связь](https://github.com/DCFApixels/DragonECS/blob/main/README-RU.md#%D0%BE%D0%B1%D1%80%D0%B0%D1%82%D0%BD%D0%B0%D1%8F-%D1%81%D0%B2%D1%8F%D0%B7%D1%8C)
> [!WARNING]
> Встроенные реализации шаблонов `UnityComponent<T>` были перенесены [СЮДА](https://gist.github.com/DCFApixels/c250f2561f09e09ab3e6a4bd4f3013cb#file-unitycomponenttemplates-cs) Так как некоторые модули Unity отключаемы, и например отключение модуля физики приведет к тому что код реализации `UnityComponent<Rigidbody>` или `UnityComponent<Collider>` не будет компилироваться.
//https://gist.github.com/DCFApixels/c250f2561f09e09ab3e6a4bd4f3013cb#file-unitycomponenttemplates-cs
# Оглавление # Оглавление
- [Установка](#установка) - [Установка](#установка)
- [Debug](#debug) - [Debug](#debug)

View File

@ -8,7 +8,7 @@
"displayName": "DragonECS-Unity", "displayName": "DragonECS-Unity",
"description": "Integration with Unity for DragonECS", "description": "Integration with Unity for DragonECS",
"unity": "2021.2", "unity": "2021.2",
"version": "0.5.10", "version": "0.5.11",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/DCFApixels/DragonECS-Unity.git" "url": "https://github.com/DCFApixels/DragonECS-Unity.git"

View File

@ -9,19 +9,11 @@ namespace DCFApixels.DragonECS
{ {
using static EcsConsts; using static EcsConsts;
internal static class UnityComponentConsts
{
internal const string UNITY_COMPONENT_NAME = "UnityComponent";
public static readonly MetaGroup BaseGroup = new MetaGroup(UNITY_COMPONENT_NAME);
public static readonly MetaGroup RenderGroup = new MetaGroup($"{UNITY_COMPONENT_NAME}/Render/");
public static readonly MetaGroup ColliderGroup = new MetaGroup($"{UNITY_COMPONENT_NAME}/Collider/");
public static readonly MetaGroup JointGroup = new MetaGroup($"{UNITY_COMPONENT_NAME}/Joint/");
}
[Serializable] [Serializable]
[MetaColor(MetaColor.DragonCyan)] [MetaColor(MetaColor.DragonCyan)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, COMPONENTS_GROUP)] [MetaGroup(EcsUnityConsts.PACK_GROUP, COMPONENTS_GROUP)]
[MetaDescription(AUTHOR, "Component-reference to Unity object for EcsPool.")] [MetaDescription(AUTHOR, "Component-reference to Unity object for EcsPool.")]
[MetaID("734F667C9201B80F1913388C2A8BB689")] [MetaID("DragonECS_734F667C9201B80F1913388C2A8BB689")]
[MetaTags(MetaTags.ENGINE_MEMBER)] [MetaTags(MetaTags.ENGINE_MEMBER)]
public struct UnityComponent<T> : IEcsComponent, IEnumerable<T>//IntelliSense hack public struct UnityComponent<T> : IEcsComponent, IEnumerable<T>//IntelliSense hack
where T : Component where T : Component
@ -44,11 +36,15 @@ namespace DCFApixels.DragonECS
} }
} }
#region Unity Component Templates internal static class UnityComponentConsts
[MetaID("13DAACF9910155DD27F822442987E0AE")] {
internal const string UNITY_COMPONENT_NAME = "UnityComponent";
public static readonly MetaGroup BaseGroup = MetaGroup.FromName(UNITY_COMPONENT_NAME);
}
[MetaColor(MetaColor.DragonCyan)] [MetaColor(MetaColor.DragonCyan)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, OTHER_GROUP)] [MetaGroup(EcsUnityConsts.PACK_GROUP, OTHER_GROUP)]
[MetaDescription(AUTHOR, "Template for UnityComponent<T>")] [MetaDescription(AUTHOR, "Template for UnityComponent<T>")]
[MetaID("DragonECS_13DAACF9910155DD27F822442987E0AE")]
public abstract class UnityComponentTemplate<T> : ComponentTemplateBase<UnityComponent<T>> where T : Component public abstract class UnityComponentTemplate<T> : ComponentTemplateBase<UnityComponent<T>> where T : Component
{ {
public override string Name public override string Name
@ -74,173 +70,4 @@ namespace DCFApixels.DragonECS
} }
} }
} }
}
[Serializable]
[MetaTags(MetaTags.HIDDEN)]
[MetaID("843B8EF991013F1BFD9133437E1AFE9C")]
[MetaColor(MetaColor.DragonCyan)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, TEMPLATES_GROUP)]
[MetaDescription(AUTHOR, "...")]
public sealed class UnityComponentTransformTemplate : UnityComponentTemplate<Transform> { }
[Serializable]
[MetaTags(MetaTags.HIDDEN)]
[MetaID("9A4B8EF99101396C44BF789C3215E9A9")]
[MetaColor(MetaColor.DragonCyan)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, TEMPLATES_GROUP)]
[MetaDescription(AUTHOR, "...")]
public sealed class UnityComponentRigitBodyInitializer : UnityComponentTemplate<Rigidbody> { }
[Serializable]
[MetaTags(MetaTags.HIDDEN)]
[MetaID("52598EF991016655335F234F20F44526")]
[MetaColor(MetaColor.DragonCyan)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, TEMPLATES_GROUP)]
[MetaDescription(AUTHOR, "...")]
public sealed class UnityComponentAnimatorInitializer : UnityComponentTemplate<Animator> { }
[Serializable]
[MetaTags(MetaTags.HIDDEN)]
[MetaID("AD658EF99101E8E38BB575D5353E7B1E")]
[MetaColor(MetaColor.DragonCyan)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, TEMPLATES_GROUP)]
[MetaDescription(AUTHOR, "...")]
public sealed class UnityComponentCharacterControllerInitializer : UnityComponentTemplate<CharacterController> { }
#endregion
#region Render Templates
[Serializable]
[MetaTags(MetaTags.HIDDEN)]
[MetaID("6C6CA0F99101E80E013BCCCB5DA78FA5")]
[MetaColor(MetaColor.DragonCyan)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, TEMPLATES_GROUP)]
[MetaDescription(AUTHOR, "...")]
public sealed class UnityComponentMeshRendererTemplate : UnityComponentTemplate<MeshRenderer>
{
public override MetaGroup Group { get { return UnityComponentConsts.RenderGroup; } }
}
[Serializable]
[MetaTags(MetaTags.HIDDEN)]
[MetaID("5475A1F9910109A138F609268B697A62")]
[MetaColor(MetaColor.DragonCyan)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, TEMPLATES_GROUP)]
[MetaDescription(AUTHOR, "...")]
public sealed class UnityComponentMeshFilterTemplate : UnityComponentTemplate<MeshFilter>
{
public override MetaGroup Group { get { return UnityComponentConsts.RenderGroup; } }
}
[Serializable]
[MetaTags(MetaTags.HIDDEN)]
[MetaID("2C13A2F99101FAA3EA21BD351BF3B169")]
[MetaColor(MetaColor.DragonCyan)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, TEMPLATES_GROUP)]
[MetaDescription(AUTHOR, "...")]
public sealed class UnityComponentSkinnedMeshRendererTemplate : UnityComponentTemplate<SkinnedMeshRenderer>
{
public override MetaGroup Group { get { return UnityComponentConsts.RenderGroup; } }
}
[Serializable]
[MetaTags(MetaTags.HIDDEN)]
[MetaID("8B57A1F991016B2E1FC57D16F2D20A64")]
[MetaColor(MetaColor.DragonCyan)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, TEMPLATES_GROUP)]
[MetaDescription(AUTHOR, "...")]
public sealed class UnityComponentSpriteRendererTemplate : UnityComponentTemplate<SpriteRenderer>
{
public override MetaGroup Group { get { return UnityComponentConsts.RenderGroup; } }
}
#endregion
#region Collider Templates
[Serializable]
[MetaTags(MetaTags.HIDDEN)]
[MetaID("557F8EF9910132FE990CF50CBF368412")]
[MetaColor(MetaColor.DragonCyan)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, TEMPLATES_GROUP)]
[MetaDescription(AUTHOR, "...")]
public sealed class UnityComponentColliderTemplate : UnityComponentTemplate<Collider>
{
public override MetaGroup Group { get { return UnityComponentConsts.ColliderGroup; } }
}
[Serializable]
[MetaTags(MetaTags.HIDDEN)]
[MetaID("43669CF99101E94AB9EC19DC8EA3878B")]
[MetaColor(MetaColor.DragonCyan)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, TEMPLATES_GROUP)]
[MetaDescription(AUTHOR, "...")]
public sealed class UnityComponentBoxColliderTemplate : UnityComponentTemplate<BoxCollider>
{
public override MetaGroup Group { get { return UnityComponentConsts.ColliderGroup; } }
}
[Serializable]
[MetaTags(MetaTags.HIDDEN)]
[MetaID("749F9CF991017792E288D4E3B5BFE340")]
[MetaColor(MetaColor.DragonCyan)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, TEMPLATES_GROUP)]
[MetaDescription(AUTHOR, "...")]
public sealed class UnityComponentSphereColliderTemplate : UnityComponentTemplate<SphereCollider>
{
public override MetaGroup Group { get { return UnityComponentConsts.ColliderGroup; } }
}
[Serializable]
[MetaTags(MetaTags.HIDDEN)]
[MetaID("72B09CF99101A33EBC4410B0FD8375E0")]
[MetaColor(MetaColor.DragonCyan)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, TEMPLATES_GROUP)]
[MetaDescription(AUTHOR, "...")]
public sealed class UnityComponentCapsuleColliderTemplate : UnityComponentTemplate<CapsuleCollider>
{
public override MetaGroup Group { get { return UnityComponentConsts.ColliderGroup; } }
}
[Serializable]
[MetaTags(MetaTags.HIDDEN)]
[MetaID("3BBC9CF99101F7C00989D2E55A40EF1B")]
[MetaColor(MetaColor.DragonCyan)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, TEMPLATES_GROUP)]
[MetaDescription(AUTHOR, "...")]
public sealed class UnityComponentMeshColliderTemplate : UnityComponentTemplate<MeshCollider>
{
public override MetaGroup Group { get { return UnityComponentConsts.ColliderGroup; } }
}
#endregion
#region Joint Templates
[Serializable]
[MetaTags(MetaTags.HIDDEN)]
[MetaID("1AC79CF99101C4279852BB6AE12DC61B")]
[MetaColor(MetaColor.DragonCyan)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, TEMPLATES_GROUP)]
[MetaDescription(AUTHOR, "...")]
public sealed class UnityComponentJointTemplate : UnityComponentTemplate<Joint>
{
public override MetaGroup Group { get { return UnityComponentConsts.JointGroup; } }
}
[Serializable]
[MetaTags(MetaTags.HIDDEN)]
[MetaID("E3D99CF991016428C6688672052C6F4E")]
[MetaColor(MetaColor.DragonCyan)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, TEMPLATES_GROUP)]
[MetaDescription(AUTHOR, "...")]
public sealed class UnityComponentFixedJointTemplate : UnityComponentTemplate<FixedJoint>
{
public override MetaGroup Group { get { return UnityComponentConsts.JointGroup; } }
}
[Serializable]
[MetaTags(MetaTags.HIDDEN)]
[MetaID("7BE59CF99101322AE307229E1466B225")]
[MetaColor(MetaColor.DragonCyan)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, TEMPLATES_GROUP)]
[MetaDescription(AUTHOR, "...")]
public sealed class UnityComponentCharacterJointTemplate : UnityComponentTemplate<CharacterJoint>
{
public override MetaGroup Group { get { return UnityComponentConsts.JointGroup; } }
}
[Serializable]
[MetaTags(MetaTags.HIDDEN)]
[MetaID("FBF29CF99101EE07543CFF460854B1F6")]
[MetaColor(MetaColor.DragonCyan)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, TEMPLATES_GROUP)]
[MetaDescription(AUTHOR, "...")]
public sealed class UnityComponentConfigurableJointTemplate : UnityComponentTemplate<ConfigurableJoint>
{
public override MetaGroup Group { get { return UnityComponentConsts.JointGroup; } }
}
#endregion
}

View File

@ -8,7 +8,7 @@ namespace DCFApixels.DragonECS
[MetaColor(MetaColor.DragonRose)] [MetaColor(MetaColor.DragonRose)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)] [MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
[MetaDescription(EcsConsts.AUTHOR, "The process to run when EcsPipeline.DrawGizmos() is called.")] [MetaDescription(EcsConsts.AUTHOR, "The process to run when EcsPipeline.DrawGizmos() is called.")]
[MetaID("5DDBBB80920163B891A5BF52F9718A30")] [MetaID("DragonECS_5DDBBB80920163B891A5BF52F9718A30")]
public interface IEcsGizmosProcess : IEcsProcess public interface IEcsGizmosProcess : IEcsProcess
{ {
public void DrawGizmos(); public void DrawGizmos();
@ -17,7 +17,7 @@ namespace DCFApixels.DragonECS
[MetaColor(MetaColor.DragonRose)] [MetaColor(MetaColor.DragonRose)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)] [MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
[MetaDescription(EcsConsts.AUTHOR, "The process to run when EcsPipeline.LateRun() is called.")] [MetaDescription(EcsConsts.AUTHOR, "The process to run when EcsPipeline.LateRun() is called.")]
[MetaID("BCE8BB8092015F2442B767645FD7F6CA")] [MetaID("DragonECS_BCE8BB8092015F2442B767645FD7F6CA")]
public interface IEcsLateRunProcess : IEcsProcess public interface IEcsLateRunProcess : IEcsProcess
{ {
public void LateRun(); public void LateRun();
@ -26,7 +26,7 @@ namespace DCFApixels.DragonECS
[MetaColor(MetaColor.DragonRose)] [MetaColor(MetaColor.DragonRose)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)] [MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
[MetaDescription(EcsConsts.AUTHOR, "The process to run when EcsPipeline.FixedRun() is called.")] [MetaDescription(EcsConsts.AUTHOR, "The process to run when EcsPipeline.FixedRun() is called.")]
[MetaID("54F4BB8092010228FAAD78F9D2352117")] [MetaID("DragonECS_54F4BB8092010228FAAD78F9D2352117")]
public interface IEcsFixedRunProcess : IEcsProcess public interface IEcsFixedRunProcess : IEcsProcess
{ {
public void FixedRun(); public void FixedRun();
@ -54,7 +54,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
[MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)] [MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
[MetaDescription(EcsConsts.AUTHOR, "...")] [MetaDescription(EcsConsts.AUTHOR, "...")]
[MetaTags(MetaTags.HIDDEN)] [MetaTags(MetaTags.HIDDEN)]
[MetaID("2DD8BC809201633E2761D5AEF65B7090")] [MetaID("DragonECS_2DD8BC809201633E2761D5AEF65B7090")]
public class EcsLateGizmosRunner : EcsRunner<IEcsGizmosProcess>, IEcsGizmosProcess public class EcsLateGizmosRunner : EcsRunner<IEcsGizmosProcess>, IEcsGizmosProcess
{ {
private RunHelper _helper; private RunHelper _helper;
@ -72,7 +72,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
[MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)] [MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
[MetaDescription(EcsConsts.AUTHOR, "...")] [MetaDescription(EcsConsts.AUTHOR, "...")]
[MetaTags(MetaTags.HIDDEN)] [MetaTags(MetaTags.HIDDEN)]
[MetaID("EDE8BC809201603B47C3A9D1EFD4EE95")] [MetaID("DragonECS_EDE8BC809201603B47C3A9D1EFD4EE95")]
public class EcsLateRunRunner : EcsRunner<IEcsLateRunProcess>, IEcsLateRunProcess public class EcsLateRunRunner : EcsRunner<IEcsLateRunProcess>, IEcsLateRunProcess
{ {
private RunHelper _helper; private RunHelper _helper;
@ -90,7 +90,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
[MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)] [MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)]
[MetaDescription(EcsConsts.AUTHOR, "...")] [MetaDescription(EcsConsts.AUTHOR, "...")]
[MetaTags(MetaTags.HIDDEN)] [MetaTags(MetaTags.HIDDEN)]
[MetaID("45F7BC809201866AA05F6DC096A47F01")] [MetaID("DragonECS_45F7BC809201866AA05F6DC096A47F01")]
public class EcsFixedRunRunner : EcsRunner<IEcsFixedRunProcess>, IEcsFixedRunProcess public class EcsFixedRunRunner : EcsRunner<IEcsFixedRunProcess>, IEcsFixedRunProcess
{ {
private RunHelper _helper; private RunHelper _helper;

View File

@ -13,7 +13,7 @@ namespace DCFApixels.DragonECS
[MetaColor(MetaColor.DragonCyan)] [MetaColor(MetaColor.DragonCyan)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, EcsUnityConsts.ENTITY_BUILDING_GROUP)] [MetaGroup(EcsUnityConsts.PACK_GROUP, EcsUnityConsts.ENTITY_BUILDING_GROUP)]
[MetaDescription(AUTHOR, nameof(MonoBehaviour) + ". Automatically creates an entity in the selected world and connects it to EcsEntityConnect.")] [MetaDescription(AUTHOR, nameof(MonoBehaviour) + ". Automatically creates an entity in the selected world and connects it to EcsEntityConnect.")]
[MetaID("D699B3809201285A46DDF91BCF0540A7")] [MetaID("DragonECS_D699B3809201285A46DDF91BCF0540A7")]
public class AutoEntityCreator : MonoBehaviour public class AutoEntityCreator : MonoBehaviour
{ {
[SerializeField] [SerializeField]

View File

@ -65,8 +65,8 @@ namespace DCFApixels.DragonECS
[MetaColor(MetaColor.DragonCyan)] [MetaColor(MetaColor.DragonCyan)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, EcsUnityConsts.ENTITY_BUILDING_GROUP)] [MetaGroup(EcsUnityConsts.PACK_GROUP, EcsUnityConsts.ENTITY_BUILDING_GROUP)]
[MetaDescription(AUTHOR, nameof(MonoBehaviour) + ". Responsible for connecting the entity and GameObject using the EcsEntityConnect.ConnectWith method.")] [MetaDescription(AUTHOR, nameof(MonoBehaviour) + ". Responsible for connecting the entity and GameObject using the EcsEntityConnect.ConnectWith method.")]
[MetaID("FF7EB3809201DEC2F1977C00D3B3443B")] [MetaID("DragonECS_FF7EB3809201DEC2F1977C00D3B3443B")]
public class EcsEntityConnect : MonoBehaviour public class EcsEntityConnect : MonoBehaviour, ITemplateNode
{ {
private entlong _entity; private entlong _entity;
private EcsWorld _world; private EcsWorld _world;
@ -82,6 +82,12 @@ namespace DCFApixels.DragonECS
private bool _isConnectInvoked = false; private bool _isConnectInvoked = false;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void OnLoad()
{
_connectedEntities.Clear();
}
#region Properties #region Properties
public entlong Entity public entlong Entity
{ {
@ -113,6 +119,10 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region Connect #region Connect
void ITemplateNode.Apply(short worldID, int entityID)
{
ConnectWith((EcsWorld.GetWorld(worldID), entityID), true);
}
public void ConnectWith(entlong entity, bool applyTemplates) public void ConnectWith(entlong entity, bool applyTemplates)
{ {
Disconnect(); Disconnect();

View File

@ -4,6 +4,7 @@
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using UnityEngine; using UnityEngine;
using DCFApixels.DragonECS.Unity; using DCFApixels.DragonECS.Unity;
using DCFApixels.DragonECS.Core;
#if UNITY_EDITOR #if UNITY_EDITOR
using UnityEditor; using UnityEditor;
#endif #endif
@ -13,7 +14,7 @@ namespace DCFApixels.DragonECS
[MetaColor(MetaColor.DragonCyan)] [MetaColor(MetaColor.DragonCyan)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.COMPONENTS_GROUP)] [MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.COMPONENTS_GROUP)]
[MetaDescription(EcsConsts.AUTHOR, "This component is automatically added if an entity is connected to one of the EcsEntityConnect. It also contains a reference to the connected EcsEntityConnect.")] [MetaDescription(EcsConsts.AUTHOR, "This component is automatically added if an entity is connected to one of the EcsEntityConnect. It also contains a reference to the connected EcsEntityConnect.")]
[MetaID("14AC6B239201C6A60337AF3384D237E7")] [MetaID("DragonECS_14AC6B239201C6A60337AF3384D237E7")]
[MetaTags(MetaTags.ENGINE_MEMBER)] [MetaTags(MetaTags.ENGINE_MEMBER)]
[System.Serializable] [System.Serializable]
public readonly struct GameObjectConnect : IEcsComponent, IEcsComponentLifecycle<GameObjectConnect> public readonly struct GameObjectConnect : IEcsComponent, IEcsComponentLifecycle<GameObjectConnect>

View File

@ -16,6 +16,13 @@
public class EcsUnityDefines public class EcsUnityDefines
{ {
public const bool DRAGONECS_ENABLE_UNITY_CONSOLE_SHORTCUT_LINKS =
#if DRAGONECS_ENABLE_UNITY_CONSOLE_SHORTCUT_LINKS
true;
#else
false;
#endif
public const bool ENABLE_IL2CPP = public const bool ENABLE_IL2CPP =
#if ENABLE_IL2CPP #if ENABLE_IL2CPP
true; true;

View File

@ -78,9 +78,9 @@ namespace DCFApixels.DragonECS.Unity.Editors
rect = GUILayoutUtility.GetLastRect(); rect = GUILayoutUtility.GetLastRect();
rect.xMin += 9f; rect.xMin += 9f;
GUI.Label(rect, "Scripting Define Symbols", EditorStyles.whiteLargeLabel); GUI.Label(rect, "Scripting Define Symbols", EditorStyles.whiteLargeLabel);
InitDefines(); InitDefines();
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
foreach (var symbol in _defineSymbols) foreach (var symbol in _defineSymbols)
{ {

View File

@ -6,7 +6,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
[MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.DEBUG_GROUP)] [MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.DEBUG_GROUP)]
[MetaDescription(EcsConsts.AUTHOR, "...")] [MetaDescription(EcsConsts.AUTHOR, "...")]
[MetaTags(MetaTags.HIDDEN)] [MetaTags(MetaTags.HIDDEN)]
[MetaID("A551B6809201D56AA0F1B51248174B4D")] [MetaID("DragonECS_A551B6809201D56AA0F1B51248174B4D")]
internal class EntityMonitor : MonoBehaviour internal class EntityMonitor : MonoBehaviour
{ {
private entlong _entity; private entlong _entity;

View File

@ -7,7 +7,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
[MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.DEBUG_GROUP)] [MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.DEBUG_GROUP)]
[MetaDescription(EcsConsts.AUTHOR, "...")] [MetaDescription(EcsConsts.AUTHOR, "...")]
[MetaTags(MetaTags.HIDDEN)] [MetaTags(MetaTags.HIDDEN)]
[MetaID("EC9DB6809201CDD801B5B342C8A2AC8D")] [MetaID("DragonECS_EC9DB6809201CDD801B5B342C8A2AC8D")]
internal class PipelineMonitor : MonoBehaviour internal class PipelineMonitor : MonoBehaviour
{ {
private EcsPipeline _pipeline; private EcsPipeline _pipeline;
@ -25,7 +25,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
[MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.DEBUG_GROUP)] [MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.DEBUG_GROUP)]
[MetaDescription(EcsConsts.AUTHOR, "...")] [MetaDescription(EcsConsts.AUTHOR, "...")]
[MetaTags(MetaTags.HIDDEN)] [MetaTags(MetaTags.HIDDEN)]
[MetaID("1DB9B6809201E092088A446A19EB9C7D")] [MetaID("DragonECS_1DB9B6809201E092088A446A19EB9C7D")]
internal class PipelineMonitorSystem : IEcsInit, IEcsPipelineMember, IEcsDestroy internal class PipelineMonitorSystem : IEcsInit, IEcsPipelineMember, IEcsDestroy
{ {
private PipelineMonitor _monitor; private PipelineMonitor _monitor;

View File

@ -6,7 +6,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
[MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.DEBUG_GROUP)] [MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.DEBUG_GROUP)]
[MetaDescription(EcsConsts.AUTHOR, "...")] [MetaDescription(EcsConsts.AUTHOR, "...")]
[MetaTags(MetaTags.HIDDEN)] [MetaTags(MetaTags.HIDDEN)]
[MetaID("75CCB6809201450CA3E1F280CB1EB0E7")] [MetaID("DragonECS_75CCB6809201450CA3E1F280CB1EB0E7")]
internal class PipelineProcessMonitor : MonoBehaviour internal class PipelineProcessMonitor : MonoBehaviour
{ {
private EcsPipeline _pipeline; private EcsPipeline _pipeline;

View File

@ -8,7 +8,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
[MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.DEBUG_GROUP)] [MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.DEBUG_GROUP)]
[MetaDescription(EcsConsts.AUTHOR, "...")] [MetaDescription(EcsConsts.AUTHOR, "...")]
[MetaTags(MetaTags.HIDDEN)] [MetaTags(MetaTags.HIDDEN)]
[MetaID("DDE9B6809201381D86DEF36AD06601A9")] [MetaID("DragonECS_DDE9B6809201381D86DEF36AD06601A9")]
internal class WorldMonitor : MonoBehaviour internal class WorldMonitor : MonoBehaviour
{ {
private EcsWorld _world; private EcsWorld _world;
@ -26,7 +26,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
[MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.DEBUG_GROUP)] [MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.DEBUG_GROUP)]
[MetaDescription(EcsConsts.AUTHOR, "...")] [MetaDescription(EcsConsts.AUTHOR, "...")]
[MetaTags(MetaTags.HIDDEN)] [MetaTags(MetaTags.HIDDEN)]
[MetaID("B5FBB680920179310BEBB305817462B5")] [MetaID("DragonECS_B5FBB680920179310BEBB305817462B5")]
internal class WorldMonitorSystem : IEcsInit, IEcsWorldEventListener, IEcsEntityEventListener internal class WorldMonitorSystem : IEcsInit, IEcsWorldEventListener, IEcsEntityEventListener
{ {
private EcsWorld _world; private EcsWorld _world;

View File

@ -8,7 +8,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
[MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.DEBUG_GROUP)] [MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.DEBUG_GROUP)]
[MetaDescription(EcsConsts.AUTHOR, "...")] [MetaDescription(EcsConsts.AUTHOR, "...")]
[MetaTags(MetaTags.HIDDEN)] [MetaTags(MetaTags.HIDDEN)]
[MetaID("AC178504930164FD2EABFA071EF0476F")] [MetaID("DragonECS_AC178504930164FD2EABFA071EF0476F")]
internal class WorldQueriesMonitor : MonoBehaviour internal class WorldQueriesMonitor : MonoBehaviour
{ {
private EcsWorld _world; private EcsWorld _world;

View File

@ -6,7 +6,7 @@ namespace DCFApixels.DragonECS
[MetaColor(MetaColor.DragonRose)] [MetaColor(MetaColor.DragonRose)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.DEBUG_GROUP)] [MetaGroup(EcsUnityConsts.PACK_GROUP, EcsConsts.DEBUG_GROUP)]
[MetaDescription(EcsConsts.AUTHOR, "...")] [MetaDescription(EcsConsts.AUTHOR, "...")]
[MetaID("1D16B980920108B62A0971E4058A3E01")] [MetaID("DragonECS_1D16B980920108B62A0971E4058A3E01")]
public sealed class UnityDebugModule : IEcsModule public sealed class UnityDebugModule : IEcsModule
{ {
public EcsWorld[] _worlds; public EcsWorld[] _worlds;

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 69f2abf8b8744c840b2da7f8988b3f8d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,18 +1,8 @@
using System; using DCFApixels.DragonECS.Unity.Internal;
using System;
using Unity.Profiling; using Unity.Profiling;
using UnityEngine; using UnityEngine;
#region [InitializeOnLoad]
#if UNITY_EDITOR
namespace DCFApixels.DragonECS
{
using UnityEditor;
[InitializeOnLoad]
public partial class UnityDebugService { }
}
#endif
#endregion
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
// Методы юнитевского Debug и ProfilerMarker потоко безопасны // Методы юнитевского Debug и ProfilerMarker потоко безопасны
@ -20,12 +10,9 @@ namespace DCFApixels.DragonECS
{ {
private ProfilerMarker[] _profilerMarkers = new ProfilerMarker[64]; private ProfilerMarker[] _profilerMarkers = new ProfilerMarker[64];
static UnityDebugService()
{
Activate();
}
public static void Activate() public static void Activate()
{ {
if (Instance.GetType() == typeof(UnityDebugService)) { return; }
Set<UnityDebugService>(); Set<UnityDebugService>();
} }
@ -33,6 +20,9 @@ namespace DCFApixels.DragonECS
{ {
return new UnityDebugService(); return new UnityDebugService();
} }
#if UNITY_2021_3_OR_NEWER
[HideInCallstack]
#endif
public override void Print(string tag, object v) public override void Print(string tag, object v)
{ {
if (v is Exception e) if (v is Exception e)
@ -40,8 +30,37 @@ namespace DCFApixels.DragonECS
Debug.LogException(e); Debug.LogException(e);
return; return;
} }
string msg = AutoConvertObjectToString(v);
bool hasTag = string.IsNullOrEmpty(tag) == false; bool hasTag = string.IsNullOrEmpty(tag) == false;
string msg = AutoConvertObjectToString(v);
#if DRAGONECS_ENABLE_UNITY_CONSOLE_SHORTCUT_LINKS
string indexedLink = UnityDebugServiceStorage.NewIndexedLink();
if (hasTag)
{
string taglower = tag.ToLower();
switch (taglower)
{
case "pass":
Debug.Log(
$"{indexedLink}[<color=#00ff00>{tag}</color>] {msg}");
break;
case "warning":
Debug.LogWarning(
$"{indexedLink}[<color=#ffff00>{tag}</color>] {msg}");
break;
case "error":
Debug.LogError(
$"{indexedLink}[<color=#ff4028>{tag}</color>] {msg}");
break;
default:
Debug.Log(
$"{indexedLink}[{tag}] {msg}");
break;
}
return;
}
Debug.Log($"{indexedLink}{msg}");
#else
if (hasTag) if (hasTag)
{ {
string taglower = tag.ToLower(); string taglower = tag.ToLower();
@ -66,7 +85,8 @@ namespace DCFApixels.DragonECS
} }
return; return;
} }
Debug.Log(msg); Debug.Log($"{msg}");
#endif
} }
public override void Break() public override void Break()
{ {

View File

@ -0,0 +1,213 @@
#if UNITY_EDITOR
#if DRAGONECS_ENABLE_UNITY_CONSOLE_SHORTCUT_LINKS
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading;
using UnityEditor;
using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Internal
{
using static UnityDebugServiceStorage;
using static UnityDebugServiceStorageInitializer;
[InitializeOnLoad]
internal static class UnityDebugServiceStorageInitializer
{
private static readonly MethodInfo _getLogsCountMethod;
public static readonly bool IsSupportAutoLingks;
static UnityDebugServiceStorageInitializer()
{
var logEntriesType = typeof(EditorWindow).Assembly.GetType("UnityEditor.LogEntries");
if (logEntriesType != null)
{
_getLogsCountMethod = logEntriesType.GetMethod("GetCount", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
}
IsSupportAutoLingks = _getLogsCountMethod != null;
EditorGUI.hyperLinkClicked -= EditorGUI_hyperLinkClicked;
Application.logMessageReceived -= Application_logMessageReceived;
_consoleLogCounter = -1;
//if (IsSupportAutoLingks)
{
EditorGUI.hyperLinkClicked += EditorGUI_hyperLinkClicked;
Application.logMessageReceived += Application_logMessageReceived;
_consoleLogCounter = GetConsoleLogCount();
}
}
internal static int GetConsoleLogCount()
{
return (int)_getLogsCountMethod.Invoke(null, null);
}
}
internal class UnityDebugServiceStorage : ScriptableSingleton<UnityDebugServiceStorage>
{
public UnityDebugServiceStorage() { }
internal const int IntervalChecksTicksThreshold = 100;
internal static int _consoleLogCounter;
internal static int _intervalChecksTicks = 0;
[SerializeField]
internal StructList<LogEntry> _logEntries = new StructList<LogEntry>(256);
[SerializeField]
private int _hyperLinkIndex = 0;
internal static object _lock = new object();
internal static void EditorGUI_hyperLinkClicked(EditorWindow window, HyperLinkClickedEventArgs args)
{
OnProcessClickData(args.hyperLinkData);
}
internal static void OnProcessClickData(Dictionary<string, string> infos)
{
var inst = instance;
if (infos == null) return;
if (!infos.TryGetValue("href", out var path)) return;
for (int i = 0; i < inst._logEntries.Count; i++)
{
ref var e = ref inst._logEntries._items[i];
if (CheckLogWithIndexedLink(e.LogString))
{
int indexof = INDEXED_LINK_PREV.Length - 1;// откатываю символ ∆
int stringIndexLength = e.LogString.IndexOf(INDEXED_LINK_POST) - indexof;
if(stringIndexLength == path.Length)
{
bool isSkip = false;
for (int j = 1; j < stringIndexLength; j++)
{
var pathchar = path[j];
var logchar = e.LogString[indexof + j];
if (pathchar != logchar) { isSkip = true; break; }
}
if (isSkip) { continue; }
OpenIDE(e);
break;
}
}
}
}
private static void OpenIDE(LogEntry entry)
{
var parsed = ParseLastCall(entry.StackTrace);
if (string.IsNullOrEmpty(parsed.path)) { return; }
UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(parsed.path, parsed.line); //TODO
}
public static (string path, int line) ParseLastCall(string stackTrace)
{
var debugTypeFullname = typeof(DCFApixels.DragonECS.EcsDebug).FullName;
stackTrace = stackTrace.Remove(0, stackTrace.IndexOf(debugTypeFullname));
var lines = stackTrace.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 1; i < lines.Length; i++)
{
var line = lines[i];
Match match = Regex.Match(line, @"\(at (?<path>.+?):(?<line>\d+)\)");
if (match.Success)
{
string filePath = match.Groups["path"].Value;
string lineNumber = match.Groups["line"].Value;
return (filePath, int.Parse(lineNumber));
}
}
return default;
}
internal static void Application_logMessageReceived(string logString, string stackTrace, LogType type)
{
var inst = instance;
if (_intervalChecksTicks >= IntervalChecksTicksThreshold ||
inst._logEntries.Count >= inst._logEntries.Capacity - 1)
{
CheckConsoleClean();
}
inst._logEntries.Add(new LogEntry(logString, stackTrace));
_consoleLogCounter++;
_intervalChecksTicks++;
}
private static bool CheckConsoleClean()
{
lock (_lock)
{
var inst = instance;
if (_intervalChecksTicks < IntervalChecksTicksThreshold) { return false; }
int currentCount = GetConsoleLogCount();
if (_consoleLogCounter > currentCount)
{
var l = _consoleLogCounter - currentCount;
if(l < inst._logEntries.Count)
{
inst._logEntries.FastRemoveSpan(0, l);
}
_consoleLogCounter = currentCount;
_intervalChecksTicks = 0;
return true;
}
return false;
}
}
private const string INDEXED_LINK_PREV = "<a href=\"∆";
private const string INDEXED_LINK_POST = "\">→ </a>";
private static string CreateIndexedLink(int index)
{
return $"{INDEXED_LINK_PREV}{index}{INDEXED_LINK_POST}";
}
//multi thread access.
public static string NewIndexedLink()
{
return instance.GetHyperLink_Internal();
}
public string GetHyperLink_Internal()
{
var index = Interlocked.Increment(ref _hyperLinkIndex);
string hyperLink = CreateIndexedLink(index);
return hyperLink;
}
private static bool CheckLogWithIndexedLink(string log)
{
if (log == null) { return false; }
if (log.Length < INDEXED_LINK_PREV.Length) { return false; }
for (int i = 0; i < INDEXED_LINK_PREV.Length; i++)
{
char constChar = INDEXED_LINK_PREV[i];
char logChar = log[i];
if (constChar != logChar) { return false; }
}
return true;
}
[Serializable]
internal struct LogEntry
{
public string LogString;
public string StackTrace;
public LogEntry(string logString, string stackTrace)
{
LogString = logString;
StackTrace = stackTrace;
}
}
}
}
#endif
#endif

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 8666cb6c75b076c41910acbe59d258af

View File

@ -5,7 +5,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
{ {
internal abstract class Config<TSelf> : ScriptableObject where TSelf : ScriptableObject internal abstract class Config<TSelf> : ScriptableObject where TSelf : ScriptableObject
{ {
private static object _lock = new object(); private readonly static object _lock = new object();
private static TSelf _instance; private static TSelf _instance;
public static TSelf Instance public static TSelf Instance
{ {

View File

@ -72,58 +72,31 @@ namespace DCFApixels.DragonECS.Unity.Internal
} }
} }
internal static class ArrayUtility internal static class DragonArrayUtility
{ {
private static int GetHighBitNumber(uint bits) public static int NextPow2(int v)
{
if (bits == 0)
{
return -1;
}
int bit = 0;
if ((bits & 0xFFFF0000) != 0)
{
bits >>= 16;
bit |= 16;
}
if ((bits & 0xFF00) != 0)
{
bits >>= 8;
bit |= 8;
}
if ((bits & 0xF0) != 0)
{
bits >>= 4;
bit |= 4;
}
if ((bits & 0xC) != 0)
{
bits >>= 2;
bit |= 2;
}
if ((bits & 0x2) != 0)
{
bit |= 1;
}
return bit;
}
public static int NormalizeSizeToPowerOfTwo(int minSize)
{ {
unchecked unchecked
{ {
return 1 << (GetHighBitNumber((uint)minSize - 1u) + 1); v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
return ++v;
} }
} }
public static int NormalizeSizeToPowerOfTwo_ClampOverflow(int minSize) public static int NextPow2_ClampOverflow(int v)
{ {
unchecked unchecked
{ {
int hibit = (GetHighBitNumber((uint)minSize - 1u) + 1); const int NO_SIGN_HIBIT = 0x40000000;
if (hibit >= 32) if ((v & NO_SIGN_HIBIT) != 0)
{ {
return int.MaxValue; return int.MaxValue;
} }
return 1 << hibit; return NextPow2(v);
} }
} }
public static void Fill<T>(T[] array, T value, int startIndex = 0, int length = -1) public static void Fill<T>(T[] array, T value, int startIndex = 0, int length = -1)

View File

@ -16,6 +16,28 @@ namespace DCFApixels.DragonECS.Unity.Editors
{ {
public static partial class Layout public static partial class Layout
{ {
public static void ManuallySerializeButton(IEnumerable<UnityObject> objects)
{
if (GUILayout.Button(UnityEditorUtility.GetLabel("Manually serialize")))
{
foreach (var obj in objects)
{
EditorUtility.SetDirty(obj);
}
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
}
public static void ManuallySerializeButton(UnityObject obj)
{
if (GUILayout.Button(UnityEditorUtility.GetLabel("Manually serialize")))
{
EditorUtility.SetDirty(obj);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
}
public static void ScriptAssetButton(MonoScript script, params GUILayoutOption[] options) public static void ScriptAssetButton(MonoScript script, params GUILayoutOption[] options)
{ {
EcsGUI.ScriptAssetButton(GUILayoutUtility.GetRect(UnityEditorUtility.GetLabelTemp(), EditorStyles.miniButton, options), script); EcsGUI.ScriptAssetButton(GUILayoutUtility.GetRect(UnityEditorUtility.GetLabelTemp(), EditorStyles.miniButton, options), script);
@ -310,12 +332,16 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
#region Default DrawRuntimeData #region Default DrawRuntimeData
[InitializeOnLoadMethod] [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void ResetRuntimeComponentReflectionCache() private static void ResetRuntimeComponentReflectionCache()
{ {
foreach (var item in _runtimeComponentReflectionCaches)
{
item.Value.Dispose();
}
_runtimeComponentReflectionCaches.Clear(); _runtimeComponentReflectionCaches.Clear();
} }
internal class RuntimeComponentReflectionCache internal class RuntimeComponentReflectionCache : IDisposable
{ {
public readonly Type Type; public readonly Type Type;
@ -350,6 +376,14 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
} }
} }
public void Dispose()
{
if(Wrapper != null)
{
UnityObject.DestroyImmediate(Wrapper);
}
}
public readonly struct FieldInfoData public readonly struct FieldInfoData
{ {
public readonly FieldInfo FieldInfo; public readonly FieldInfo FieldInfo;
@ -455,7 +489,6 @@ namespace DCFApixels.DragonECS.Unity.Editors
else else
{ {
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
//WrapperBase wrapper = RefEditorWrapper.Take(data);
RefEditorWrapper wrapper = cache.Wrapper; RefEditorWrapper wrapper = cache.Wrapper;

View File

@ -418,19 +418,30 @@ namespace DCFApixels.DragonECS.Unity.Editors
{ {
var current = Event.current; var current = Event.current;
var hover = IconHoverScan(position, current); var hover = IconHoverScan(position, current);
using (new ColorScope(new Color(1f, 1f, 1f, hover ? 1f : 0.8f))) if (GUI.enabled)
{ {
DrawIcon(position, Icons.Instance.FileIcon, hover ? 1f : 2f, "One click - Ping File. Double click - Edit Script"); using (SetColor(1f, 1f, 1f, hover ? 1f : 0.8f))
}
if (hover)
{
if (current.type == EventType.MouseUp)
{ {
EditorGUIUtility.PingObject(script); DrawIcon(position, Icons.Instance.FileIcon, hover ? 1f : 2f, "One click - Ping File. Double click - Edit Script");
} }
else if (current.type == EventType.MouseDown && current.clickCount >= 2) if (hover)
{ {
AssetDatabase.OpenAsset(script); if (current.type == EventType.MouseUp)
{
EditorGUIUtility.PingObject(script);
}
else if (current.type == EventType.MouseDown && current.clickCount >= 2)
{
//UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(); //TODO
AssetDatabase.OpenAsset(script);
}
}
}
else
{
using (SetColor(0.85f, 0.85f, 0.85f, 0.7f))
{
DrawIcon(position, Icons.Instance.FileIcon, 2f, "One click - Ping File. Double click - Edit Script");
} }
} }
} }
@ -748,6 +759,18 @@ namespace DCFApixels.DragonECS.Unity.Editors
#endregion #endregion
#region Other Elements #region Other Elements
public static void ManuallySerializeButton(Rect position, UnityEngine.Object obj)
{
if (GUI.Button(position, UnityEditorUtility.GetLabel("Manually serialize")))
{
var so = new SerializedObject(obj);
EditorUtility.SetDirty(obj);
so.UpdateIfRequiredOrScript();
so.ApplyModifiedProperties();
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
}
public static bool AddComponentButton(Rect position, out Rect dropDownRect) public static bool AddComponentButton(Rect position, out Rect dropDownRect)
{ {
dropDownRect = RectUtility.AddPadding(position, 20f, 20f, 1f, 1f); ; dropDownRect = RectUtility.AddPadding(position, 20f, 20f, 1f, 1f); ;

View File

@ -88,19 +88,12 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
internal class ComponentDropDown : MetaObjectsDropDown<IComponentTemplate> internal class ComponentDropDown : MetaObjectsDropDown<IComponentTemplate>
{ {
//private class StringComparer : IComparer<string>
//{
// public int Compare(string x, string y)
// {
// return x.CompareTo(y);
// }
//}
public ComponentDropDown() public ComponentDropDown()
{ {
IEnumerable<(IComponentTemplate template, ITypeMeta meta)> itemMetaPairs = ComponentTemplateTypeCache.Dummies.ToArray().Select(dummy => IEnumerable<(IComponentTemplate template, ITypeMeta meta)> itemMetaPairs = ComponentTemplateTypeCache.Dummies.ToArray().Select(dummy =>
{ {
ITypeMeta meta; ITypeMeta meta;
if (dummy is IComponentTemplateWithMetaOverride withMetaOverride) if (dummy is ITypeMeta withMetaOverride)
{ {
meta = withMetaOverride; meta = withMetaOverride;
} }

View File

@ -1,10 +1,8 @@
using DCFApixels.DragonECS.Unity.Internal; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using UnityEngine; using UnityEngine;
using UnityObject = UnityEngine.Object;
namespace DCFApixels.DragonECS.Unity.Editors namespace DCFApixels.DragonECS.Unity.Editors
{ {
@ -101,6 +99,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
#if UNITY_EDITOR #if UNITY_EDITOR
namespace DCFApixels.DragonECS.Unity.Editors namespace DCFApixels.DragonECS.Unity.Editors
{ {
using DCFApixels.DragonECS.Unity.Internal;
using UnityEditor; using UnityEditor;
using Assembly = System.Reflection.Assembly; using Assembly = System.Reflection.Assembly;
@ -109,12 +108,16 @@ namespace DCFApixels.DragonECS.Unity.Editors
{ {
static UnityEditorUtility() static UnityEditorUtility()
{ {
EcsWorld.ResetStaticState(); const int PREWARMUP_LIST_SIZE = 64;
OnLoad();
_integrationAssembly = typeof(UnityEditorUtility).Assembly; _integrationAssembly = typeof(UnityEditorUtility).Assembly;
List<Type> serializableTypes = new List<Type>(); List<Type> serializableTypes = new List<Type>(PREWARMUP_LIST_SIZE);
List<EntityEditorBlockDrawer> entityEditorBlockDrawers = new List<EntityEditorBlockDrawer>(); List<TypeMeta> typeWithMetaIDMetas = new List<TypeMeta>(PREWARMUP_LIST_SIZE);
List<TypeMeta> serializableTypeWithMetaIDMetas = new List<TypeMeta>(PREWARMUP_LIST_SIZE);
List<EntityEditorBlockDrawer> entityEditorBlockDrawers = new List<EntityEditorBlockDrawer>(PREWARMUP_LIST_SIZE);
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{ {
//var targetTypes = assembly.GetTypes().Where(type => //var targetTypes = assembly.GetTypes().Where(type =>
@ -124,29 +127,75 @@ namespace DCFApixels.DragonECS.Unity.Editors
foreach (var type in assembly.GetTypes()) foreach (var type in assembly.GetTypes())
{ {
if ((type.IsGenericType || type.IsAbstract || type.IsInterface) == false && bool hasMetaID = false;
typeof(EntityEditorBlockDrawer).IsAssignableFrom(type)) if (TypeMeta.TryGetCustomMeta(type, out TypeMeta meta) && meta.IsHasMetaID())
{ {
var drawer = (EntityEditorBlockDrawer)Activator.CreateInstance(type); typeWithMetaIDMetas.Add(meta);
entityEditorBlockDrawers.Add(drawer); hasMetaID = true;
}
if (type.IsConcreteType())
{
if (typeof(EntityEditorBlockDrawer).IsAssignableFrom(type))
{
var drawer = (EntityEditorBlockDrawer)Activator.CreateInstance(type);
entityEditorBlockDrawers.Add(drawer);
}
if (type.IsUnityObject() == false && type.GetConstructor(Type.EmptyTypes) != null)
{
serializableTypes.Add(type);
if (hasMetaID)
{
serializableTypeWithMetaIDMetas.Add(meta);
}
}
}
}
}
_serializableTypes = serializableTypes.ToArray();
_typeWithMetaIDMetas = typeWithMetaIDMetas.ToArray();
_serializableTypeWithMetaIDMetas = serializableTypeWithMetaIDMetas.ToArray();
_entityEditorBlockDrawers = entityEditorBlockDrawers.ToArray();
_metaIDCollisions = MetaID.FindMetaIDCollisions(_typeWithMetaIDMetas);
IsHasAnyMetaIDCollision = _metaIDCollisions.IsHasAnyCollision;
if (_metaIDCollisions.IsHasAnyCollision)
{
StringBuilder log = new StringBuilder();
log.Append("MetaID identifier collisions detected. Some functions that use MetaID were disabled until the collisions were fixed. List of collisions:\r\n");
{
int i = 0;
foreach (var collision in _metaIDCollisions)
{
i++;
log.Append('├');
log.Append($"ID: {collision.MetaID}\r\n");
int j = 0;
foreach (var meta in collision)
{
j++;
log.Append('│');
if (j == collision.Count)
{
log.Append('└');
}
else
{
log.Append('├');
}
log.Append($"Type: {meta.TypeName}\r\n");
}
} }
} }
var targetTypes = assembly.GetTypes().Where(type => Debug.LogError(log.ToString());
(type.IsGenericType || type.IsAbstract || type.IsInterface) == false &&
type.IsSubclassOf(typeof(UnityObject)) == false &&
type.GetConstructor(Type.EmptyTypes) != null);
serializableTypes.AddRange(targetTypes);
} }
_serializableTypes = serializableTypes.ToArray(); foreach (var item in _typeWithMetaIDMetas)
_entityEditorBlockDrawers = entityEditorBlockDrawers.ToArray();
_serializableTypeWithMetaIDMetas = serializableTypes
.Where(TypeMeta.IsHasMetaID)
.Select(type => type.ToMeta())
.ToArray();
foreach (var item in _serializableTypeWithMetaIDMetas)
{ {
_metaIDTypePairs[item.MetaID] = item.Type; _metaIDTypePairs[item.MetaID] = item.Type;
} }
@ -158,10 +207,24 @@ namespace DCFApixels.DragonECS.Unity.Editors
//}).ToArray(); //}).ToArray();
} }
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void OnLoad()
{
EcsWorld.ResetStaticState();
if (DebugService.IsNullOrDefault)
{
UnityDebugService.Activate();
}
}
internal static readonly Assembly _integrationAssembly; internal static readonly Assembly _integrationAssembly;
internal static readonly Type[] _serializableTypes; internal static readonly Type[] _serializableTypes;
internal static readonly EntityEditorBlockDrawer[] _entityEditorBlockDrawers; internal static readonly TypeMeta[] _typeWithMetaIDMetas;
internal static readonly TypeMeta[] _serializableTypeWithMetaIDMetas; internal static readonly TypeMeta[] _serializableTypeWithMetaIDMetas;
internal static readonly EntityEditorBlockDrawer[] _entityEditorBlockDrawers;
internal static readonly MetaID.CollisionList _metaIDCollisions;
public static readonly bool IsHasAnyMetaIDCollision;
private static readonly Dictionary<string, Type> _metaIDTypePairs = new Dictionary<string, Type>(); private static readonly Dictionary<string, Type> _metaIDTypePairs = new Dictionary<string, Type>();
public static bool TryGetTypeForMetaID(string metaID, out Type type) public static bool TryGetTypeForMetaID(string metaID, out Type type)
@ -170,13 +233,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
//private static Type[] _noHiddenSerializableTypes; //private static Type[] _noHiddenSerializableTypes;
private static GUIContent _singletonIconContent = null; private static GUIContent _singletonIconContent = null;
private static GUIContent _singletonContent = null; private static GUIContent _singletonContent = null;
private static GUIStyle _inputFieldCenterAnhor = null; private static GUIStyle _inputFieldCenterAnhor = null;
private static Dictionary<Type, MonoScript> _scriptsAssets = new Dictionary<Type, MonoScript>(256); private static Dictionary<Type, MonoScript> _scriptsAssets = new Dictionary<Type, MonoScript>(256);
internal static void ResetValues(this SerializedProperty property, bool isExpand = false) internal static void ResetValues(this SerializedProperty property, bool isExpand = false)
{ {
ResetValues_Internal(property.Copy(), isExpand, property.depth); ResetValues_Internal(property.Copy(), isExpand, property.depth);

View File

@ -1,4 +1,5 @@
#if UNITY_EDITOR #if UNITY_EDITOR
using DCFApixels.DragonECS.Unity.Internal;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEditor; using UnityEditor;
@ -19,42 +20,35 @@ namespace DCFApixels.DragonECS.Unity.Editors
foreach (string str in importedAssets) foreach (string str in importedAssets)
{ {
//Debug.Log("Reimported Asset: " + str);
ProcessAssetPath(str); ProcessAssetPath(str);
} }
foreach (string str in deletedAssets) foreach (string str in deletedAssets)
{ {
//Debug.Log("Deleted Asset: " + str);
RemoveAssetPath(str); RemoveAssetPath(str);
} }
foreach (var str in movedFromAssetPaths)
for (int i = 0; i < movedFromAssetPaths.Length; i++)
{ {
RemoveAssetPath(movedFromAssetPaths[i]); RemoveAssetPath(str);
} }
for (int i = 0; i < movedAssets.Length; i++) foreach (string str in movedAssets)
{ {
//Debug.Log("Moved Asset: " + movedAssets[i] + " from: " + movedFromAssetPaths[i]); ProcessAssetPath(str);
ProcessAssetPath(movedAssets[i]);
} }
//if (didDomainReload) //if (didDomainReload)
//{ //{
// Debug.Log("Domain has been reloaded"); // Debug.Log("Domain has been reloaded");
//} //}
_timeTicks = DateTime.Now.Ticks; _timeTicks = DateTime.Now.Ticks;
} }
private static List<string> _removedScriptGuids = new List<string>(); private static List<string> _removedScriptGuids = new List<string>();
private static List<string> _newScriptIDs = new List<string>(); private static List<string> _newScriptIDs = new List<string>();
public static IReadOnlyCollection<string> RemovedScriptPaths public static ReadOnlyList<string> RemovedScriptPaths
{ {
get { return _removedScriptGuids; } get { return _removedScriptGuids; }
} }
public static IReadOnlyCollection<string> NewScriptPaths public static ReadOnlyList<string> NewScriptPaths
{ {
get { return _newScriptIDs; } get { return _newScriptIDs; }
} }
@ -62,16 +56,12 @@ namespace DCFApixels.DragonECS.Unity.Editors
private static void RemoveAssetPath(string filePath) private static void RemoveAssetPath(string filePath)
{ {
if (IsScript(filePath) == false) { return; } if (IsScript(filePath) == false) { return; }
//Debug.Log("RemoveAssetPath: " + filePath);
_removedScriptGuids.Add(filePath); _removedScriptGuids.Add(filePath);
} }
private static void ProcessAssetPath(string filePath) private static void ProcessAssetPath(string filePath)
{ {
if (IsScript(filePath) == false) { return; } if (IsScript(filePath) == false) { return; }
//Debug.Log("ProcessAssetPath: " + filePath);
var script = AssetDatabase.LoadAssetAtPath<MonoScript>(filePath).text;
_newScriptIDs.Add(filePath); _newScriptIDs.Add(filePath);
} }

View File

@ -2,6 +2,7 @@
using System; using System;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using UnityObject = UnityEngine.Object;
namespace DCFApixels.DragonECS.Unity.Internal namespace DCFApixels.DragonECS.Unity.Internal
{ {
@ -18,6 +19,20 @@ namespace DCFApixels.DragonECS.Unity.Internal
{ {
return self.GetCustomAttribute<T>() != null; return self.GetCustomAttribute<T>() != null;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsConcreteType(this Type self)
{
if (self.IsGenericType || self.IsAbstract || self.IsInterface)
{
return false;
}
return self.IsValueType || self.IsClass;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsUnityObject(this Type self)
{
return self.IsSubclassOf(typeof(UnityObject));
}
} }
} }
#endif #endif

View File

@ -33,55 +33,84 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
#endregion #endregion
private static Dictionary<string, string> _metaIDScriptPathPairs = new Dictionary<string, string>(); private static Dictionary<string, string> _metaIDScriptPathPairs = new Dictionary<string, string>();
public static IReadOnlyDictionary<string, string> MetaIDScriptPathPairs
{
get
{
instance.InitUpdate();
return _metaIDScriptPathPairs;
}
}
private static SparseArray<MonoScript> _scriptsAssets = new SparseArray<MonoScript>(256); private static SparseArray<MonoScript> _scriptsAssets = new SparseArray<MonoScript>(256);
public static void Reinit()
{
instance._isInit = false;
_metaIDScriptPathPairs.Clear();
instance.InitUpdate();
}
#region Init/Update #region Init/Update
private static object _lock = new object();
private void InitUpdate() private void InitUpdate()
{ {
Init(); Init();
if (MonoScriptsAssetProcessor.Version <= _version) { return; } if (MonoScriptsAssetProcessor.Version <= _version) { return; }
lock (_lock)
if (MonoScriptsAssetProcessor.RemovedScriptPaths.Count > 0)
{ {
uint pathsLength = (uint)MonoScriptsAssetProcessor.RemovedScriptPaths.Count; if (MonoScriptsAssetProcessor.Version <= _version) { return; }
string[] paths = new string[pathsLength];
int i = 0; var paths = MonoScriptsAssetProcessor.RemovedScriptPaths;
foreach (var path in MonoScriptsAssetProcessor.RemovedScriptPaths) if (paths.Count > 0)
{ {
paths[i++] = path; List<string> removedKeys = new List<string>();
} foreach (var metaIDScriptPathPair in _metaIDScriptPathPairs)
foreach (var metaIDScriptPathPair in _metaIDScriptPathPairs)
{
for (uint j = 0; j < pathsLength; j++)
{ {
if (paths[j] == metaIDScriptPathPair.Value) for (int j = 0; j < paths.Count; j++)
{ {
_metaIDScriptPathPairs[metaIDScriptPathPair.Key] = null; if (paths[j] == metaIDScriptPathPair.Value)
{
removedKeys.Add(metaIDScriptPathPair.Key);
}
}
}
foreach (var key in removedKeys)
{
_metaIDScriptPathPairs.Remove(key);
}
}
paths = MonoScriptsAssetProcessor.NewScriptPaths;
if (paths.Count > 0)
{
List<string> metaIDs = new List<string>();
foreach (var assetPath in paths)
{
ExtractMetaIDs(AssetDatabase.LoadAssetAtPath<MonoScript>(assetPath).text, metaIDs);
foreach (var metaID in metaIDs)
{
_metaIDScriptPathPairs[metaID] = assetPath;
} }
} }
} }
}
List<string> metaIDs = new List<string>(); _version = MonoScriptsAssetProcessor.Version;
foreach (var assetPath in MonoScriptsAssetProcessor.NewScriptPaths)
{
ExtractMetaIDs(AssetDatabase.LoadAssetAtPath<MonoScript>(assetPath).text, metaIDs);
foreach (var metaID in metaIDs)
{
_metaIDScriptPathPairs[metaID] = assetPath;
}
}
_version = MonoScriptsAssetProcessor.Version;
Save(true); Save(true);
}
} }
private void Init() private void Init()
{ {
if (_isInit && _metaIDScriptPathPairs.Count > 0) { return; } if (_isInit && _metaIDScriptPathPairs.Count > 0) { return; }
if (_metaIDScriptPathPairs == null)
{
_metaIDScriptPathPairs = new Dictionary<string, string>();
}
_metaIDScriptPathPairs.Clear(); _metaIDScriptPathPairs.Clear();
var scriptGuids = AssetDatabase.FindAssets($"* t:MonoScript"); var scriptGuids = AssetDatabase.FindAssets($"* t:MonoScript");
@ -113,44 +142,44 @@ namespace DCFApixels.DragonECS.Unity.Editors
Save(true); Save(true);
} }
public void Reinit()
{
_isInit = false;
InitUpdate();
}
#endregion #endregion
#region Get #region Get
public static bool TryGetScriptAsset(TypeMeta meta, out MonoScript script) public static bool TryGetScriptAsset(TypeMeta meta, out MonoScript script)
{ {
int uniqueID = meta.GetHashCode(); int metaUniqueID = meta.GetHashCode();
if (_scriptsAssets.TryGetValue(uniqueID, out script) == false) if (_scriptsAssets.TryGetValue(metaUniqueID, out script) == false)
{ {
script = null; script = null;
//Ищем по мета айди совпадения //Ищем по мета айди совпадения
string metaID = meta.MetaID; if (UnityEditorUtility.IsHasAnyMetaIDCollision == false)
if (string.IsNullOrEmpty(metaID) == false)
{ {
instance.InitUpdate(); if (meta.IsHasMetaID())
if (_metaIDScriptPathPairs.TryGetValue(metaID, out string assetPath))
{ {
if (assetPath == null) instance.InitUpdate();
string metaID = meta.MetaID;
if (_metaIDScriptPathPairs.TryGetValue(metaID, out string assetPath))
{ {
_metaIDScriptPathPairs.Remove(metaID); if (assetPath == null)
}
else
{
MonoScript textAsset = AssetDatabase.LoadAssetAtPath<MonoScript>(assetPath);
if (textAsset != null)
{ {
script = textAsset; _metaIDScriptPathPairs.Remove(metaID);
}
else
{
MonoScript textAsset = AssetDatabase.LoadAssetAtPath<MonoScript>(assetPath);
if (textAsset != null)
{
script = textAsset;
}
} }
} }
} }
} }
if (script == null) if (script == null)
{ {
//Ищем совпадения имен в ассетах //Ищем совпадения имен в ассетах
@ -170,7 +199,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
if (assetPath.IndexOf("Packages/com.unity.") == 0) if (assetPath.IndexOf("Packages/com.unity.") == 0)
{ {
if(skippedCount == 0) if (skippedCount == 0)
{ {
skipped = new string[guids.Length]; skipped = new string[guids.Length];
} }
@ -185,7 +214,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
} }
if(script == null) if (script == null)
{ {
foreach (var assetPath in new ReadOnlySpan<string>(skipped, 0, skippedCount)) foreach (var assetPath in new ReadOnlySpan<string>(skipped, 0, skippedCount))
{ {
@ -199,7 +228,9 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
} }
_scriptsAssets.Add(uniqueID, script);
_scriptsAssets.Add(metaUniqueID, script);
} }
return script != null; return script != null;
} }

View File

@ -9,7 +9,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
{ {
public const int MIN_CAPACITY_BITS_OFFSET = 4; public const int MIN_CAPACITY_BITS_OFFSET = 4;
public const int MIN_CAPACITY = 1 << MIN_CAPACITY_BITS_OFFSET; public const int MIN_CAPACITY = 1 << MIN_CAPACITY_BITS_OFFSET;
private const int EMPTY = -1; private const int EMPTY_BUCKET = -1;
private int[] _buckets = Array.Empty<int>(); private int[] _buckets = Array.Empty<int>();
private Entry[] _entries = Array.Empty<Entry>(); private Entry[] _entries = Array.Empty<Entry>();
@ -37,7 +37,9 @@ namespace DCFApixels.DragonECS.Unity.Internal
minCapacity = NormalizeCapacity(minCapacity); minCapacity = NormalizeCapacity(minCapacity);
_buckets = new int[minCapacity]; _buckets = new int[minCapacity];
for (int i = 0; i < minCapacity; i++) for (int i = 0; i < minCapacity; i++)
_buckets[i] = EMPTY; {
_buckets[i] = EMPTY_BUCKET;
}
_entries = new Entry[minCapacity]; _entries = new Entry[minCapacity];
_modBitMask = (minCapacity - 1) & 0x7FFFFFFF; _modBitMask = (minCapacity - 1) & 0x7FFFFFFF;
} }
@ -60,7 +62,9 @@ namespace DCFApixels.DragonECS.Unity.Internal
private int FindEntry(int key) private int FindEntry(int key)
{ {
for (int i = _buckets[key & _modBitMask]; i >= 0; i = _entries[i].next) for (int i = _buckets[key & _modBitMask]; i >= 0; i = _entries[i].next)
if (_entries[i].hashKey == key) return i; {
if (_entries[i].hashKey == key) { return i; }
}
return -1; return -1;
} }
private void Insert(int key, TValue value) private void Insert(int key, TValue value)
@ -154,10 +158,12 @@ namespace DCFApixels.DragonECS.Unity.Internal
{ {
for (int i = 0; i < _buckets.Length; i++) for (int i = 0; i < _buckets.Length; i++)
{ {
_buckets[i] = -1; _buckets[i] = EMPTY_BUCKET;
} }
Array.Clear(_entries, 0, _count); Array.Clear(_entries, 0, _entries.Length);
_count = 0; _count = 0;
_freeList = 0;
_freeCount = 0;
} }
} }
#endregion #endregion
@ -171,7 +177,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
Contract.Assert(newSize >= _entries.Length); Contract.Assert(newSize >= _entries.Length);
int[] newBuckets = new int[newSize]; int[] newBuckets = new int[newSize];
for (int i = 0; i < newBuckets.Length; i++) for (int i = 0; i < newBuckets.Length; i++)
newBuckets[i] = EMPTY; newBuckets[i] = EMPTY_BUCKET;
Entry[] newEntries = new Entry[newSize]; Entry[] newEntries = new Entry[newSize];
Array.Copy(_entries, 0, newEntries, 0, _count); Array.Copy(_entries, 0, newEntries, 0, _count);

View File

@ -0,0 +1,40 @@
using System.Collections;
using System.Collections.Generic;
namespace DCFApixels.DragonECS.Unity.Internal
{
internal readonly struct ReadOnlyList<T> : IEnumerable<T>, IReadOnlyList<T>
{
private readonly List<T> _list;
public ReadOnlyList(List<T> list)
{
_list = list;
}
public int Count
{
get { return _list.Count; }
}
public T this[int index]
{
get { return _list[index]; }
set { _list[index] = value; }
}
public bool Contains(T item)
{
return _list.Contains(item);
}
public List<T>.Enumerator GetEnumerator()
{
return _list.GetEnumerator();
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return _list.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _list.GetEnumerator();
}
public static implicit operator ReadOnlyList<T>(List<T> a) { return new ReadOnlyList<T>(a); }
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d6be8f1171a60d646b862ec8472c55ef
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -3,13 +3,18 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Threading;
using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Internal namespace DCFApixels.DragonECS.Unity.Internal
{ {
[Serializable]
[DebuggerDisplay("Count: {Count}")] [DebuggerDisplay("Count: {Count}")]
internal struct StructList<T> internal struct StructList<T>
{ {
[SerializeField]
internal T[] _items; internal T[] _items;
[SerializeField]
internal int _count; internal int _count;
public IEnumerable<T> Enumerable public IEnumerable<T> Enumerable
@ -39,7 +44,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
set set
{ {
if (value <= _items.Length) { return; } if (value <= _items.Length) { return; }
value = ArrayUtility.NormalizeSizeToPowerOfTwo(value); value = DragonArrayUtility.NextPow2(value);
Array.Resize(ref _items, value); Array.Resize(ref _items, value);
} }
} }
@ -66,7 +71,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public StructList(int capacity) public StructList(int capacity)
{ {
_items = new T[ArrayUtility.NormalizeSizeToPowerOfTwo(capacity)]; _items = new T[DragonArrayUtility.NextPow2(capacity)];
_count = 0; _count = 0;
} }
@ -92,6 +97,24 @@ namespace DCFApixels.DragonECS.Unity.Internal
_items[idnex2] = tmp; _items[idnex2] = tmp;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref T FastDequeue()
{
#if DEBUG
if (_count <= 0) { Throw.ArgumentOutOfRange(); }
#endif
return ref _items[--_count];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public T Dequeue()
{
#if DEBUG
if (_count <= 0) { Throw.ArgumentOutOfRange(); }
#endif
T result = _items[--_count];
_items[_count] = default;
return result;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void FastRemoveAt(int index) public void FastRemoveAt(int index)
{ {
#if DEBUG #if DEBUG
@ -131,6 +154,33 @@ namespace DCFApixels.DragonECS.Unity.Internal
return false; return false;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void FastRemoveSpan(int startIndex, int length)
{
#if DEBUG
if (startIndex < 0) { Throw.ArgumentOutOfRange(); }
if (length < 0) { Throw.ArgumentOutOfRange(); }
if (startIndex + length > _count) { Throw.Argument("Invalid range specified"); }
#endif
if (length == 0 || _count == 0) { return; }
int elementsToMove = _count - (startIndex + length);
if (elementsToMove > 0)
{
Array.Copy(
sourceArray: _items,
sourceIndex: startIndex + length,
destinationArray: _items,
destinationIndex: startIndex,
length: elementsToMove
);
}
_count -= length;
//RuntimeHelpers.IsReferenceOrContainsReferences<T>();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool RemoveWithOrder(T item) public bool RemoveWithOrder(T item)
{ {
int index = IndexOf(item); int index = IndexOf(item);
@ -178,4 +228,38 @@ namespace DCFApixels.DragonECS.Unity.Internal
return _items; return _items;
} }
} }
internal static class StructListExt
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Add_MultiAccess<T>(this ref StructList<T> self, T item)
{
var index = Interlocked.Increment(ref self._count);
index -= 1;
if (index >= self._items.Length)
{
lock (self._items)
{
if (index >= self._items.Length)
{
Array.Resize(ref self._items, self._items.Length << 1);
}
}
}
self._items[index] = item;
}
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public static bool TryDequeue_MultiAccess<T>(this ref StructList<T> self, T item)
// {
// var index = Interlocked.Increment(ref self._count);
//
//#if DEBUG
// if (_count <= 0) { Throw.ArgumentOutOfRange(); }
//#endif
// T result = _items[--_count];
// _items[_count] = default;
// return result;
// }
}
} }

View File

@ -8,5 +8,13 @@ namespace DCFApixels.DragonECS.Unity.Internal
{ {
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
} }
internal static void Argument(string message)
{
throw new ArgumentException(message);
}
internal static void Exception()
{
throw new Exception();
}
} }
} }

View File

@ -30,7 +30,6 @@ namespace DCFApixels.DragonECS.Unity.Editors
internal class ComponentTemplateReferenceDrawer : ExtendedPropertyDrawer<ComponentTemplateReferenceAttribute> internal class ComponentTemplateReferenceDrawer : ExtendedPropertyDrawer<ComponentTemplateReferenceAttribute>
{ {
private const float DamagedComponentHeight = 18f * 2f; private const float DamagedComponentHeight = 18f * 2f;
private static readonly Rect HeadIconsRect = new Rect(0f, 0f, 19f, 19f);
private static ComponentDropDown _componentDropDown; private static ComponentDropDown _componentDropDown;
#region Properties #region Properties

View File

@ -9,13 +9,13 @@ namespace DCFApixels.DragonECS.Unity.Editors
{ {
internal abstract class EntityTemplateEditorBase : ExtendedEditor<IEntityTemplateInternal> internal abstract class EntityTemplateEditorBase : ExtendedEditor<IEntityTemplateInternal>
{ {
private static readonly Rect HeadIconsRect = new Rect(0f, 0f, 19f, 19f);
private ComponentDropDown _componentDropDown; private ComponentDropDown _componentDropDown;
private SerializedProperty _componentsProp; private SerializedProperty _componentsProp;
private ReorderableList _reorderableComponentsList; private ReorderableList _reorderableComponentsList;
protected abstract bool IsSO { get; }
//public virtual bool IsStaticData { get { return false; } } //public virtual bool IsStaticData { get { return false; } }
#region Init #region Init
@ -156,8 +156,14 @@ namespace DCFApixels.DragonECS.Unity.Editors
{ {
Init(); Init();
if (_componentsProp == null) if (IsSO)
{ {
EcsGUI.Layout.ManuallySerializeButton(targets);
}
if (IsMultipleTargets)
{
GUILayout.Label("Multi-object editing not supported.", EditorStyles.helpBox);
return; return;
} }
@ -177,10 +183,23 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
} }
using (EcsGUI.Layout.BeginVertical(UnityEditorUtility.GetTransperentBlackBackgrounStyle()))
SerializedProperty iterator = serializedObject.GetIterator();
iterator.NextVisible(true);
while (iterator.NextVisible(false))
{ {
DrawTop(Target, _componentsProp); if (_componentsProp != null && iterator.name == _componentsProp.name)
_reorderableComponentsList.DoLayoutList(); {
using (EcsGUI.Layout.BeginVertical(UnityEditorUtility.GetTransperentBlackBackgrounStyle()))
{
DrawTop(Target, _componentsProp);
_reorderableComponentsList.DoLayoutList();
}
}
else
{
EditorGUILayout.PropertyField(iterator, true);
}
} }
} }
private void DrawTop(IEntityTemplateInternal target, SerializedProperty componentsProp) private void DrawTop(IEntityTemplateInternal target, SerializedProperty componentsProp)
@ -202,15 +221,19 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
} }
[CanEditMultipleObjects]
[CustomEditor(typeof(ScriptableEntityTemplate), true)] [CustomEditor(typeof(ScriptableEntityTemplate), true)]
internal class ScriptableEntityTemplateEditor : EntityTemplateEditorBase internal class ScriptableEntityTemplateEditor : EntityTemplateEditorBase
{ {
//public override bool IsStaticData { get { return true; } } //public override bool IsStaticData { get { return true; } }
protected override bool IsSO => true;
} }
[CanEditMultipleObjects]
[CustomEditor(typeof(MonoEntityTemplate), true)] [CustomEditor(typeof(MonoEntityTemplate), true)]
internal class MonoEntityTemplateEditor : EntityTemplateEditorBase internal class MonoEntityTemplateEditor : EntityTemplateEditorBase
{ {
//public override bool IsStaticData { get { return false; } } //public override bool IsStaticData { get { return false; } }
protected override bool IsSO => false;
} }
} }
#endif #endif

View File

@ -1,6 +1,7 @@
#if DISABLE_DEBUG #if DISABLE_DEBUG
#undef DEBUG #undef DEBUG
#endif #endif
using DCFApixels.DragonECS.Core;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -31,10 +32,9 @@ namespace DCFApixels.DragonECS
Selected Selected
} }
} }
public interface IComponentTemplateWithMetaOverride : IComponentTemplate, ITypeMeta { }
[Serializable] [Serializable]
public abstract class ComponentTemplateBase : IComponentTemplateWithMetaOverride public abstract class ComponentTemplateBase : IComponentTemplate, ITypeMeta
{ {
#region Properties #region Properties
public abstract Type Type { get; } public abstract Type Type { get; }
@ -58,14 +58,50 @@ namespace DCFApixels.DragonECS
} }
[Serializable] [Serializable]
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public abstract class ComponentTemplateBase<T> : ComponentTemplateBase public abstract class ComponentTemplateBase<T> : ComponentTemplateBase, ICloneable
{ {
protected static TypeMeta Meta = EcsDebugUtility.GetTypeMeta<T>(); protected static readonly TypeMeta Meta = EcsDebugUtility.GetTypeMeta<T>();
protected static readonly bool _isHasIEcsComponentLifecycle;
protected static readonly IEcsComponentLifecycle<T> _iEcsComponentLifecycle;
private static bool _defaultValueTypeInit = false;
private static T _defaultValueType;
protected static T DefaultValueType
{
get
{
if (_defaultValueTypeInit == false)
{
Type type = typeof(T);
if (type.IsValueType)
{
FieldInfo field;
field = type.GetField("Default", BindingFlags.Static | BindingFlags.Public);
if (field != null && field.FieldType == type)
{
_defaultValueType = (T)field.GetValue(null);
}
field = type.GetField("Empty", BindingFlags.Static | BindingFlags.Public);
if (field != null && field.FieldType == type)
{
_defaultValueType = (T)field.GetValue(null);
}
}
}
return _defaultValueType;
}
}
static ComponentTemplateBase()
{
_isHasIEcsComponentLifecycle = EcsComponentLifecycleHandler<T>.isHasHandler;
_iEcsComponentLifecycle = EcsComponentLifecycleHandler<T>.instance;
}
[SerializeField] [SerializeField]
protected T component; protected T component = DefaultValueType;
[SerializeField] [SerializeField]
[HideInInspector] [HideInInspector]
private byte _offset; // Fucking Unity drove me crazy with the error "Cannot get managed reference index with out bounds offset". This workaround helps avoid that error. private byte _offset; // Avoids the error "Cannot get managed reference index with out bounds offset"
#region Properties #region Properties
public sealed override ITypeMeta BaseMeta { get { return Meta; } } public sealed override ITypeMeta BaseMeta { get { return Meta; } }
@ -80,6 +116,13 @@ namespace DCFApixels.DragonECS
#region Methods #region Methods
public sealed override object GetRaw() { return component; } public sealed override object GetRaw() { return component; }
public sealed override void SetRaw(object raw) { component = (T)raw; } public sealed override void SetRaw(object raw) { component = (T)raw; }
protected virtual T CloneComponent() { return component; }
object ICloneable.Clone()
{
ComponentTemplateBase<T> templateClone = (ComponentTemplateBase<T>)MemberwiseClone();
templateClone.component = CloneComponent();
return templateClone;
}
#endregion #endregion
} }
@ -88,7 +131,7 @@ namespace DCFApixels.DragonECS
{ {
public override void Apply(short worldID, int entityID) public override void Apply(short worldID, int entityID)
{ {
EcsWorld.GetPoolInstance<EcsPool<T>>(worldID).TryAddOrGet(entityID) = component; EcsPool<T>.Apply(ref component, entityID, worldID);
} }
} }
public abstract class TagComponentTemplate<T> : ComponentTemplateBase<T> public abstract class TagComponentTemplate<T> : ComponentTemplateBase<T>
@ -96,7 +139,7 @@ namespace DCFApixels.DragonECS
{ {
public override void Apply(short worldID, int entityID) public override void Apply(short worldID, int entityID)
{ {
EcsWorld.GetPoolInstance<EcsTagPool<T>>(worldID).Set(entityID, true); EcsTagPool<T>.Apply(ref component, entityID, worldID);
} }
} }
} }
@ -108,6 +151,10 @@ namespace DCFApixels.DragonECS.Unity.Internal
private static MethodInfo memberwiseCloneMethdo = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic); private static MethodInfo memberwiseCloneMethdo = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic);
internal static IComponentTemplate Clone(this IComponentTemplate obj) internal static IComponentTemplate Clone(this IComponentTemplate obj)
{ {
if(obj is ICloneable cloneable)
{
return (IComponentTemplate)cloneable.Clone();
}
return (IComponentTemplate)memberwiseCloneMethdo.Invoke(obj, null); return (IComponentTemplate)memberwiseCloneMethdo.Invoke(obj, null);
} }
} }

View File

@ -4,6 +4,8 @@
using DCFApixels.DragonECS.Unity; using DCFApixels.DragonECS.Unity;
using DCFApixels.DragonECS.Unity.Internal; using DCFApixels.DragonECS.Unity.Internal;
using System; using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine; using UnityEngine;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
@ -18,55 +20,63 @@ namespace DCFApixels.DragonECS
[MetaColor(MetaColor.DragonCyan)] [MetaColor(MetaColor.DragonCyan)]
[MetaGroup(EcsUnityConsts.PACK_GROUP, EcsUnityConsts.ENTITY_BUILDING_GROUP)] [MetaGroup(EcsUnityConsts.PACK_GROUP, EcsUnityConsts.ENTITY_BUILDING_GROUP)]
[MetaDescription(EcsConsts.AUTHOR, nameof(MonoBehaviour) + " implementation of an entity template. Templates are a set of components that are applied to entities.")] [MetaDescription(EcsConsts.AUTHOR, nameof(MonoBehaviour) + " implementation of an entity template. Templates are a set of components that are applied to entities.")]
[MetaID("C734BA8092014833C14F21E05D7B1551")] [MetaID("DragonECS_C734BA8092014833C14F21E05D7B1551")]
public class MonoEntityTemplate : MonoEntityTemplateBase, IEntityTemplateInternal public class MonoEntityTemplate : MonoEntityTemplateBase, IEntityTemplateInternal
{ {
[SerializeReference] [SerializeReference]
[ReferenceButton(true, typeof(IComponentTemplate))] [ReferenceButton(true, typeof(IComponentTemplate))]
private IComponentTemplate[] _components; private IComponentTemplate[] _componentTemplates;
#region Properties #region Properties
string IEntityTemplateInternal.ComponentsPropertyName string IEntityTemplateInternal.ComponentsPropertyName
{ {
get { return nameof(_components); } get { return nameof(_componentTemplates); }
} }
#endregion #endregion
#region Methods #region Methods
public ReadOnlySpan<IComponentTemplate> GetComponentTemplates()
{
return _componentTemplates;
}
public void SetComponentTemplates(IEnumerable<IComponentTemplate> componentTemplates)
{
_componentTemplates = componentTemplates.ToArray();
}
public override void Apply(short worldID, int entityID) public override void Apply(short worldID, int entityID)
{ {
foreach (var item in _components) foreach (var item in _componentTemplates)
{ {
item.Apply(worldID, entityID); item.Apply(worldID, entityID);
} }
} }
public void Clear() public void Clear()
{ {
_components = Array.Empty<IComponentTemplate>(); _componentTemplates = Array.Empty<IComponentTemplate>();
} }
#endregion #endregion
#region UnityEvents #region UnityEvents
private void OnValidate() private void OnValidate()
{ {
if (_components == null) { return; } if (_componentTemplates == null) { return; }
foreach (var item in _components) foreach (var item in _componentTemplates)
{ {
item?.OnValidate(gameObject); item?.OnValidate(gameObject);
} }
} }
private void OnDrawGizmos() private void OnDrawGizmos()
{ {
if (_components == null) { return; } if (_componentTemplates == null) { return; }
foreach (var item in _components) foreach (var item in _componentTemplates)
{ {
item?.OnGizmos(transform, IComponentTemplate.GizmosMode.Always); item?.OnGizmos(transform, IComponentTemplate.GizmosMode.Always);
} }
} }
private void OnDrawGizmosSelected() private void OnDrawGizmosSelected()
{ {
if (_components == null) { return; } if (_componentTemplates == null) { return; }
foreach (var item in _components) foreach (var item in _componentTemplates)
{ {
item?.OnGizmos(transform, IComponentTemplate.GizmosMode.Selected); item?.OnGizmos(transform, IComponentTemplate.GizmosMode.Selected);
} }

View File

@ -4,6 +4,8 @@
using DCFApixels.DragonECS.Unity; using DCFApixels.DragonECS.Unity;
using DCFApixels.DragonECS.Unity.Internal; using DCFApixels.DragonECS.Unity.Internal;
using System; using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine; using UnityEngine;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
@ -17,39 +19,61 @@ namespace DCFApixels.DragonECS
[MetaGroup(EcsUnityConsts.PACK_GROUP, EcsUnityConsts.ENTITY_BUILDING_GROUP)] [MetaGroup(EcsUnityConsts.PACK_GROUP, EcsUnityConsts.ENTITY_BUILDING_GROUP)]
[MetaDescription(EcsConsts.AUTHOR, nameof(ScriptableObject) + " implementation of an entity template. Templates are a set of components that are applied to entities.")] [MetaDescription(EcsConsts.AUTHOR, nameof(ScriptableObject) + " implementation of an entity template. Templates are a set of components that are applied to entities.")]
[CreateAssetMenu(fileName = nameof(ScriptableEntityTemplate), menuName = EcsConsts.FRAMEWORK_NAME + "/" + nameof(ScriptableEntityTemplate), order = 1)] [CreateAssetMenu(fileName = nameof(ScriptableEntityTemplate), menuName = EcsConsts.FRAMEWORK_NAME + "/" + nameof(ScriptableEntityTemplate), order = 1)]
[MetaID("7C4DBA809201D959401A5BDFB6363EC0")] [MetaID("DragonECS_7C4DBA809201D959401A5BDFB6363EC0")]
public class ScriptableEntityTemplate : ScriptableEntityTemplateBase, IEntityTemplateInternal public class ScriptableEntityTemplate : ScriptableEntityTemplateBase, IEntityTemplateInternal
{ {
[SerializeField]
private ScriptableEntityTemplateBase[] _templates;
[SerializeReference] [SerializeReference]
[ReferenceButton(true, typeof(IComponentTemplate))] [ReferenceButton(true, typeof(IComponentTemplate))]
private IComponentTemplate[] _components; private IComponentTemplate[] _componentTemplates;
#region Properties #region Properties
string IEntityTemplateInternal.ComponentsPropertyName string IEntityTemplateInternal.ComponentsPropertyName
{ {
get { return nameof(_components); } get { return nameof(_componentTemplates); }
} }
#endregion #endregion
#region Methods #region Methods
public ReadOnlySpan<ScriptableEntityTemplateBase> GetTemplates()
{
return _templates;
}
public void SetTemplates(IEnumerable<ScriptableEntityTemplateBase> templates)
{
_templates = templates.ToArray();
}
public ReadOnlySpan<IComponentTemplate> GetComponentTemplates()
{
return _componentTemplates;
}
public void SetComponentTemplates(IEnumerable<IComponentTemplate> componentTemplates)
{
_componentTemplates = componentTemplates.ToArray();
}
public override void Apply(short worldID, int entityID) public override void Apply(short worldID, int entityID)
{ {
foreach (var item in _components) foreach (var template in _templates)
{
template.Apply(worldID, entityID);
}
foreach (var item in _componentTemplates)
{ {
item.Apply(worldID, entityID); item.Apply(worldID, entityID);
} }
} }
public void Clear() public void Clear()
{ {
_components = Array.Empty<IComponentTemplate>(); _componentTemplates = Array.Empty<IComponentTemplate>();
} }
#endregion #endregion
#region UnityEvents #region UnityEvents
private void OnValidate() private void OnValidate()
{ {
if (_components == null) { return; } if (_componentTemplates == null) { return; }
foreach (var item in _components) foreach (var item in _componentTemplates)
{ {
item?.OnValidate(this); item?.OnValidate(this);
} }

View File

@ -8,8 +8,7 @@ using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Editors namespace DCFApixels.DragonECS.Unity.Editors
{ {
[CustomEditor(typeof(ScriptablePipelineTemplate))] internal abstract class PipelineTemplateEditorBase : ExtendedEditor<IPipelineTemplate>
internal class PipelineTemplateEditorBase : ExtendedEditor<IPipelineTemplate>
{ {
private SerializedProperty _parametersProp; private SerializedProperty _parametersProp;
private SerializedProperty _layersProp; private SerializedProperty _layersProp;
@ -23,6 +22,8 @@ namespace DCFApixels.DragonECS.Unity.Editors
get => _reorderableLayersList != null && _reorderableRecordsList != null; get => _reorderableLayersList != null && _reorderableRecordsList != null;
} }
protected abstract bool IsSO { get; }
protected override void OnStaticInit() { } protected override void OnStaticInit() { }
protected override void OnInit() protected override void OnInit()
{ {
@ -143,6 +144,17 @@ namespace DCFApixels.DragonECS.Unity.Editors
protected override void DrawCustom() protected override void DrawCustom()
{ {
if (IsSO)
{
EcsGUI.Layout.ManuallySerializeButton(targets);
}
if (IsMultipleTargets)
{
GUILayout.Label("Multi-object editing not supported.", EditorStyles.helpBox);
return;
}
EcsGUI.Changed = GUILayout.Button("Validate"); EcsGUI.Changed = GUILayout.Button("Validate");
DrawLayoutNameList(_layersProp); DrawLayoutNameList(_layersProp);
@ -199,8 +211,14 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
[CustomEditor(typeof(ScriptablePipelineTemplate), true)] [CustomEditor(typeof(ScriptablePipelineTemplate), true)]
internal class ScriptablePipelineTemplateEditor : PipelineTemplateEditorBase { } internal class ScriptablePipelineTemplateEditor : PipelineTemplateEditorBase
{
protected override bool IsSO => true;
}
[CustomEditor(typeof(MonoPipelineTemplate), true)] [CustomEditor(typeof(MonoPipelineTemplate), true)]
internal class MonoPipelineTemplateEditor : PipelineTemplateEditorBase { } internal class MonoPipelineTemplateEditor : PipelineTemplateEditorBase
{
protected override bool IsSO => false;
}
} }
#endif #endif

View File

@ -11,7 +11,7 @@ namespace DCFApixels.DragonECS
[MetaName("MonoBehaviourSystem")] [MetaName("MonoBehaviourSystem")]
[MetaColor(MetaColor.DragonCyan)] [MetaColor(MetaColor.DragonCyan)]
[MetaDescription(AUTHOR, "Wrapper for MonoBehaviour systems")] [MetaDescription(AUTHOR, "Wrapper for MonoBehaviour systems")]
[MetaID("2877029E9201347B4F58E1EC0A4BCD1B")] [MetaID("DragonECS_2877029E9201347B4F58E1EC0A4BCD1B")]
[MetaGroup(EcsUnityConsts.PACK_GROUP, OTHER_GROUP)] [MetaGroup(EcsUnityConsts.PACK_GROUP, OTHER_GROUP)]
public class MonoBehaviourSystemWrapper : IEcsModule public class MonoBehaviourSystemWrapper : IEcsModule
{ {

View File

@ -11,7 +11,7 @@ namespace DCFApixels.DragonECS
[MetaName("ScriptableObjectSystem")] [MetaName("ScriptableObjectSystem")]
[MetaColor(MetaColor.DragonCyan)] [MetaColor(MetaColor.DragonCyan)]
[MetaDescription(AUTHOR, "Wrapper for ScriptableObject systems")] [MetaDescription(AUTHOR, "Wrapper for ScriptableObject systems")]
[MetaID("F5A94C5F92015B4D9286E76809311AF4")] [MetaID("DragonECS_F5A94C5F92015B4D9286E76809311AF4")]
[MetaGroup(EcsUnityConsts.PACK_GROUP, OTHER_GROUP)] [MetaGroup(EcsUnityConsts.PACK_GROUP, OTHER_GROUP)]
public class ScriptableObjectSystemWrapper : IEcsModule public class ScriptableObjectSystemWrapper : IEcsModule
{ {

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: da6b7ba7fc0a44a4f8228f10ef5abcd1
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 620c5dc67428c21428ff4bd9c92ed631
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,89 @@
#if UNITY_EDITOR
using DCFApixels.DragonECS.Unity.Internal;
using DCFApixels.DragonECS.Unity.RefRepairer.Editors;
using DCFApixels.DragonECS.Unity.RefRepairer.Internal;
using UnityEditor;
using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Editors
{
internal class DeepDebuggerWindow : EditorWindow
{
public const string TITLE = "DeepDebuggerWindow";
#if DRAGONECS_DEEP_DEBUG
[MenuItem("Tools/" + EcsConsts.FRAMEWORK_NAME + "/" + TITLE)]
static void Open()
{
var wnd = GetWindow<DeepDebuggerWindow>();
wnd.titleContent = new GUIContent(TITLE);
wnd.minSize = new Vector2(100f, 120f);
wnd.Show();
}
#endif
public enum Page
{
ScriptsCache,
MetaIDRegistry,
}
private Page _page;
private Vector2 pos;
private void OnGUI()
{
_page = (Page)EditorGUILayout.EnumPopup(_page);
switch (_page)
{
case Page.ScriptsCache:
DrawScriptsCache();
break;
case Page.MetaIDRegistry:
DrawMetaIDRegistry();
break;
}
}
private void DrawScriptsCache()
{
if (GUILayout.Button("Reset"))
{
ScriptsCache.Reinit();
}
var dicst = ScriptsCache.MetaIDScriptPathPairs;
pos = GUILayout.BeginScrollView(pos);
foreach (var (metaID, scriptPath) in dicst)
{
GUILayout.Label("", GUILayout.ExpandWidth(true));
Rect rect = GUILayoutUtility.GetLastRect();
var (leftRect, rightRect) = rect.HorizontalSliceLerp(0.5f);
GUI.Label(leftRect, metaID);
GUI.Label(rightRect, scriptPath);
}
GUILayout.EndScrollView();
}
private void DrawMetaIDRegistry()
{
if (GUILayout.Button("Reset"))
{
MetaIDRegistry.instance.Reinit();
}
var dicst = MetaIDRegistry.instance.TypeKeyMetaIDPairs;
pos = GUILayout.BeginScrollView(pos);
foreach (var (typeData, scriptPath) in dicst)
{
GUILayout.Label("", GUILayout.ExpandWidth(true));
Rect rect = GUILayoutUtility.GetLastRect();
var (leftRect, rightRect) = rect.HorizontalSliceLerp(0.5f);
Rect preLeftRect = default;
(preLeftRect, leftRect) = rect.HorizontalSliceLeft(18f);
GUI.Label(preLeftRect, typeData.ToType() == null ? "-" : "+");
GUI.Label(leftRect, typeData.ToString());
GUI.Label(rightRect, scriptPath);
}
GUILayout.EndScrollView();
}
}
}
#endif

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 66e2240e9dd52204daec6a089888e7be
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -42,7 +42,7 @@ namespace DCFApixels.DragonECS.Unity.Docs
{ {
foreach (var type in assembly.GetTypes()) foreach (var type in assembly.GetTypes())
{ {
if (TypeMeta.IsHasMeta(type)) if (TypeMeta.IsHasCustomMeta(type))
{ {
result.Add(type); result.Add(type);
} }

View File

@ -28,11 +28,18 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
private Pair[] _typeKeyMetaIDPairsSerializable; private Pair[] _typeKeyMetaIDPairsSerializable;
#endregion #endregion
private Dictionary<TypeData, string> _typeKeyMetaIDPairs = new Dictionary<TypeData, string>(); private Dictionary<TypeData, string> _typeKeyMetaIDPairs = new Dictionary<TypeData, string>();
internal IReadOnlyDictionary<TypeData, string> TypeKeyMetaIDPairs => _typeKeyMetaIDPairs;
private bool _isChanged = false; private bool _isChanged = false;
public bool TryGetMetaID(TypeData key, out string metaID) public bool TryGetMetaID(TypeData key, out string metaID)
{ {
return _typeKeyMetaIDPairs.TryGetValue(key, out metaID); bool result = _typeKeyMetaIDPairs.TryGetValue(key, out metaID);
if(result && string.IsNullOrEmpty(metaID))
{
result = false;
_typeKeyMetaIDPairs.Remove(key);
}
return result;
} }
@ -43,7 +50,7 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
private static void BeforeCompilation() private static void BeforeCompilation()
{ {
EditorApplication.update -= BeforeCompilation; EditorApplication.update -= BeforeCompilation;
instance.TryGetMetaID(default, out _); instance.TryGetMetaID(TypeData.Empty, out _);
instance.Update(); instance.Update();
} }
@ -55,25 +62,26 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
} }
private void Update() private void Update()
{ {
var typeMetas = UnityEditorUtility._serializableTypeWithMetaIDMetas; if (UnityEditorUtility.IsHasAnyMetaIDCollision) { return; }
var typeMetas = UnityEditorUtility._typeWithMetaIDMetas;
foreach (var meta in typeMetas) foreach (var meta in typeMetas)
{ {
var key = new TypeData(meta.Type); var typeKey = new TypeData(meta.Type);
var metaID = meta.MetaID; var metaID = meta.MetaID;
//Debug.LogWarning(type + " " + metaID); //Debug.LogWarning(type + " " + metaID);
if (_typeKeyMetaIDPairs.TryGetValue(key, out string keyMetaID)) if (_typeKeyMetaIDPairs.TryGetValue(typeKey, out string storedMetaID))
{ {
if (keyMetaID != metaID) if (storedMetaID != metaID)
{ {
_typeKeyMetaIDPairs[key] = null; //Таким образом помечаются моменты когда не однозначно какой идентификатор принадлежит этому имени _typeKeyMetaIDPairs[typeKey] = string.Empty; //Таким образом помечаются моменты когда не однозначно какой идентификатор принадлежит этому имени
_isChanged = true; _isChanged = true;
} }
} }
else else
{ {
_typeKeyMetaIDPairs[key] = metaID; _typeKeyMetaIDPairs[typeKey] = metaID;
_isChanged = true; _isChanged = true;
} }
} }
@ -92,10 +100,9 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
_typeKeyMetaIDPairs.Clear(); _typeKeyMetaIDPairs.Clear();
foreach (var pair in _typeKeyMetaIDPairsSerializable) foreach (var pair in _typeKeyMetaIDPairsSerializable)
{ {
if (string.IsNullOrEmpty(pair.value) == false) if (string.IsNullOrEmpty(pair.value) || pair.key.IsEmpty) { continue; }
{
_typeKeyMetaIDPairs[pair.key] = pair.value; _typeKeyMetaIDPairs[pair.key] = pair.value;
}
} }
} }
void ISerializationCallbackReceiver.OnBeforeSerialize() void ISerializationCallbackReceiver.OnBeforeSerialize()

View File

@ -65,6 +65,8 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
{ {
if (GUI.Button(rect, "")) if (GUI.Button(rect, ""))
{ {
GUIUtility.hotControl = -1;
GUIUtility.keyboardControl = -1;
_selectedMissingsResolvingData = _cachedMissingsResolvingDatas[index]; _selectedMissingsResolvingData = _cachedMissingsResolvingDatas[index];
} }
} }

View File

@ -1,7 +1,6 @@
#if UNITY_EDITOR #if UNITY_EDITOR
using DCFApixels.DragonECS.Unity.RefRepairer.Internal; using DCFApixels.DragonECS.Unity.RefRepairer.Internal;
using System; using System;
using System.Reflection;
namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
{ {
@ -9,8 +8,13 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
{ {
public readonly TypeData OldTypeData; public readonly TypeData OldTypeData;
public readonly string OldSerializedInfoLine; public readonly string OldSerializedInfoLine;
private TypeData _newTypeData; private TypeData _newTypeData;
private string _newSerializedInfoLine; private string _newSerializedInfoLine;
private Type _chachedNewType = null;
private bool _chachedNewTypeInited = false;
public MissingsResolvingData(TypeData oldTypeData) public MissingsResolvingData(TypeData oldTypeData)
{ {
OldTypeData = oldTypeData; OldTypeData = oldTypeData;
@ -18,13 +22,7 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
} }
public bool IsResolved public bool IsResolved
{ {
get get { return FindNewType() != null; }
{
//return
// string.IsNullOrEmpty(_newTypeData.ClassName) == false &&
// string.IsNullOrEmpty(_newTypeData.AssemblyName) == false;
return FindNewType() != null;
}
} }
public bool IsEmpty public bool IsEmpty
{ {
@ -35,34 +33,6 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
string.IsNullOrEmpty(_newTypeData.AssemblyName); string.IsNullOrEmpty(_newTypeData.AssemblyName);
} }
} }
private Type _chachedNewType = null;
private bool _chachedNewTypeInited = false;
public Type FindNewType()
{
if (_chachedNewTypeInited == false)
{
if (string.IsNullOrEmpty(_newTypeData.AssemblyName) == false)
{
Assembly assembly = null;
try
{
assembly = Assembly.Load(_newTypeData.AssemblyName);
}
catch { }
if (assembly == null)
{
_chachedNewType = null;
}
else
{
string fullTypeName = $"{_newTypeData.NamespaceName}.{_newTypeData.ClassName}";
_chachedNewType = assembly.GetType(fullTypeName);
}
_chachedNewTypeInited = true;
}
}
return _chachedNewType;
}
public TypeData NewTypeData public TypeData NewTypeData
{ {
get { return _newTypeData; } get { return _newTypeData; }
@ -85,6 +55,15 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
return _newSerializedInfoLine; return _newSerializedInfoLine;
} }
} }
public Type FindNewType()
{
if (_chachedNewTypeInited == false)
{
_chachedNewType = _newTypeData.ToType();
}
return _chachedNewType;
}
} }
} }
#endif #endif

View File

@ -1,5 +1,6 @@
#if UNITY_EDITOR #if UNITY_EDITOR
using System; using System;
using System.Reflection;
using System.Text; using System.Text;
using UnityEditor; using UnityEditor;
@ -11,6 +12,7 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Internal
public string ClassName; public string ClassName;
public string NamespaceName; public string NamespaceName;
public string AssemblyName; public string AssemblyName;
public bool IsEmpty { get { return string.IsNullOrWhiteSpace(ClassName); } }
public TypeDataSerializable(string typeName, string namespaceName, string assemblyName) public TypeDataSerializable(string typeName, string namespaceName, string assemblyName)
{ {
ClassName = typeName; ClassName = typeName;
@ -19,17 +21,19 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Internal
} }
public static implicit operator TypeDataSerializable(TypeData type) { return new TypeDataSerializable(type.ClassName, type.NamespaceName, type.AssemblyName); } public static implicit operator TypeDataSerializable(TypeData type) { return new TypeDataSerializable(type.ClassName, type.NamespaceName, type.AssemblyName); }
public static implicit operator TypeData(TypeDataSerializable type) { return new TypeData(type.ClassName, type.NamespaceName, type.AssemblyName); } public static implicit operator TypeData(TypeDataSerializable type) { return new TypeData(type.ClassName, type.NamespaceName, type.AssemblyName); }
public override string ToString() { return $"{{{AssemblyName}, {NamespaceName}, {ClassName}}}"; }
} }
internal readonly struct TypeData : IEquatable<TypeData> internal readonly struct TypeData : IEquatable<TypeData>
{ {
public static readonly TypeData Empty = new TypeData(string.Empty, string.Empty, string.Empty);
public readonly string ClassName; public readonly string ClassName;
public readonly string NamespaceName; public readonly string NamespaceName;
public readonly string AssemblyName; public readonly string AssemblyName;
public TypeData(ManagedReferenceMissingType managedReferenceMissingType) public TypeData(ManagedReferenceMissingType managedReferenceMissingType)
{ {
ClassName = managedReferenceMissingType.className; ClassName = managedReferenceMissingType.className ?? string.Empty;
NamespaceName = managedReferenceMissingType.namespaceName; NamespaceName = managedReferenceMissingType.namespaceName ?? string.Empty;
AssemblyName = managedReferenceMissingType.assemblyName; AssemblyName = managedReferenceMissingType.assemblyName ?? string.Empty;
} }
public TypeData(string typeName, string namespaceName, string assemblyName) public TypeData(string typeName, string namespaceName, string assemblyName)
{ {
@ -37,12 +41,12 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Internal
NamespaceName = namespaceName; NamespaceName = namespaceName;
AssemblyName = assemblyName; AssemblyName = assemblyName;
} }
public bool IsEmpty { get { return string.IsNullOrWhiteSpace(ClassName); } }
[ThreadStatic] [ThreadStatic]
private static StringBuilder sb; private static StringBuilder sb;
public TypeData(Type type) public TypeData(Type type)
{ {
string name = null; string name = string.Empty;
if (type.DeclaringType == null) if (type.DeclaringType == null)
{ {
name = type.Name; name = type.Name;
@ -65,7 +69,7 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Internal
} }
ClassName = name; ClassName = name;
NamespaceName = type.Namespace; NamespaceName = type.Namespace ?? string.Empty;
AssemblyName = type.Assembly.GetName().Name; AssemblyName = type.Assembly.GetName().Name;
} }
public bool Equals(TypeData other) public bool Equals(TypeData other)
@ -74,13 +78,48 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Internal
NamespaceName == other.NamespaceName && NamespaceName == other.NamespaceName &&
AssemblyName == other.AssemblyName; AssemblyName == other.AssemblyName;
} }
public override bool Equals(object obj) public override bool Equals(object obj) { return Equals((TypeData)obj); }
public override int GetHashCode()
{ {
return Equals((TypeData)obj); int hash1 = ClassName.GetHashCode();
int hash2 = NamespaceName.GetHashCode();
int hash3 = AssemblyName.GetHashCode();
return hash1 ^ hash2 ^ hash3;
} }
public override int GetHashCode() public override string ToString() { return $"{{{AssemblyName}, {NamespaceName}, {ClassName}}}"; }
}
internal static class TypeDataExtensions
{
public static Type ToType(this TypeData sefl)
{ {
return HashCode.Combine(ClassName, NamespaceName, AssemblyName); return ToType(sefl.AssemblyName, sefl.NamespaceName, sefl.ClassName);
}
public static Type ToType(this TypeDataSerializable sefl)
{
return ToType(sefl.AssemblyName, sefl.NamespaceName, sefl.ClassName);
}
private static Type ToType(string AssemblyName, string NamespaceName, string ClassName)
{
Type result = null;
if (string.IsNullOrEmpty(AssemblyName) == false)
{
Assembly assembly = null;
try
{
assembly = Assembly.Load(AssemblyName);
}
catch { }
if (assembly == null)
{
result = null;
}
else
{
string fullTypeName = $"{NamespaceName}.{ClassName}";
result = assembly.GetType(fullTypeName);
}
}
return result;
} }
} }
} }