From 4ff7d68516122f70fb662ab6b1fd57ada757a989 Mon Sep 17 00:00:00 2001 From: Ralph Wessel Date: Wed, 20 Nov 2024 21:49:47 +0000 Subject: [PATCH] ElementHighlighter ensures layers are visible (on request) before selecting target elements Updates to allow attribute changes to be written Workaround to force VS to recognise template specialisations --- SpeckleConnector/Connector.vcxproj | 6 ++++ SpeckleConnector/Connector.vcxproj.filters | 30 +++++++++++++++++-- SpeckleConnector/Connector/Connector.cpp | 25 ++++++++++++++++ .../Connector/ConnectorResource.h | 2 +- .../Browser/Bridge/Base/HighlightModel.cpp | 18 ++++++----- .../Browser/Bridge/Base/HighlightObjects.cpp | 26 +++++----------- .../Bridge/Selection/SelectionBridge.cpp | 2 +- .../Connector/Tool/ElementHighlighter.cpp | 7 +++-- SpeckleConnector/RINT/Connector.grc | 2 +- .../Speckle/Database/BIMElementDatabase.cpp | 2 +- .../Speckle/Database/BIMElementDatabase.h | 2 +- .../ArchicadAttributeDBaseEngine.cpp | 2 +- .../Attribute/ArchicadAttributeDBaseEngine.h | 2 +- .../Element/ArchicadElementDBaseEngine.cpp | 8 +++-- .../Element/ArchicadElementDBaseEngine.h | 2 +- .../Property/ArchicadGroupDBaseEngine.h | 2 +- .../Property/ArchicadPropertyDBaseEngine.h | 2 +- .../DocumentStore/DocumentStoreEngine.h | 2 +- SpeckleLib/Speckle/Environment/Host.cpp | 4 +-- .../Speckle/Interface/Browser/JSFunction.h | 2 ++ .../Speckle/Record/Attribute/Attribute.h | 5 ++++ .../Speckle/Record/Attribute/Finish.cpp | 14 +++++++++ SpeckleLib/Speckle/Record/Attribute/Finish.h | 9 +++++- SpeckleLib/Speckle/Record/Attribute/Layer.cpp | 18 +++++++++++ SpeckleLib/Speckle/Record/Attribute/Layer.h | 9 +++++- .../Speckle/Record/Attribute/Material.cpp | 14 +++++++++ .../Speckle/Record/Attribute/Material.h | 9 +++++- .../Speckle/Record/Attribute/Storey.cpp | 12 ++++++++ SpeckleLib/Speckle/Record/Attribute/Storey.h | 7 +++++ .../Serialise/JSBase/JSBaseTransport.cpp | 4 +-- SpeckleLib/SpeckleLib17.vcxproj | 4 +++ SpeckleLib/SpeckleLib17.vcxproj.filters | 15 ++++++++++ 32 files changed, 214 insertions(+), 54 deletions(-) diff --git a/SpeckleConnector/Connector.vcxproj b/SpeckleConnector/Connector.vcxproj index 96f0cbf..33d1e1d 100644 --- a/SpeckleConnector/Connector.vcxproj +++ b/SpeckleConnector/Connector.vcxproj @@ -175,6 +175,8 @@ + + @@ -206,6 +208,7 @@ + @@ -234,6 +237,8 @@ + + @@ -268,6 +273,7 @@ + diff --git a/SpeckleConnector/Connector.vcxproj.filters b/SpeckleConnector/Connector.vcxproj.filters index 2e2ca28..bf46e71 100644 --- a/SpeckleConnector/Connector.vcxproj.filters +++ b/SpeckleConnector/Connector.vcxproj.filters @@ -74,6 +74,12 @@ {1d9a10c3-cac6-4b15-afb9-f117b99b3a24} + + {896b7b9b-61d8-46e7-8432-cfbdab4918fb} + + + {f9330e8f-8242-4605-b25c-b1ba24451825} + @@ -98,9 +104,6 @@ - - Connector - Connector\Interface @@ -260,6 +263,18 @@ Connector\Interface\Browser\Bridge\Config + + Connector\Interface\Browser\Bridge\Receive + + + Connector\Interface\Browser\Bridge\Receive + + + Connector\Tool + + + Connector + @@ -445,5 +460,14 @@ Connector\Interface\Browser\Bridge\Config + + Connector\Interface\Browser\Bridge\Receive + + + Connector\Interface\Browser\Bridge\Receive + + + Connector\Tool + \ No newline at end of file diff --git a/SpeckleConnector/Connector/Connector.cpp b/SpeckleConnector/Connector/Connector.cpp index 9321923..c63157b 100644 --- a/SpeckleConnector/Connector/Connector.cpp +++ b/SpeckleConnector/Connector/Connector.cpp @@ -4,12 +4,21 @@ #include "Connector/Environment/ConnectorProject.h" #include "Connector/Interface/ConnectorMenu.h" #include "Connector/Interface/ConnectorPalette.h" +#include "Connector/Tool/ElementHighlighter.h" #include "Speckle/Database/AccountDatabase.h" #include "Speckle/Environment/Addon.h" #include "Speckle/Utility/String.h" #include +#ifdef WINDOWS + //NB: VS is ignoring template specialisations unless they are explicitly used in the top-level project +#include "Active/Setting/Values/GuidValue.h" +#include "Active/Setting/Values/TimeValue.h" +#include "Active/Setting/Values/StringValue.h" +using namespace active::setting; +#endif + using namespace active::file; using namespace active::environment; using namespace connector; @@ -42,6 +51,7 @@ namespace { //Define the connector UI components add(); add(); + add(); } // MARK: Functions (const) @@ -84,6 +94,18 @@ namespace { return std::nullopt; return Directory{*appData, speckleDataDirName, true}; } //getAppDataDirectory + +#ifdef WINDOWS + //NB: VS is ignoring template specialisations unless they are explicitly used in the top-level project + void invokeSpecialisation() { + StringValue stringValue; + active::utility::String unusedString = stringValue; + GuidValue guidValue; + active::utility::Guid unusedGuid = guidValue; + TimeValue timeValue; + active::utility::Time unusedTime = timeValue; + } +#endif } @@ -93,6 +115,9 @@ namespace { name: The add-on name --------------------------------------------------------------------*/ ConnectorAddon::ConnectorAddon(const speckle::utility::String& name) : Addon{name} { +#ifdef WINDOWS + invokeSpecialisation(); +#endif } //ConnectorAddon::ConnectorAddon diff --git a/SpeckleConnector/Connector/ConnectorResource.h b/SpeckleConnector/Connector/ConnectorResource.h index aa4983f..7a31c72 100755 --- a/SpeckleConnector/Connector/ConnectorResource.h +++ b/SpeckleConnector/Connector/ConnectorResource.h @@ -40,12 +40,12 @@ enum PromptString { //Information strings (in UI content, logging, reports) enum GeneralString { - showHiddenLayersID = 1, }; //Notification strings (advice displayed in alerts) enum NotifyString { + showHiddenLayersID = 1, }; diff --git a/SpeckleConnector/Connector/Interface/Browser/Bridge/Base/HighlightModel.cpp b/SpeckleConnector/Connector/Interface/Browser/Bridge/Base/HighlightModel.cpp index 724aa59..ee6f7d3 100644 --- a/SpeckleConnector/Connector/Interface/Browser/Bridge/Base/HighlightModel.cpp +++ b/SpeckleConnector/Connector/Interface/Browser/Bridge/Base/HighlightModel.cpp @@ -1,7 +1,11 @@ +#include "Active/Setting/ValueSetting.h" +#include "Active/Setting/Values/GuidValue.h" +#include "Active/Event/Event.h" #include "Connector/Interface/Browser/Bridge/Base/HighlightModel.h" #include "Connector/Connector.h" #include "Connector/ConnectorResource.h" #include "Connector/Environment/ConnectorProject.h" +#include "Connector/Event/ConnectorEventID.h" #include "Connector/Database/ModelCardDatabase.h" #include "Connector/Interface/Browser/Bridge/Send/Arg/SendError.h" #include "Connector/Record/Model/SenderModelCard.h" @@ -12,6 +16,8 @@ #include "Speckle/Environment/Host.h" #include "Speckle/Environment/Project.h" +using namespace active::event; +using namespace active::setting; using namespace connector::environment; using namespace connector::interfac::browser::bridge; using namespace connector::record; @@ -46,13 +52,9 @@ void HighlightModel::run(const String& modelCardID) const { return; } if (auto senderCard = dynamic_cast(modelCard.get())) { - auto modelCardSelection = senderCard->getFilter().getElementIDs(); - auto project = connector()->getActiveProject().lock(); - if (!project) - return; // TODO: is this OK? should this throw? - auto elementDatabase = project->getElementDatabase(); - elementDatabase->clearSelection(); - elementDatabase->setSelection(modelCardSelection); - host()->zoomToFit(true); + ValueSetting elementIDs{recordLinks}; + for (const auto& elementID : senderCard->getFilter().getElementIDs()) + elementIDs.emplace_back(GuidValue{elementID}); + connector()->publish(Event{setElementHighlight, { elementIDs }}); } } //HighlightModel::run diff --git a/SpeckleConnector/Connector/Interface/Browser/Bridge/Base/HighlightObjects.cpp b/SpeckleConnector/Connector/Interface/Browser/Bridge/Base/HighlightObjects.cpp index 1fa87ae..a977c74 100644 --- a/SpeckleConnector/Connector/Interface/Browser/Bridge/Base/HighlightObjects.cpp +++ b/SpeckleConnector/Connector/Interface/Browser/Bridge/Base/HighlightObjects.cpp @@ -1,12 +1,13 @@ #include "Connector/Interface/Browser/Bridge/Base/HighlightObjects.h" +#include "Active/Setting/ValueSetting.h" +#include "Active/Event/Event.h" #include "Connector/Connector.h" -#include "Connector/Environment/ConnectorProject.h" -#include "Speckle/Database/BIMElementDatabase.h" -#include "Speckle/Environment/Host.h" -#include "Speckle/Environment/Project.h" +#include "Connector/Event/ConnectorEventID.h" -using namespace connector::environment; +using namespace active::event; +using namespace active::setting; +using namespace connector; using namespace connector::interfac::browser::bridge; using namespace speckle::database; using namespace speckle::environment; @@ -26,18 +27,5 @@ HighlightObjects::HighlightObjects() : BridgeMethod{"HighlightObjects", [&](cons objectIDs: List of object IDs to be highlighted --------------------------------------------------------------------*/ void HighlightObjects::run(const StringList& objectIDs) const { - BIMLinkList objectSelection; - for (const auto& text : objectIDs) - if (Guid guid{text}; !guid.empty()) - objectSelection.emplace_back(guid); - if (objectSelection.empty()) - return; - auto project = connector()->getActiveProject().lock(); - auto connectorProject = dynamic_cast(project.get()); - if (!connectorProject) - return; - auto elementDatabase = project->getElementDatabase(); - elementDatabase->clearSelection(); - elementDatabase->setSelection(objectSelection); - host()->zoomToFit(true); + connector()->publish(Event{setElementHighlight, { ValueSetting{objectIDs, recordLinks} }}); } //HighlightObjects::run diff --git a/SpeckleConnector/Connector/Interface/Browser/Bridge/Selection/SelectionBridge.cpp b/SpeckleConnector/Connector/Interface/Browser/Bridge/Selection/SelectionBridge.cpp index cb05aed..559cc96 100644 --- a/SpeckleConnector/Connector/Interface/Browser/Bridge/Selection/SelectionBridge.cpp +++ b/SpeckleConnector/Connector/Interface/Browser/Bridge/Selection/SelectionBridge.cpp @@ -24,7 +24,7 @@ SelectionBridge::SelectionBridge() : BrowserBridge{"selectionBinding"} { --------------------------------------------------------------------*/ bool SelectionBridge::handle(const speckle::event::SelectionEvent& event) { auto selectionInfo = std::make_unique(); - auto wrapped = std::make_unique>(std::move(selectionInfo)); + auto wrapped = std::make_unique>(std::move(selectionInfo)); sendEvent("setSelection", std::move(wrapped)); return true; } //SelectionBridge::handle diff --git a/SpeckleConnector/Connector/Tool/ElementHighlighter.cpp b/SpeckleConnector/Connector/Tool/ElementHighlighter.cpp index 985bfa6..13fb5f9 100644 --- a/SpeckleConnector/Connector/Tool/ElementHighlighter.cpp +++ b/SpeckleConnector/Connector/Tool/ElementHighlighter.cpp @@ -86,11 +86,11 @@ Subscriber::Subscription ElementHighlighter::subscription() const { bool ElementHighlighter::receive(const active::event::Event& event) { //Collect the IDs of elements to be highlighted ValueSetting* elementIDs = nullptr; - if (elementIDs = event.findValue(recordLinks); elementIDs != nullptr) + if (elementIDs = event.findValue(recordLinks); elementIDs == nullptr) return false; BIMLinkList elementSelection; for (const auto& value : *elementIDs) - if (Guid guid{*value}; guid) + if (Guid guid{value->operator active::utility::Guid()}; guid) elementSelection.emplace_back(guid); if (elementSelection.empty()) return false; @@ -101,7 +101,8 @@ bool ElementHighlighter::receive(const active::event::Event& event) { auto elementDatabase = project->getElementDatabase(); //Collect the layers assigned to the model card elements ElementVisibilityCollector collector; - elementDatabase->findElements(collector, elementSelection); + BIMElementDatabase::Filter filter = [&collector](const speckle::record::element::Element& elem) { return collector(elem); }; + elementDatabase->findElements(&filter, elementSelection); //If any collected layers are hidden, the useer is prompted to show them (otherwise they may see nothing happen when a model card is clicked) for (const auto& layer : collector.getLayers()) { if (layer.second.isHidden()) { diff --git a/SpeckleConnector/RINT/Connector.grc b/SpeckleConnector/RINT/Connector.grc index 58f0d09..9e938ff 100644 --- a/SpeckleConnector/RINT/Connector.grc +++ b/SpeckleConnector/RINT/Connector.grc @@ -7,7 +7,7 @@ 'STR#' 32602 "Notify strings" { -/* [ 1] */ "No objects were found to convert. Please update your publish filter!" +/* [ 1] */ "Some elements published with the selected model card are on hidden layers - do you wish to make these layers visible?" } diff --git a/SpeckleLib/Speckle/Database/BIMElementDatabase.cpp b/SpeckleLib/Speckle/Database/BIMElementDatabase.cpp index ffe00ca..408144f 100644 --- a/SpeckleLib/Speckle/Database/BIMElementDatabase.cpp +++ b/SpeckleLib/Speckle/Database/BIMElementDatabase.cpp @@ -154,7 +154,7 @@ void BIMElementDatabase::clearSelection() const { return: A list containing IDs of found elements (empty if none found) --------------------------------------------------------------------*/ -BIMRecordIDList BIMElementDatabase::findElements(const Filter& filter, const BIMRecordIDList& subset, std::optional tableID, +BIMRecordIDList BIMElementDatabase::findElements(const Filter* filter, const BIMRecordIDList& subset, std::optional tableID, std::optional documentID) const { return m_engine->findObjects(filter, subset, tableID, documentID); } //BIMElementDatabase::findElements diff --git a/SpeckleLib/Speckle/Database/BIMElementDatabase.h b/SpeckleLib/Speckle/Database/BIMElementDatabase.h index d03b2d3..d1a692c 100644 --- a/SpeckleLib/Speckle/Database/BIMElementDatabase.h +++ b/SpeckleLib/Speckle/Database/BIMElementDatabase.h @@ -79,7 +79,7 @@ namespace speckle::database { @param documentID Optional document ID (filter for this document only - nullopt = all objects) @return A list containing IDs of found elements (empty if none found) */ - BIMRecordIDList findElements(const Filter& filter = nullptr, const BIMRecordIDList& subset = {}, + BIMRecordIDList findElements(const Filter* filter = nullptr, const BIMRecordIDList& subset = {}, std::optional tableID = std::nullopt, std::optional documentID = std::nullopt) const; /*! Get a specified element diff --git a/SpeckleLib/Speckle/Database/Storage/ArchicadDBase/Attribute/ArchicadAttributeDBaseEngine.cpp b/SpeckleLib/Speckle/Database/Storage/ArchicadDBase/Attribute/ArchicadAttributeDBaseEngine.cpp index a71a5fe..85d2e57 100644 --- a/SpeckleLib/Speckle/Database/Storage/ArchicadDBase/Attribute/ArchicadAttributeDBaseEngine.cpp +++ b/SpeckleLib/Speckle/Database/Storage/ArchicadDBase/Attribute/ArchicadAttributeDBaseEngine.cpp @@ -223,7 +223,7 @@ active::container::Vector ArchicadAttributeDBaseEngine::getObjects(co --------------------------------------------------------------------*/ void ArchicadAttributeDBaseEngine::write(Attribute& object, const BIMRecordID& objID, std::optional objDocID, std::optional tableID, std::optional documentID) const { - auto attributeData = object.getData(); + auto attributeData = object.getDataOut(); //An record with no index has not been written (and needs to be created in the dbase) GSErrCode status = NoError; #ifdef ServerMainVers_2700 diff --git a/SpeckleLib/Speckle/Database/Storage/ArchicadDBase/Attribute/ArchicadAttributeDBaseEngine.h b/SpeckleLib/Speckle/Database/Storage/ArchicadDBase/Attribute/ArchicadAttributeDBaseEngine.h index c988a2e..cf66b6b 100644 --- a/SpeckleLib/Speckle/Database/Storage/ArchicadDBase/Attribute/ArchicadAttributeDBaseEngine.h +++ b/SpeckleLib/Speckle/Database/Storage/ArchicadDBase/Attribute/ArchicadAttributeDBaseEngine.h @@ -60,7 +60,7 @@ namespace speckle::database { @param documentID Optional document ID (filter for this document only - nullopt = all objects) @return A list containing IDs of found elements (empty if none found) */ - virtual ObjIDList findObjects(const Filter& filter = nullptr, const ObjIDList& subset = {}, + virtual ObjIDList findObjects(const Filter* filter = nullptr, const ObjIDList& subset = {}, std::optional tableID = std::nullopt, std::optional documentID = std::nullopt) const override { return {}; } //Implement when required /*! diff --git a/SpeckleLib/Speckle/Database/Storage/ArchicadDBase/Element/ArchicadElementDBaseEngine.cpp b/SpeckleLib/Speckle/Database/Storage/ArchicadDBase/Element/ArchicadElementDBaseEngine.cpp index 130e4a0..ad00cef 100644 --- a/SpeckleLib/Speckle/Database/Storage/ArchicadDBase/Element/ArchicadElementDBaseEngine.cpp +++ b/SpeckleLib/Speckle/Database/Storage/ArchicadDBase/Element/ArchicadElementDBaseEngine.cpp @@ -308,7 +308,7 @@ void ArchicadElementDBaseEngine::setDefaultTable(const BIMRecordID& tableID) con return: A list containing IDs of found elements (empty if none found) --------------------------------------------------------------------*/ -BIMRecordIDList ArchicadElementDBaseEngine::findObjects(const Filter& filter, const BIMRecordIDList& subset, std::optional tableID, +BIMRecordIDList ArchicadElementDBaseEngine::findObjects(const Filter* filter, const BIMRecordIDList& subset, std::optional tableID, std::optional documentID) const { //Switch to the target table (when specified). Otherwise the currently active table will be used if (tableID) @@ -328,8 +328,10 @@ BIMRecordIDList ArchicadElementDBaseEngine::findObjects(const Filter& filter, co } //Run the filter on the specified elements for (const auto& elemID : *source) { - if (auto element = getObject(elemID); element && filter(*element)) - result.insert(elemID); + if (auto element = getObject(elemID); element) { + if ((*filter)(*element)) + result.insert(elemID); + } } return result; } //ArchicadElementDBaseEngine::findObjects diff --git a/SpeckleLib/Speckle/Database/Storage/ArchicadDBase/Element/ArchicadElementDBaseEngine.h b/SpeckleLib/Speckle/Database/Storage/ArchicadDBase/Element/ArchicadElementDBaseEngine.h index 468eaba..a8679b5 100644 --- a/SpeckleLib/Speckle/Database/Storage/ArchicadDBase/Element/ArchicadElementDBaseEngine.h +++ b/SpeckleLib/Speckle/Database/Storage/ArchicadDBase/Element/ArchicadElementDBaseEngine.h @@ -97,7 +97,7 @@ namespace speckle::database { @param documentID Optional document ID (filter for this document only - nullopt = all objects) @return A list containing IDs of found elements (empty if none found) */ - virtual BIMRecordIDList findObjects(const Filter& filter = nullptr, const BIMRecordIDList& subset = {}, + virtual BIMRecordIDList findObjects(const Filter* filter = nullptr, const BIMRecordIDList& subset = {}, std::optional tableID = std::nullopt, std::optional documentID = std::nullopt) const override; /*! diff --git a/SpeckleLib/Speckle/Database/Storage/ArchicadDBase/Property/ArchicadGroupDBaseEngine.h b/SpeckleLib/Speckle/Database/Storage/ArchicadDBase/Property/ArchicadGroupDBaseEngine.h index cf2ac31..59c96c5 100644 --- a/SpeckleLib/Speckle/Database/Storage/ArchicadDBase/Property/ArchicadGroupDBaseEngine.h +++ b/SpeckleLib/Speckle/Database/Storage/ArchicadDBase/Property/ArchicadGroupDBaseEngine.h @@ -55,7 +55,7 @@ namespace speckle::database { @param documentID Optional document ID (filter for this document only - nullopt = all objects) @return A list containing IDs of found elements (empty if none found) */ - virtual ObjIDList findObjects(const Filter& filter = nullptr, const ObjIDList& subset = {}, + virtual ObjIDList findObjects(const Filter* filter = nullptr, const ObjIDList& subset = {}, std::optional tableID = std::nullopt, std::optional documentID = std::nullopt) const override { return {}; } //Implement when required /*! diff --git a/SpeckleLib/Speckle/Database/Storage/ArchicadDBase/Property/ArchicadPropertyDBaseEngine.h b/SpeckleLib/Speckle/Database/Storage/ArchicadDBase/Property/ArchicadPropertyDBaseEngine.h index c652d7f..1cfa27b 100644 --- a/SpeckleLib/Speckle/Database/Storage/ArchicadDBase/Property/ArchicadPropertyDBaseEngine.h +++ b/SpeckleLib/Speckle/Database/Storage/ArchicadDBase/Property/ArchicadPropertyDBaseEngine.h @@ -56,7 +56,7 @@ namespace speckle::database { @param documentID Optional document ID (filter for this document only - nullopt = all objects) @return A list containing IDs of found elements (empty if none found) */ - virtual ObjIDList findObjects(const Filter& filter = nullptr, const ObjIDList& subset = {}, std::optional tableID = std::nullopt, + virtual ObjIDList findObjects(const Filter* filter = nullptr, const ObjIDList& subset = {}, std::optional tableID = std::nullopt, std::optional documentID = std::nullopt) const override { return {}; } //Implement when required /*! Find all property templates linked to specified classifications diff --git a/SpeckleLib/Speckle/Database/Storage/DocumentStore/DocumentStoreEngine.h b/SpeckleLib/Speckle/Database/Storage/DocumentStore/DocumentStoreEngine.h index e7420ab..88bf31a 100644 --- a/SpeckleLib/Speckle/Database/Storage/DocumentStore/DocumentStoreEngine.h +++ b/SpeckleLib/Speckle/Database/Storage/DocumentStore/DocumentStoreEngine.h @@ -68,7 +68,7 @@ namespace speckle::database { @param documentID Optional document ID (filter for this document only - nullopt = all objects) @return A list containing IDs of found elements (empty if none found) */ - virtual ObjIDList findObjects(const Filter& filter = nullptr, const ObjIDList& subset = {}, std::optional tableID = std::nullopt, + virtual ObjIDList findObjects(const Filter* filter = nullptr, const ObjIDList& subset = {}, std::optional tableID = std::nullopt, std::optional documentID = std::nullopt) const override { return {}; } //Implement when required /*! Get an object by index diff --git a/SpeckleLib/Speckle/Environment/Host.cpp b/SpeckleLib/Speckle/Environment/Host.cpp index 0fd0235..9b1e0a7 100644 --- a/SpeckleLib/Speckle/Environment/Host.cpp +++ b/SpeckleLib/Speckle/Environment/Host.cpp @@ -107,8 +107,8 @@ bool Host::displayConfirmation(const speckle::utility::String& question, const speckle::utility::String::Option negativeOption) const { #ifdef ARCHICAD String positivePrompt{positiveOption.value_or(addon()->getLocalString(titleStringLib, positiveResponseTitleID))}, - negativePrompt{positiveOption.value_or(addon()->getLocalString(titleStringLib, positiveResponseTitleID))}; - return (DGAlert(DG_WARNING, addon()->getLocalString(titleStringLib, confirmDialogTitleID), question, positivePrompt, negativePrompt) == 1); + negativePrompt{positiveOption.value_or(addon()->getLocalString(titleStringLib, negativeResponseTitleID))}; + return (DGAlert(DG_WARNING, addon()->getLocalString(titleStringLib, confirmDialogTitleID), question, String{}, positivePrompt, negativePrompt) == 1); #endif } //Host::displayConfirmation diff --git a/SpeckleLib/Speckle/Interface/Browser/JSFunction.h b/SpeckleLib/Speckle/Interface/Browser/JSFunction.h index 0044ebf..5ad0b60 100644 --- a/SpeckleLib/Speckle/Interface/Browser/JSFunction.h +++ b/SpeckleLib/Speckle/Interface/Browser/JSFunction.h @@ -74,6 +74,8 @@ namespace speckle::interfac::browser { //Process any returned result into the binding value type auto processResult = [&, transport](Return* outgoing) -> typename Binding::ValueType { if constexpr(!std::is_same::value) { + if (outgoing == nullptr) + throw; //NB: Throw a system exception here in future with a defined error typename Binding::ValueType result; transport.send(std::move(*outgoing), active::serialise::Identity{}, result); return result; diff --git a/SpeckleLib/Speckle/Record/Attribute/Attribute.h b/SpeckleLib/Speckle/Record/Attribute/Attribute.h index adc3577..372df5d 100644 --- a/SpeckleLib/Speckle/Record/Attribute/Attribute.h +++ b/SpeckleLib/Speckle/Record/Attribute/Attribute.h @@ -117,6 +117,11 @@ namespace speckle::record::attribute { @return The attribute data (for internal use to populate derived classes) */ API_Attribute getData() const; + /*! + Get the attribute data to be written to the database + @return The attribute data (for internal use to write to the database) + */ + virtual API_Attribute getDataOut() const = 0; #endif }; diff --git a/SpeckleLib/Speckle/Record/Attribute/Finish.cpp b/SpeckleLib/Speckle/Record/Attribute/Finish.cpp index ac028a6..b9dc137 100644 --- a/SpeckleLib/Speckle/Record/Attribute/Finish.cpp +++ b/SpeckleLib/Speckle/Record/Attribute/Finish.cpp @@ -275,6 +275,20 @@ bool Finish::validate() { } //Finish::validate +/*-------------------------------------------------------------------- + Get the attribute data to be written to the database + + return: The attribute data (for internal use to write to the database) + --------------------------------------------------------------------*/ +API_Attribute Finish::getDataOut() const { + confirmData(); + API_Attribute result; + active::utility::Memory::erase(result); + result.material = m_data->root; + return result; +} //Finish::getDataOut + + /*-------------------------------------------------------------------- Confirm the internal data, either loading from the BIM application or setting a default --------------------------------------------------------------------*/ diff --git a/SpeckleLib/Speckle/Record/Attribute/Finish.h b/SpeckleLib/Speckle/Record/Attribute/Finish.h index c1aaffd..e12b42a 100644 --- a/SpeckleLib/Speckle/Record/Attribute/Finish.h +++ b/SpeckleLib/Speckle/Record/Attribute/Finish.h @@ -135,7 +135,14 @@ namespace speckle::record::attribute { @return True if the data has been validated */ bool validate() override; - + + protected: + /*! + Get the attribute data to be written to the database + @return The attribute data (for internal use to write to the database) + */ + API_Attribute getDataOut() const override; + private: /*! Confirm the internal data, either loading from the BIM application or setting a default diff --git a/SpeckleLib/Speckle/Record/Attribute/Layer.cpp b/SpeckleLib/Speckle/Record/Attribute/Layer.cpp index eed370f..a46e1a6 100644 --- a/SpeckleLib/Speckle/Record/Attribute/Layer.cpp +++ b/SpeckleLib/Speckle/Record/Attribute/Layer.cpp @@ -125,6 +125,7 @@ Layer& Layer::operator=(const Layer& source) { return: True if the layer is hidden --------------------------------------------------------------------*/ bool Layer::isHidden() const { + confirmData(); return m_data->isHidden; } //Layer::isHidden @@ -135,6 +136,7 @@ bool Layer::isHidden() const { return: True if the layer is locked --------------------------------------------------------------------*/ bool Layer::isLocked() const { + confirmData(); return m_data->isLocked; } //Layer::isLocked @@ -158,6 +160,7 @@ const API_Attr_Head& Layer::getHead() const { state: True if the layer is hidden --------------------------------------------------------------------*/ void Layer::setHidden(bool state) { + confirmData(); m_data->isHidden = state; #ifdef ARCHICAD if (state) @@ -174,6 +177,7 @@ void Layer::setHidden(bool state) { state: True if the layer is locked --------------------------------------------------------------------*/ void Layer::setLocked(bool state) { + confirmData(); m_data->isLocked = state; #ifdef ARCHICAD if (state) @@ -265,6 +269,20 @@ bool Layer::validate() { } //Layer::validate +/*-------------------------------------------------------------------- + Get the attribute data to be written to the database + + return: The attribute data (for internal use to write to the database) + --------------------------------------------------------------------*/ +API_Attribute Layer::getDataOut() const { + confirmData(); + API_Attribute result; + active::utility::Memory::erase(result); + result.layer = m_data->root; + return result; +} //Layer::getDataOut + + /*-------------------------------------------------------------------- Confirm the internal data, either loading from the BIM application or setting a default --------------------------------------------------------------------*/ diff --git a/SpeckleLib/Speckle/Record/Attribute/Layer.h b/SpeckleLib/Speckle/Record/Attribute/Layer.h index 3351349..1c13719 100644 --- a/SpeckleLib/Speckle/Record/Attribute/Layer.h +++ b/SpeckleLib/Speckle/Record/Attribute/Layer.h @@ -150,7 +150,14 @@ namespace speckle::record::attribute { @return True if the data has been validated */ bool validate() override; - + + protected: + /*! + Get the attribute data to be written to the database + @return The attribute data (for internal use to write to the database) + */ + API_Attribute getDataOut() const override; + private: /*! Confirm the internal data, either loading from the BIM application or setting a default diff --git a/SpeckleLib/Speckle/Record/Attribute/Material.cpp b/SpeckleLib/Speckle/Record/Attribute/Material.cpp index 13e6142..d623dcc 100644 --- a/SpeckleLib/Speckle/Record/Attribute/Material.cpp +++ b/SpeckleLib/Speckle/Record/Attribute/Material.cpp @@ -186,6 +186,20 @@ void Material::setDefault() { } //Material::setDefault +/*-------------------------------------------------------------------- + Get the attribute data to be written to the database + + return: The attribute data (for internal use to write to the database) + --------------------------------------------------------------------*/ +API_Attribute Material::getDataOut() const { + confirmData(); + API_Attribute result; + active::utility::Memory::erase(result); + result.buildingMaterial = m_data->root; + return result; +} //Material::getDataOut + + /*-------------------------------------------------------------------- Confirm the internal data, either loading from the BIM application or setting a default --------------------------------------------------------------------*/ diff --git a/SpeckleLib/Speckle/Record/Attribute/Material.h b/SpeckleLib/Speckle/Record/Attribute/Material.h index fd5b0f6..2273c28 100644 --- a/SpeckleLib/Speckle/Record/Attribute/Material.h +++ b/SpeckleLib/Speckle/Record/Attribute/Material.h @@ -126,7 +126,14 @@ namespace speckle::record::attribute { Set to the default package content */ void setDefault() override; - + + protected: + /*! + Get the attribute data to be written to the database + @return The attribute data (for internal use to write to the database) + */ + API_Attribute getDataOut() const override; + private: /*! Confirm the internal data, either loading from the BIM application or setting a default diff --git a/SpeckleLib/Speckle/Record/Attribute/Storey.cpp b/SpeckleLib/Speckle/Record/Attribute/Storey.cpp index 69ec24b..f37921c 100644 --- a/SpeckleLib/Speckle/Record/Attribute/Storey.cpp +++ b/SpeckleLib/Speckle/Record/Attribute/Storey.cpp @@ -185,6 +185,18 @@ void Storey::setDefault() { } //Storey::setDefault +/*-------------------------------------------------------------------- + Get the attribute data to be written to the database + + return: The attribute data (for internal use to write to the database) + --------------------------------------------------------------------*/ +API_Attribute Storey::getDataOut() const { + API_Attribute result; + active::utility::Memory::erase(result); + return result; +} //Storey::getDataOut + + /*-------------------------------------------------------------------- Confirm the internal data, either loading from the BIM application or setting a default --------------------------------------------------------------------*/ diff --git a/SpeckleLib/Speckle/Record/Attribute/Storey.h b/SpeckleLib/Speckle/Record/Attribute/Storey.h index e009eec..4ef24b5 100644 --- a/SpeckleLib/Speckle/Record/Attribute/Storey.h +++ b/SpeckleLib/Speckle/Record/Attribute/Storey.h @@ -104,6 +104,13 @@ namespace speckle::record::attribute { */ void setDefault() override; + protected: + /*! + Get the attribute data to be written to the database + @return The attribute data (for internal use to write to the database) + */ + API_Attribute getDataOut() const override; + private: /*! Confirm the internal data, either loading from the BIM application or setting a default diff --git a/SpeckleLib/Speckle/Serialise/JSBase/JSBaseTransport.cpp b/SpeckleLib/Speckle/Serialise/JSBase/JSBaseTransport.cpp index 294a3da..b36d76f 100644 --- a/SpeckleLib/Speckle/Serialise/JSBase/JSBaseTransport.cpp +++ b/SpeckleLib/Speckle/Serialise/JSBase/JSBaseTransport.cpp @@ -397,7 +397,7 @@ namespace { isWrapperTag = !identity.name.empty() && !inventory.begin()->identity().name.empty() && (inventory.begin()->identity() != identity); } auto sequence = inventory.sequence(); - auto container = destination; + auto container{destination}; if (isWrapperTag) { auto containerType = cargo.entryType().value_or((inventory.size() == 1) && !(inventory.begin()->maximum() == 1) ? Entry::Type::array : Entry::Type::element); @@ -411,7 +411,7 @@ namespace { destination = container; } for (auto& entry : sequence) { - auto item = *entry.second; + auto item{*entry.second}; if (!item.required) continue; //Each cargo container may contain multiple export items diff --git a/SpeckleLib/SpeckleLib17.vcxproj b/SpeckleLib/SpeckleLib17.vcxproj index 69e58a9..d07529b 100644 --- a/SpeckleLib/SpeckleLib17.vcxproj +++ b/SpeckleLib/SpeckleLib17.vcxproj @@ -122,6 +122,7 @@ + @@ -162,6 +163,7 @@ + @@ -228,6 +230,7 @@ + @@ -267,6 +270,7 @@ + diff --git a/SpeckleLib/SpeckleLib17.vcxproj.filters b/SpeckleLib/SpeckleLib17.vcxproj.filters index 43351db..e79c0d8 100644 --- a/SpeckleLib/SpeckleLib17.vcxproj.filters +++ b/SpeckleLib/SpeckleLib17.vcxproj.filters @@ -128,6 +128,9 @@ {ccb4ca39-1960-4590-ad5a-8f9092924778} + + {e6e7128b-795b-441c-9ea6-051c99a0343d} + @@ -502,6 +505,12 @@ Speckle\Record\Element\Interface + + Speckle\Record\Attribute + + + Speckle\Record\Filter + @@ -783,6 +792,12 @@ Speckle\Record\Element\Interface + + Speckle\Record\Attribute + + + Speckle\Record\Filter +