unsafe drag drop test
- unsafe because of entity reference - unsafe because of unsafe code lol - fixes in parent/child system
This commit is contained in:
		@@ -1,4 +1,4 @@
 | 
			
		||||
namespace Nerfed.Editor.Components;
 | 
			
		||||
 | 
			
		||||
public readonly record struct SelectedInHierachy;
 | 
			
		||||
public readonly record struct ClickedInHierarchy;
 | 
			
		||||
public readonly record struct ClickedInHierachy;
 | 
			
		||||
@@ -9,6 +9,7 @@
 | 
			
		||||
        <IsPackable>false</IsPackable>
 | 
			
		||||
        <Configurations>Debug;Test;Release</Configurations>
 | 
			
		||||
        <Platforms>x64</Platforms>
 | 
			
		||||
        <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
 | 
			
		||||
    </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
 | 
			
		||||
 
 | 
			
		||||
@@ -31,6 +31,7 @@ internal class Program
 | 
			
		||||
        editorSystems.Add(new EditorHierarchyWindow(world));
 | 
			
		||||
 | 
			
		||||
        Entity ent1 = world.CreateEntity("parent");
 | 
			
		||||
        world.Set(ent1, new Root());
 | 
			
		||||
        world.Set(ent1, new LocalTransform(new Vector3(1, 0, 0), Quaternion.Identity, Vector3.One));
 | 
			
		||||
 | 
			
		||||
        Entity ent2 = world.CreateEntity("child");
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,9 @@
 | 
			
		||||
using ImGuiNET;
 | 
			
		||||
using MoonTools.ECS;
 | 
			
		||||
using Nerfed.Editor.Components;
 | 
			
		||||
using Nerfed.Runtime;
 | 
			
		||||
using Nerfed.Runtime.Components;
 | 
			
		||||
using Nerfed.Runtime.Util;
 | 
			
		||||
 | 
			
		||||
