Repository: FlaxEngine/FlaxEngine
File: Source/Engine/Level/SceneObjectsFactory.cpp (C++)

Code before:
        // Apply the current prefab instance objects ids table to resolve references inside a prefab properly
        context.CurrentInstance = instanceIndex;
        auto& instance = context.Instances[instanceIndex];
        for (auto& e : instance.IdsMapping)
            context.Modifier->IdsMapping[e.Key] = e.Value;
    }

    // Load data
    obj->Deserialize(stream, context.Modifier);
}

void SceneObjectsFactory::HandleObjectDeserializationError(const ISerializable::DeserializeStream& value)
{
    // Print invalid object data contents
    rapidjson_flax::StringBuffer buffer;
    PrettyJsonWriter writer(buffer);
    value.Accept(writer.GetWriter());
    LOG(Warning, "Failed to deserialize scene object from data: {0}", String(buffer.GetString()));

    // Try to log some useful info about missing object (eg. it's parent name for faster fixing)
    const auto parentIdMember = value.FindMember("ParentID");
    if (parentIdMember != value.MemberEnd() && parentIdMember->value.IsString())
    {
        const Guid parentId = JsonTools::GetGuid(parentIdMember->value);
        Actor* parent = Scripting::FindObject<Actor>(parentId);
        DummyScript* dummyScript = parent->AddScript<DummyScript>();
        dummyScript->Data = String(buffer.GetString());
        if (parent)
        {
            LOG(Warning, "Parent actor of the missing object: {0}", parent->GetName());
        }
    }
}

Actor* SceneObjectsFactory::CreateActor(int32 typeId, const Guid& id)
{
    // [Deprecated: 18.07.2019 expires 18.07.2020]

    // Convert deprecated typeId into actor type name
    StringAnsiView typeName;
    switch (typeId)
    {
#define CASE(type, typeId) case typeId: typeName = type; break;
    CASE("FlaxEngine.StaticModel", 1);
    CASE("FlaxEngine.Camera", 2);
    CASE("FlaxEngine.EmptyActor", 3);
    CASE("FlaxEngine.DirectionalLight", 4);
    CASE("FlaxEngine.PointLight", 5);
    CASE("FlaxEngine.Skybox", 6);
    CASE("FlaxEngine.EnvironmentProbe", 7);
    CASE("FlaxEngine.BoxBrush", 8);

Review comment (suggestion):
Check if `parent ` is valid as it might be `null`.

Code after:
        // Apply the current prefab instance objects ids table to resolve references inside a prefab properly
        context.CurrentInstance = instanceIndex;
        auto& instance = context.Instances[instanceIndex];
        for (auto& e : instance.IdsMapping)
            context.Modifier->IdsMapping[e.Key] = e.Value;
    }

    // Load data
    obj->Deserialize(stream, context.Modifier);
}

void SceneObjectsFactory::HandleObjectDeserializationError(const ISerializable::DeserializeStream& value)
{
    // Print invalid object data contents
    rapidjson_flax::StringBuffer buffer;
    PrettyJsonWriter writer(buffer);
    value.Accept(writer.GetWriter());
    LOG(Warning, "Failed to deserialize scene object from data: {0}", String(buffer.GetString()));

    // Try to log some useful info about missing object (eg. it's parent name for faster fixing)
    const auto parentIdMember = value.FindMember("ParentID");
    if (parentIdMember != value.MemberEnd() && parentIdMember->value.IsString())
    {
        const Guid parentId = JsonTools::GetGuid(parentIdMember->value);
        Actor* parent = Scripting::FindObject<Actor>(parentId);
        if (parent)
        {
            MissingScript* dummyScript = parent->AddScript<MissingScript>();

            const auto parentIdMember = value.FindMember("TypeName");
            dummyScript->MissingTypeName = parentIdMember->value.GetString();
            dummyScript->Data = String(buffer.GetString());
            
            LOG(Warning, "Parent actor of the missing object: {0}", parent->GetName());
        }
    }
}

Actor* SceneObjectsFactory::CreateActor(int32 typeId, const Guid& id)
{
    // [Deprecated: 18.07.2019 expires 18.07.2020]

    // Convert deprecated typeId into actor type name
    StringAnsiView typeName;
    switch (typeId)
    {
#define CASE(type, typeId) case typeId: typeName = type; break;
    CASE("FlaxEngine.StaticModel", 1);
    CASE("FlaxEngine.Camera", 2);
    CASE("FlaxEngine.EmptyActor", 3);
    CASE("FlaxEngine.DirectionalLight", 4);