From ca52be3c48004a30c511ef6adfbccb3795091179 Mon Sep 17 00:00:00 2001 From: Ralph Wessel Date: Fri, 8 Nov 2024 15:13:55 +0000 Subject: [PATCH] Clickling cancel during Send emits "triggerCancelSend" event in JS UI --- .../Bridge/Functions/GetCallResult.cpp | 11 +++++- SpeckleLib/Speckle/Record/Element/Element.cpp | 9 +++-- .../Serialise/Collection/ConversionReporter.h | 13 +++++++ SpeckleLib/Speckle/Utility/Exception.h | 2 +- SpeckleLib/Speckle/Utility/UserCancel.h | 37 +++++++++++++++++++ .../SpeckleLib.xcodeproj/project.pbxproj | 4 ++ 6 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 SpeckleLib/Speckle/Utility/UserCancel.h diff --git a/SpeckleLib/Speckle/Interface/Browser/Bridge/Functions/GetCallResult.cpp b/SpeckleLib/Speckle/Interface/Browser/Bridge/Functions/GetCallResult.cpp index b94f108..9cd4a9e 100644 --- a/SpeckleLib/Speckle/Interface/Browser/Bridge/Functions/GetCallResult.cpp +++ b/SpeckleLib/Speckle/Interface/Browser/Bridge/Functions/GetCallResult.cpp @@ -5,6 +5,7 @@ #include "Active/Utility/BufferOut.h" #include "Speckle/Interface/Browser/Bridge/BrowserBridge.h" #include "Speckle/Record/Element/ModelElement.h" +#include "Speckle/Utility/UserCancel.h" #include @@ -45,7 +46,15 @@ std::unique_ptr GetCallResult::getResult(const WrappedResultAr if (!item) return nullptr; String jsonOutput; - JSONTransport().send(std::forward(*item), Identity{}, jsonOutput); + try { + JSONTransport().send(std::forward(*item), Identity{}, jsonOutput); + } catch(const UserCancel& userCancel) { + //If the user cancels and we have a model card ID, notify the JS UI that the operation is cancelled + if (userCancel.getModelCardID()) + getBridge()->sendEvent("triggerCancelSend", + std::make_unique, String>>(String{*userCancel.getModelCardID()})); + return nullptr; + } record::element::ModelElement::resetCache(); return std::make_unique(jsonOutput); } //GetCallResult::getResult diff --git a/SpeckleLib/Speckle/Record/Element/Element.cpp b/SpeckleLib/Speckle/Record/Element/Element.cpp index ce22ad6..a13fbf2 100644 --- a/SpeckleLib/Speckle/Record/Element/Element.cpp +++ b/SpeckleLib/Speckle/Record/Element/Element.cpp @@ -1,5 +1,6 @@ #include "Speckle/Record/Element/Element.h" +#include "Active/Serialise/CargoHold.h" #include "Active/Serialise/Management/Management.h" #include "Speckle/Database/BIMElementDatabase.h" #include "Speckle/Environment/Addon.h" @@ -8,7 +9,7 @@ #include "Speckle/Record/Element/Setting/TypeSetting.h" #include "Speckle/Serialise/Collection/ConversionReporter.h" #include "Speckle/SpeckleResource.h" -#include "Active/Serialise/CargoHold.h" +#include "Speckle/Utility/UserCancel.h" using namespace active::serialise; using namespace speckle::database; @@ -263,8 +264,10 @@ void Element::setDefault() { void Element::useManagement(Management* management) const { if (management != nullptr) { //If a conversion report is collected, add this record to the report (also updates progress display in the UI) - if (auto reporter = management->get(); reporter != nullptr) - reporter->logRecord(getBIMID(), {ConversionReporter::Data::Status::success, getTypeName(), getSpeckleType()}); + if (auto reporter = management->get(); reporter != nullptr) { + if (!reporter->logRecord(getBIMID(), {ConversionReporter::Data::Status::success, getTypeName(), getSpeckleType()})) + throw UserCancel{reporter->getModelCardID()}; + } } } //Element::useManagement diff --git a/SpeckleLib/Speckle/Serialise/Collection/ConversionReporter.h b/SpeckleLib/Speckle/Serialise/Collection/ConversionReporter.h index 921c7f6..27ece7b 100644 --- a/SpeckleLib/Speckle/Serialise/Collection/ConversionReporter.h +++ b/SpeckleLib/Speckle/Serialise/Collection/ConversionReporter.h @@ -2,6 +2,7 @@ #define SPECKLE_SERIALISE_CONVERSION_REPORTER #include "Active/Serialise/Management/Manager.h" +#include "Speckle/Database/Identity/RecordID.h" #include "Speckle/Database/Identity/BIMRecordID.h" namespace speckle::interfac { @@ -46,6 +47,11 @@ namespace speckle::serialise { // MARK: - Functions (const) + /*! + Get the conversion report model card ID + @return The model card ID + */ + const database::RecordID& getModelCardID() const { return m_modelCardID; } /*! Get the conversion log @return The conversion log @@ -54,6 +60,11 @@ namespace speckle::serialise { // MARK: - Functions (mutating) + /*! + Set the conversion report model card ID + @param cardID The model card ID + */ + void setModelCardID(const database::RecordID& cardID) { m_modelCardID = cardID; } /*! Increment the number of projected records to be logged */ @@ -77,6 +88,8 @@ namespace speckle::serialise { private: ///The reporter log Log m_log; + ///The ID of the conversion model card + database::RecordID m_modelCardID; ///The conversion progress UI display std::shared_ptr m_progress; ///Projected number of records to be logged (used to calculate UI progress components) diff --git a/SpeckleLib/Speckle/Utility/Exception.h b/SpeckleLib/Speckle/Utility/Exception.h index 1c29477..7bb11e8 100644 --- a/SpeckleLib/Speckle/Utility/Exception.h +++ b/SpeckleLib/Speckle/Utility/Exception.h @@ -8,7 +8,7 @@ namespace speckle::utility { /*! - Record index class + Speckle exception base */ class Exception : public std::runtime_error { public: diff --git a/SpeckleLib/Speckle/Utility/UserCancel.h b/SpeckleLib/Speckle/Utility/UserCancel.h new file mode 100644 index 0000000..c706c8d --- /dev/null +++ b/SpeckleLib/Speckle/Utility/UserCancel.h @@ -0,0 +1,37 @@ +#ifndef SPECKLE_UTILITY_USER_CANCEL +#define SPECKLE_UTILITY_USER_CANCEL + +#include "Speckle/Database/Identity/RecordID.h" +#include "Speckle/Utility/Exception.h" + +namespace speckle::utility { + + /*! + Exception thrown to signal the user has cancelled a process + */ + class UserCancel : public Exception { + public: + /*! + Default constructor + */ + UserCancel() : Exception{{}} {} + /*! + Constructor + @param modelCardID The model card ID associated with the cancelled process + */ + UserCancel(const database::RecordID& modelCardID) : Exception{{}}, m_modelCardID{modelCardID} {} + + /*! + Get the ID of the model card associated with the cancelled process + @return The model card ID (nullopt = process not associated with a model card) + */ + const database::RecordID::Option getModelCardID() const { return m_modelCardID; } + + private: + ///The model card ID associated with the cancelled process (nullopt = process not associated with a model card) + database::RecordID::Option m_modelCardID; + }; + +} + +#endif //SPECKLE_UTILITY_USER_CANCEL diff --git a/SpeckleLib/SpeckleLib.xcodeproj/project.pbxproj b/SpeckleLib/SpeckleLib.xcodeproj/project.pbxproj index ed4c1e2..b3279fa 100644 --- a/SpeckleLib/SpeckleLib.xcodeproj/project.pbxproj +++ b/SpeckleLib/SpeckleLib.xcodeproj/project.pbxproj @@ -80,6 +80,7 @@ 2199BB6F2CDC2B2500A4BEEC /* ConversionReporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2199BB6E2CDC2B2500A4BEEC /* ConversionReporter.cpp */; }; 2199BB732CDCB0D500A4BEEC /* Progress.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2199BB702CDCB0D500A4BEEC /* Progress.cpp */; }; 2199BB742CDCB0D500A4BEEC /* Progress.h in Headers */ = {isa = PBXBuildFile; fileRef = 2199BB712CDCB0D500A4BEEC /* Progress.h */; }; + 2199BB842CDE508800A4BEEC /* UserCancel.h in Headers */ = {isa = PBXBuildFile; fileRef = 2199BB812CDE508800A4BEEC /* UserCancel.h */; }; 21A0FBA42CB880690023F24E /* FinishCollector.h in Headers */ = {isa = PBXBuildFile; fileRef = 21A0FB9F2CB880690023F24E /* FinishCollector.h */; }; 21A0FBB52CBA5E380023F24E /* Str256.h in Headers */ = {isa = PBXBuildFile; fileRef = 21A0FBB42CBA5E380023F24E /* Str256.h */; }; 21A0FBBC2CBBC04C0023F24E /* ArchicadRGB.h in Headers */ = {isa = PBXBuildFile; fileRef = 21A0FBB92CBBC04C0023F24E /* ArchicadRGB.h */; }; @@ -312,6 +313,7 @@ 2199BB6E2CDC2B2500A4BEEC /* ConversionReporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConversionReporter.cpp; sourceTree = ""; }; 2199BB702CDCB0D500A4BEEC /* Progress.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Progress.cpp; sourceTree = ""; }; 2199BB712CDCB0D500A4BEEC /* Progress.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Progress.h; sourceTree = ""; }; + 2199BB812CDE508800A4BEEC /* UserCancel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserCancel.h; sourceTree = ""; }; 21A0FB9F2CB880690023F24E /* FinishCollector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FinishCollector.h; sourceTree = ""; }; 21A0FBA92CB9324A0023F24E /* FinishProxy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FinishProxy.h; sourceTree = ""; }; 21A0FBB42CBA5E380023F24E /* Str256.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Str256.h; sourceTree = ""; }; @@ -672,6 +674,7 @@ 210CC88D2C81A98500610F58 /* Guid64.h */, 219351AE2C62CC1A00E5A69C /* String.cpp */, 219351AF2C62CC1A00E5A69C /* String.h */, + 2199BB812CDE508800A4BEEC /* UserCancel.h */, ); path = Utility; sourceTree = ""; @@ -1082,6 +1085,7 @@ 21A0FBA42CB880690023F24E /* FinishCollector.h in Headers */, 21384C192CD585A600D4602B /* Roof.h in Headers */, 21AE19802CC7D265004DBCFC /* PropertiedWrapper.h in Headers */, + 2199BB842CDE508800A4BEEC /* UserCancel.h in Headers */, 21A0FC0B2CBE5E220023F24E /* Segment.h in Headers */, 215F088D2CA195EC00CD343B /* ArchicadElementDBaseEngine.h in Headers */, 21384BC82CD24ADC00D4602B /* ElementEvent.h in Headers */,