namespace Nerfed.Editor.Systems
 | 
			
		||||
{
 | 
			
		||||
@@ -10,7 +12,7 @@ namespace Nerfed.Editor.Systems
 | 
			
		||||
    {
 | 
			
		||||
        private const ImGuiTreeNodeFlags baseFlags = ImGuiTreeNodeFlags.OpenOnArrow | ImGuiTreeNodeFlags.OpenOnDoubleClick | ImGuiTreeNodeFlags.SpanAvailWidth;
 | 
			
		||||
 | 
			
		||||
        private readonly Filter rootEntitiesWithTransformFilter;
 | 
			
		||||
        //private readonly Filter rootEntitiesWithTransformFilter;
 | 
			
		||||
        //private readonly Filter rootEntitiesFilterBroken;
 | 
			
		||||
        private readonly Filter rootEntitiesFilter;
 | 
			
		||||
 | 
			
		||||
@@ -18,7 +20,7 @@ namespace Nerfed.Editor.Systems
 | 
			
		||||
 | 
			
		||||
        public EditorHierarchyWindow(World world) : base(world)
 | 
			
		||||
        {
 | 
			
		||||
            rootEntitiesWithTransformFilter = FilterBuilder.Include<LocalTransform>().Exclude<Child>().Build();
 | 
			
		||||
            //rootEntitiesWithTransformFilter = FilterBuilder.Include<LocalTransform>().Exclude<Child>().Build();
 | 
			
		||||
 | 
			
		||||
            // TODO: this doesn't work.
 | 
			
		||||
            //rootEntitiesFilterBroken = FilterBuilder.Exclude<Child>().Build();
 | 
			
		||||
@@ -42,10 +44,28 @@ namespace Nerfed.Editor.Systems
 | 
			
		||||
 | 
			
		||||
            if (ImGui.TreeNodeEx("World", flags))
 | 
			
		||||
            {
 | 
			
		||||
                foreach (Entity entity in rootEntitiesWithTransformFilter.Entities)
 | 
			
		||||
                if (ImGui.BeginDragDropTarget())
 | 
			
		||||
                {
 | 
			
		||||
                    DrawEntityAndChildren(entity);
 | 
			
		||||
                    unsafe
 | 
			
		||||
                    {
 | 
			
		||||
                        ImGuiPayloadPtr payload = ImGui.AcceptDragDropPayload($"{nameof(EditorHierarchyWindow)}");
 | 
			
		||||
                        if (payload.NativePtr != null)
 | 
			
		||||
                        {
 | 
			
		||||
                            Entity* data = (Entity*)payload.Data;
 | 
			
		||||
                            Entity child = data[0];
 | 
			
		||||
 | 
			
		||||
                            Log.Info($"Dropped {child.ID}");
 | 
			
		||||
 | 
			
		||||
                            Transform.RemoveParent(World, child);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    ImGui.EndDragDropTarget();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                //foreach (Entity entity in rootEntitiesWithTransformFilter.Entities)
 | 
			
		||||
                //{
 | 
			
		||||
                //    DrawEntityAndChildren(entity);
 | 
			
		||||
                //}
 | 
			
		||||
 | 
			
		||||
                foreach (Entity entity in rootEntitiesFilter.Entities)
 | 
			
		||||
                {
 | 
			
		||||
@@ -76,9 +96,41 @@ namespace Nerfed.Editor.Systems
 | 
			
		||||
 | 
			
		||||
            if (ImGui.TreeNodeEx($"{entity.ID} | {GetTag(entity)}", flags))
 | 
			
		||||
            {
 | 
			
		||||
                // Selection.
 | 
			
		||||
                if (ImGui.IsItemClicked() && !ImGui.IsItemToggledOpen())
 | 
			
		||||
                {
 | 
			
		||||
                    World.Set(entity, new ClickedInHierarchy());
 | 
			
		||||
                    World.Set(entity, new ClickedInHierachy());
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Drag and drop.
 | 
			
		||||
                if (ImGui.BeginDragDropSource())
 | 
			
		||||
                {
 | 
			
		||||
                    unsafe
 | 
			
		||||
                    {
 | 
			
		||||
                        fixed (Entity* payload = &entity)
 | 
			
		||||
                        {
 | 
			
		||||
                            ImGui.SetDragDropPayload($"{nameof(EditorHierarchyWindow)}", (IntPtr)payload, (uint)sizeof(Entity));
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    ImGui.EndDragDropSource();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (ImGui.BeginDragDropTarget())
 | 
			
		||||
                {
 | 
			
		||||
                    unsafe
 | 
			
		||||
                    {
 | 
			
		||||
                        ImGuiPayloadPtr payload = ImGui.AcceptDragDropPayload($"{nameof(EditorHierarchyWindow)}");
 | 
			
		||||
                        if (payload.NativePtr != null)
 | 
			
		||||
                        {
 | 
			
		||||
                            Entity* data = (Entity*)payload.Data;
 | 
			
		||||
                            Entity ent = data[0];
 | 
			
		||||
 | 
			
		||||
                            Log.Info($"Dropped {ent.ID}");
 | 
			
		||||
 | 
			
		||||
                            Transform.SetParent(World, ent, entity);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    ImGui.EndDragDropTarget();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                ReverseSpanEnumerator<Entity> childEntities = World.InRelations<ChildParentRelation>(entity);
 | 
			
		||||
@@ -100,7 +152,7 @@ namespace Nerfed.Editor.Systems
 | 
			
		||||
            public EditorHierachySelectionSystem(World world) : base(world)
 | 
			
		||||
            {
 | 
			
		||||
                selectedEntities = FilterBuilder.Include<SelectedInHierachy>().Build();
 | 
			
		||||
                clickedEntities = FilterBuilder.Include<ClickedInHierarchy>().Build();
 | 
			
		||||
                clickedEntities = FilterBuilder.Include<ClickedInHierachy>().Build();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public override void Update(TimeSpan delta)
 | 
			
		||||
@@ -128,8 +180,20 @@ namespace Nerfed.Editor.Systems
 | 
			
		||||
                        Set(entity, new SelectedInHierachy());
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    Remove<ClickedInHierarchy>(entity);
 | 
			
		||||
                }
 | 
			
		||||
                    Remove<ClickedInHierachy>(entity);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private class EditorHierachyDragAndDropSystem : MoonTools.ECS.System
 | 
			
		||||
        {
 | 
			
		||||
            public EditorHierachyDragAndDropSystem(World world) : base(world)
 | 
			
		||||
            {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public override void Update(TimeSpan delta)
 | 
			
		||||
            {
 | 
			
		||||
                
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -45,7 +45,7 @@ namespace Nerfed.Runtime.Systems
 | 
			
		||||
                LocalToWorld localToWorld = new(localToWorldMatrix);
 | 
			
		||||
                Set(entity, localToWorld);
 | 
			
		||||
 | 
			
		||||
                Log.Info($"Entity {entity} | local position {localTransform.position} | world position {localToWorldMatrix.Translation}");
 | 
			
		||||
                //Log.Info($"Entity {entity} | local position {localTransform.position} | world position {localToWorldMatrix.Translation}");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            ReverseSpanEnumerator<Entity> childEntities = World.OutRelations<ChildParentRelation>(entity);
 | 
			
		||||
 
 | 
			
		||||
@@ -28,10 +28,7 @@ namespace Nerfed.Runtime.Util
 | 
			
		||||
        // Relation goes from child to parent.
 | 
			
		||||
        public static void SetParent(in World world, in Entity child, in Entity parent)
 | 
			
		||||
        {
 | 
			
		||||
            if (world.Related<ChildParentRelation>(parent, child))
 | 
			
		||||
            {
 | 
			
		||||
                RemoveParent(world, parent);
 | 
			
		||||
            }
 | 
			
		||||
            RemoveParent(world, child);
 | 
			
		||||
 | 
			
		||||
            world.Relate(child, parent, new ChildParentRelation());
 | 
			
		||||
            world.Set(child, new Child());
 | 
			
		||||
@@ -47,8 +44,10 @@ namespace Nerfed.Runtime.Util
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Entity parent = world.OutRelationSingleton<ChildParentRelation>(child);
 | 
			
		||||
 | 
			
		||||
            // TODO: Check if Unrelate all also unrelates incomming relations..?
 | 
			
		||||
            world.UnrelateAll<ChildParentRelation>(child);
 | 
			
		||||
            world.Unrelate<ChildParentRelation>(child, parent);
 | 
			
		||||
            world.Remove<Child>(child);
 | 
			
		||||
            world.Set(child, new Root());
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user