From 9a0df077b33d23f7a32ade93a57a2da54c9bd8e4 Mon Sep 17 00:00:00 2001 From: Florian Rival Date: Thu, 16 Jan 2025 23:27:32 +0100 Subject: [PATCH] Fix a crash when opening a project missing a custom object that was loaded in the previously opened project (#7317) --- .../Extensions/Metadata/ObjectMetadata.cpp | 31 ++++++++----------- .../Extensions/Metadata/ObjectMetadata.h | 15 ++++++--- Core/GDCore/Extensions/Platform.cpp | 14 ++++++--- newIDE/app/src/MainFrame/index.js | 2 +- 4 files changed, 33 insertions(+), 29 deletions(-) diff --git a/Core/GDCore/Extensions/Metadata/ObjectMetadata.cpp b/Core/GDCore/Extensions/Metadata/ObjectMetadata.cpp index 2e48ce6a2883..3650045560bb 100644 --- a/Core/GDCore/Extensions/Metadata/ObjectMetadata.cpp +++ b/Core/GDCore/Extensions/Metadata/ObjectMetadata.cpp @@ -46,30 +46,25 @@ ObjectMetadata::ObjectMetadata(const gd::String& extensionNamespace_, const gd::String& fullname_, const gd::String& description_, const gd::String& icon24x24) - : ObjectMetadata(extensionNamespace_, - name_, - fullname_, - description_, - icon24x24, - []() -> std::unique_ptr { - gd::LogFatalError( - "Error: Event-based objects don't have blueprint. " - "This method should never be called."); - return nullptr; - }) {} + : name(name_), + iconFilename(icon24x24), + extensionNamespace(extensionNamespace_) { + SetFullName(gd::String(fullname_)); + SetDescription(gd::String(description_)); +} ObjectMetadata::ObjectMetadata(const gd::String& extensionNamespace_, const gd::String& name_, const gd::String& fullname_, const gd::String& description_, const gd::String& icon24x24, - CreateFunPtr createFunPtrP) - : name(name_), - iconFilename(icon24x24), - createFunPtr(createFunPtrP), - extensionNamespace(extensionNamespace_) { - SetFullName(gd::String(fullname_)); - SetDescription(gd::String(description_)); + CreateFunPtr createFunPtr_) + : ObjectMetadata(extensionNamespace_, + name_, + fullname_, + description_, + icon24x24) { + createFunPtr = createFunPtr_; } gd::InstructionMetadata& ObjectMetadata::AddCondition( diff --git a/Core/GDCore/Extensions/Metadata/ObjectMetadata.h b/Core/GDCore/Extensions/Metadata/ObjectMetadata.h index 6e60f9f3d678..cb06ff47c93c 100644 --- a/Core/GDCore/Extensions/Metadata/ObjectMetadata.h +++ b/Core/GDCore/Extensions/Metadata/ObjectMetadata.h @@ -39,6 +39,8 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada /** * \brief Construct an object metadata, using a "blueprint" object that will * be copied when a new object is requested. + * + * \note This is used for objects declared in JavaScript extensions. */ ObjectMetadata(const gd::String& extensionNamespace_, const gd::String& name_, @@ -47,9 +49,9 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada const gd::String& icon24x24_, std::shared_ptr blueprintObject_); /** - * \brief Construct an object metadata, without "blueprint" object + * \brief Construct an object metadata. * - * \note This is used by events based objects. + * \note This is used by events based objects ("custom objects"). */ ObjectMetadata(const gd::String& extensionNamespace_, const gd::String& name_, @@ -60,14 +62,17 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada /** * \brief Construct an object metadata, with a function that will be called * to instantiate a new object. + * + * \note This is used for objects declared in C++ extensions. */ ObjectMetadata(const gd::String& extensionNamespace_, const gd::String& name_, const gd::String& fullname_, const gd::String& description_, const gd::String& icon24x24_, - CreateFunPtr createFunPtrP); - ObjectMetadata() : createFunPtr(NULL) {} + CreateFunPtr createFunPtr_); + + ObjectMetadata() {} virtual ~ObjectMetadata(){}; /** @@ -360,7 +365,7 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada std::vector includeFiles; gd::String className; - CreateFunPtr createFunPtr; + CreateFunPtr createFunPtr = nullptr; private: gd::String extensionNamespace; diff --git a/Core/GDCore/Extensions/Platform.cpp b/Core/GDCore/Extensions/Platform.cpp index af01a417c37d..97ebf6330be0 100644 --- a/Core/GDCore/Extensions/Platform.cpp +++ b/Core/GDCore/Extensions/Platform.cpp @@ -38,12 +38,14 @@ bool Platform::AddExtension(std::shared_ptr extension) { extensionsLoaded.push_back(extension); - // Load all creation/destruction functions for objects provided by the - // extension + // Load all creation functions for objects provided by the + // extension. vector objectsTypes = extension->GetExtensionObjectsTypes(); for (std::size_t i = 0; i < objectsTypes.size(); ++i) { - creationFunctionTable[objectsTypes[i]] = - extension->GetObjectCreationFunctionPtr(objectsTypes[i]); + CreateFunPtr createFunPtr = extension->GetObjectCreationFunctionPtr(objectsTypes[i]); + if (createFunPtr != nullptr) { + creationFunctionTable[objectsTypes[i]] = createFunPtr; + } } for (const auto& it : @@ -62,7 +64,9 @@ void Platform::RemoveExtension(const gd::String& name) { if (extension->GetName() == name) { vector objectsTypes = extension->GetExtensionObjectsTypes(); for (std::size_t i = 0; i < objectsTypes.size(); ++i) { - creationFunctionTable.erase(objectsTypes[i]); + if (creationFunctionTable.find(objectsTypes[i]) != creationFunctionTable.end()) { + creationFunctionTable.erase(objectsTypes[i]); + } } } } diff --git a/newIDE/app/src/MainFrame/index.js b/newIDE/app/src/MainFrame/index.js index b69b752cba00..3bb62c7cf2d2 100644 --- a/newIDE/app/src/MainFrame/index.js +++ b/newIDE/app/src/MainFrame/index.js @@ -4068,7 +4068,7 @@ const MainFrame = (props: Props) => { } setQuickCustomizationDialogOpenedFromGameId(null); - closeProject(); + await closeProject(); openHomePage(); if (!hasUnsavedChanges) { navigateToRoute('build');