Implemented Entity and Component Drop-Targets and added Name property for entities

- Also fixed non generic GetComponent
- Use UUID as Drag-Drop value for entities
- Removed unused methods from ComponentEditWindow
- Started a marginally type-safe version of ImGui.Payload
This commit is contained in:
Simon Lübeß
2023-12-26 02:00:44 +01:00
parent 4fa6384544
commit a4c311c2e4
9 changed files with 255 additions and 184 deletions
@@ -568,174 +568,6 @@ namespace GlitchyEditor.EditWindows
ScriptEngine.ShowScriptEditor(entity, scriptComponent);
}
private static Entity? ShowEntitySelector()
{
static char8[128] entitySearch = .();
Entity? result = null;
if (ImGui.BeginPopup("ENTITY_SELECTOR"))
{
ImGui.TextUnformatted("Search:");
ImGui.SameLine();
if (ImGui.InputText("##entitySearcher", &entitySearch, (uint64)entitySearch.Count))
{
}
ImGui.EndPopup();
}
return result;
}
private static void ShowEntityReceiver(ScriptFieldInstance* field, StringView fieldName, ScriptClass scriptClass)
{
var entityId = field.GetData<UUID>();
Result<Entity> fieldEntity = Editor.Instance.CurrentScene.GetEntityByID(entityId);
String entityName = scope .(32);
if (entityId == UUID(0))
entityName.Set("None");
else if (fieldEntity case .Ok(Entity e))
entityName.Set(e.Name);
else
entityName..Clear().AppendF($"Missing entity ({entityId})");
ImGui.Text($"{fieldName}: ");
ImGui.SameLine();
if (ImGui.Button(entityName))
{
if (fieldEntity case .Ok)
Editor.Instance.EntityHierarchyWindow.HighlightEntity(fieldEntity);
}
if (ImGui.BeginDragDropTarget())
{
ImGui.Payload* peekPayload = ImGui.AcceptDragDropPayload(.Entity, .AcceptPeekOnly);
bool allowDrop = false;
if (peekPayload != null)
{
Entity draggedEntity = *(Entity*)peekPayload.Data;
ScriptClass draggedScriptClass = ScriptEngine.Classes.EntityRoot;
if (draggedEntity.TryGetComponent<ScriptComponent>(let draggedScript))
{
var draggedClassName = draggedScript.ScriptClassName;
draggedScriptClass = ScriptEngine.GetScriptClass(draggedClassName);
}
// TODO: I don't like the fact, that we are using mono directly
ScriptField scriptField = scriptClass.Fields[fieldName];
var fieldMonoClass = Mono.mono_type_get_class(scriptField.GetMonoType());
allowDrop = draggedScriptClass.[Friend]IsSubclass(fieldMonoClass);
}
if (allowDrop)
{
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.Entity);
if (payload != null)
{
Log.EngineLogger.AssertDebug(payload.DataSize == sizeof(Entity));
Entity droppedEntity = *(Entity*)payload.Data;
if (droppedEntity.IsValid)
field.SetData<UUID>(droppedEntity.UUID);
}
}
ImGui.EndDragDropTarget();
}
}
//private static Entity?
private static void ShowComponentReceiver(ScriptFieldInstance* field, StringView fieldName, ScriptClass scriptClass)
{
var entityId = field.GetData<UUID>();
Result<Entity> fieldEntity = Editor.Instance.CurrentScene.GetEntityByID(entityId);
String entityName = scope .(32);
if (entityId == UUID(0))
entityName.Set("None");
else if (fieldEntity case .Ok(Entity e))
entityName.Set(e.Name);
else
entityName..Clear().AppendF($"Missing reference ({entityId})");
ImGui.Text($"{fieldName}: ");
ImGui.SameLine();
if (ImGui.Button(entityName))
{
if (fieldEntity case .Ok)
Editor.Instance.EntityHierarchyWindow.HighlightEntity(fieldEntity);
}
if (ImGui.BeginDragDropTarget())
{
ImGui.Payload* peekPayload = ImGui.AcceptDragDropPayload(.Entity, .AcceptPeekOnly);
bool allowDrop = false;
if (peekPayload != null)
{
Entity draggedEntity = *(Entity*)peekPayload.Data;
// TODO: I don't like the fact, that we are using mono directly
ScriptField scriptField = scriptClass.Fields[fieldName];
// For some reason we have to retrieve the MonoType like this. Using scriptField.GetMonoType() directly returns the wrong type...
MonoReflectionType* reflectionType = Mono.mono_type_get_object(ScriptEngine.[Friend]s_AppDomain, scriptField.GetMonoType());
MonoType* actualMonoType = Mono.mono_reflection_type_get_type(reflectionType);
// TODO: We shouldn't abuse the script glue like that.
// ScriptGlue should only be called by C#, not by Beef.
if (ScriptGlue.[Friend]s_HasComponentMethods.TryGetValue(actualMonoType, let has_component))
{
allowDrop = has_component(draggedEntity);
}
else
{
Log.EngineLogger.Warning($"No HasComponent-Function found for field {scriptField.Name}");
allowDrop = false;
}
}
if (allowDrop)
{
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.Entity);
if (payload != null)
{
Log.EngineLogger.AssertDebug(payload.DataSize == sizeof(Entity));
Entity droppedEntity = *(Entity*)payload.Data;
if (droppedEntity.IsValid)
field.SetData<UUID>(droppedEntity.UUID);
}
}
ImGui.EndDragDropTarget();
}
}
private static void LabelColumn(StringView label)
{
ImGui.TextUnformatted(label);
@@ -415,7 +415,8 @@ namespace GlitchyEditor.EditWindows
{
isDragged = true;
ImGui.SetDragDropPayload(.Entity, &tree.Value, sizeof(Entity));
UUID id = tree.Value.UUID;
ImGui.SetDragDropPayload(.Entity, &id, sizeof(UUID));
ImGui.Text(name);
@@ -464,13 +465,13 @@ namespace GlitchyEditor.EditWindows
{
if(ImGui.BeginDragDropTarget())
{
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.Entity);
Payload<UUID>? payload = ImGui.AcceptDragDropPayload<UUID>(.Entity);
if(payload != null)
{
Log.ClientLogger.AssertDebug(payload.DataSize == sizeof(Entity));
UUID movedEntityId = payload->Data;
Entity movedEntity = *(Entity*)payload.Data;
Entity movedEntity = _editor.CurrentScene.GetEntityByID(movedEntityId);
bool dropLegal = true;
@@ -556,13 +557,13 @@ namespace GlitchyEditor.EditWindows
{
if(ImGui.BeginDragDropTarget())
{
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.Entity);
Payload<UUID>? payload = ImGui.AcceptDragDropPayload<UUID>(.Entity);
if(payload != null)
{
Log.ClientLogger.AssertDebug(payload.DataSize == sizeof(Entity));
Entity movedEntity = *(Entity*)payload.Data;
UUID movedEntityId = payload->Data;
Entity movedEntity = _editor.CurrentScene.GetEntityByID(movedEntityId);
// Also mark transform as dirty
var transformComponent = movedEntity.GetComponent<TransformComponent>();