mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Fixed Script data for entity copying
This commit is contained in:
@@ -859,11 +859,17 @@ static class ScriptEngine
|
|||||||
|
|
||||||
for (let (id, script) in _entityScriptInstances)
|
for (let (id, script) in _entityScriptInstances)
|
||||||
{
|
{
|
||||||
SerializedObject object = new SerializedObject(allObjects, script.ScriptClass.FullName, script.EntityId);
|
SerializeScriptInstance(script, allObjects);
|
||||||
object.Serialize(script);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Serializes the given script instance
|
||||||
|
public static void SerializeScriptInstance(ScriptInstance script, Dictionary<UUID, SerializedObject> allObjects)
|
||||||
|
{
|
||||||
|
SerializedObject object = new SerializedObject(allObjects, script.ScriptClass.FullName, script.EntityId);
|
||||||
|
object.Serialize(script);
|
||||||
|
}
|
||||||
|
|
||||||
/// Deserializes the given data into the script instances
|
/// Deserializes the given data into the script instances
|
||||||
public static void DeserializeScriptInstances(Dictionary<UUID, SerializedObject> allObjects)
|
public static void DeserializeScriptInstances(Dictionary<UUID, SerializedObject> allObjects)
|
||||||
{
|
{
|
||||||
@@ -871,9 +877,36 @@ static class ScriptEngine
|
|||||||
|
|
||||||
for (let (id, script) in _entityScriptInstances)
|
for (let (id, script) in _entityScriptInstances)
|
||||||
{
|
{
|
||||||
if (allObjects.TryGetValue(id, let object))
|
DeserializeScriptInstance(id, script, allObjects);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deserializes the given script instance.
|
||||||
|
/// @returns true if the script had serialized data; false otherwise.
|
||||||
|
public static bool DeserializeScriptInstance(UUID id, ScriptInstance script, Dictionary<UUID, SerializedObject> allObjects)
|
||||||
|
{
|
||||||
|
if (allObjects.TryGetValue(id, let object))
|
||||||
|
{
|
||||||
|
object.Deserialize(script);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Replaces Entity references in the given serialized data using the specified translation table.
|
||||||
|
public static void FixupSerializedIds(Dictionary<UUID, UUID> originalToCopyIds, Dictionary<UUID, SerializedObject> allObjects)
|
||||||
|
{
|
||||||
|
for (let (id, object) in allObjects)
|
||||||
|
{
|
||||||
|
for (var fieldData in ref object.Fields.Values)
|
||||||
{
|
{
|
||||||
object.Deserialize(script);
|
if (fieldData.PrimitiveType != .EntityReference && fieldData.PrimitiveType != .ComponentReference)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (originalToCopyIds.TryGetValue(fieldData.Data.EngineObject.ID, let copyId))
|
||||||
|
fieldData.Data.EngineObject.ID = copyId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using GlitchyEngine.Content;
|
|||||||
using GlitchyEngine.Scripting;
|
using GlitchyEngine.Scripting;
|
||||||
using GlitchyEngine.Math;
|
using GlitchyEngine.Math;
|
||||||
using GlitchyEngine.Scripting.Classes;
|
using GlitchyEngine.Scripting.Classes;
|
||||||
|
using GlitchyEngine.Serialization;
|
||||||
|
|
||||||
namespace GlitchyEngine.World
|
namespace GlitchyEngine.World
|
||||||
{
|
{
|
||||||
@@ -773,10 +774,14 @@ namespace GlitchyEngine.World
|
|||||||
*/
|
*/
|
||||||
public Entity CreateInstance(Entity entity)
|
public Entity CreateInstance(Entity entity)
|
||||||
{
|
{
|
||||||
|
Dictionary<UUID, SerializedObject> serializedData = scope .();
|
||||||
|
defer { ClearDictionaryAndDeleteValues!(serializedData); }
|
||||||
|
|
||||||
List<Entity> newEntities = scope .();
|
List<Entity> newEntities = scope .();
|
||||||
Dictionary<EcsEntity, EcsEntity> sourceToTargetEntity = scope .();
|
Dictionary<EcsEntity, EcsEntity> sourceToTargetEntity = scope .();
|
||||||
Dictionary<UUID, UUID> sourceIdToTargetId = scope .();
|
Dictionary<UUID, UUID> sourceIdToTargetId = scope .();
|
||||||
Dictionary<UUID, Entity> targetIdToSourceEntity = scope .();
|
Dictionary<UUID, Entity> targetIdToSourceEntity = scope .();
|
||||||
|
List<(UUID oldId, ScriptInstance scriptInstance)> newScripts = scope .();
|
||||||
|
|
||||||
Entity CopyEntityAndChildren(Entity original, Entity? copyParent)
|
Entity CopyEntityAndChildren(Entity original, Entity? copyParent)
|
||||||
{
|
{
|
||||||
@@ -801,7 +806,7 @@ namespace GlitchyEngine.World
|
|||||||
CopyComponent<BoxCollider2DComponent>(original, copy);
|
CopyComponent<BoxCollider2DComponent>(original, copy);
|
||||||
CopyComponent<CircleCollider2DComponent>(original, copy);
|
CopyComponent<CircleCollider2DComponent>(original, copy);
|
||||||
CopyComponent<PolygonCollider2DComponent>(original, copy);
|
CopyComponent<PolygonCollider2DComponent>(original, copy);
|
||||||
|
|
||||||
// Copy ScriptComponent... needs extra handling for the script instances
|
// Copy ScriptComponent... needs extra handling for the script instances
|
||||||
if (original.TryGetComponent<ScriptComponent>(let sourceScript))
|
if (original.TryGetComponent<ScriptComponent>(let sourceScript))
|
||||||
{
|
{
|
||||||
@@ -809,15 +814,16 @@ namespace GlitchyEngine.World
|
|||||||
|
|
||||||
targetScript.ScriptClassName = sourceScript.ScriptClassName;
|
targetScript.ScriptClassName = sourceScript.ScriptClassName;
|
||||||
|
|
||||||
// Initializes the created instance
|
if (sourceScript.Instance != null)
|
||||||
// TODO: this returns false, if no script with ScriptClassName exists, we have to handle this case correctly I think.
|
{
|
||||||
ScriptEngine.InitializeInstance(copy, targetScript);
|
ScriptEngine.SerializeScriptInstance(sourceScript.Instance, serializedData);
|
||||||
|
|
||||||
// TODO: Copy Data from one instance to another
|
// Initializes the created instance
|
||||||
//ScriptEngine.CopyFieldsToInstance(targetScript, sourceScript);
|
// TODO: this returns false, if no script with ScriptClassName exists, we have to handle this case correctly I think.
|
||||||
|
ScriptEngine.InitializeInstance(copy, targetScript);
|
||||||
// TODO: Only if we are in Runtime
|
|
||||||
targetScript.Instance.InvokeOnCreate();
|
newScripts.Add((original.UUID, targetScript.Instance));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is kinda slow because it's in O(n*m) where n is the tree depth and m is the total number of entities in the scene...
|
// This is kinda slow because it's in O(n*m) where n is the tree depth and m is the total number of entities in the scene...
|
||||||
@@ -830,22 +836,22 @@ namespace GlitchyEngine.World
|
|||||||
}
|
}
|
||||||
|
|
||||||
Entity newEntity = CopyEntityAndChildren(entity, null);
|
Entity newEntity = CopyEntityAndChildren(entity, null);
|
||||||
|
|
||||||
for (let copy in newEntities)
|
// Replace old IDs with new ones
|
||||||
|
ScriptEngine.FixupSerializedIds(sourceIdToTargetId, serializedData);
|
||||||
|
|
||||||
|
// Use separate loops for deserialization and OnCreate to ensure complete entities and references in OnCreate
|
||||||
|
|
||||||
|
for (let (originalId, newScriptInstance) in newScripts)
|
||||||
{
|
{
|
||||||
if (copy.TryGetComponent<ScriptComponent>(let targetScript))
|
ScriptEngine.DeserializeScriptInstance(originalId, newScriptInstance, serializedData);
|
||||||
{
|
|
||||||
Entity originalEntity = targetIdToSourceEntity[copy.UUID];
|
|
||||||
|
|
||||||
if (!originalEntity.TryGetComponent<ScriptComponent>(let sourceScript))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ScriptEngine.CopyFieldsToInstance(targetScript, sourceScript, sourceIdToTargetId);
|
|
||||||
|
|
||||||
//targetScript.Instance.InvokeOnCreate();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (let (_, newScriptInstance) in newScripts)
|
||||||
|
{
|
||||||
|
if (ScriptEngine.ApplicationInfo.IsInPlayMode || newScriptInstance.ScriptClass.RunInEditMode)
|
||||||
|
newScriptInstance.InvokeOnCreate();
|
||||||
|
}
|
||||||
|
|
||||||
return newEntity;
|
return newEntity;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -504,7 +504,7 @@ public class DeserializationObject
|
|||||||
|
|
||||||
public unsafe object? DeserializeClass(string fieldName, Type fieldType)
|
public unsafe object? DeserializeClass(string fieldName, Type fieldType)
|
||||||
{
|
{
|
||||||
if (fieldType.GetGenericTypeDefinition() == typeof(List<>))
|
if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(List<>))
|
||||||
{
|
{
|
||||||
return DeserializeList(fieldName, fieldType, fieldType.GetGenericArguments()[0]);
|
return DeserializeList(fieldName, fieldType, fieldType.GetGenericArguments()[0]);
|
||||||
}
|
}
|
||||||
@@ -514,7 +514,10 @@ public class DeserializationObject
|
|||||||
|
|
||||||
if (isEntity || isComponent)
|
if (isEntity || isComponent)
|
||||||
{
|
{
|
||||||
var data = (DataHelper.EngineObjectReferenceHelper)GetFieldValue(fieldName, isEntity ? SerializationType.EntityReference : SerializationType.ComponentReference);
|
object? fieldData = GetFieldValue(fieldName, isEntity ? SerializationType.EntityReference : SerializationType.ComponentReference);
|
||||||
|
|
||||||
|
if (fieldData is not DataHelper.EngineObjectReferenceHelper data)
|
||||||
|
return NoValueDeserialized;
|
||||||
|
|
||||||
UUID id = data.Id;
|
UUID id = data.Id;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user