Added RecordID to express common ID types for Archicad

Added ArchicadEverythingFilter
Added ArchicadSelectionFilter
Added EverythingSendFilter
Updated SendFilter bridge method with defined filter types
Updated FilterMover with defined filter types
Implemented SendFilter::checkExpiry
Updated CardMover with ReceiverModelCard
Updated all bridge method args as const reference
This commit is contained in:
Ralph Wessel
2024-09-15 22:23:12 +01:00
parent e75ef3133d
commit e92729e10f
37 changed files with 601 additions and 108 deletions
@@ -27,6 +27,8 @@
214B7A372C764BCD00D586C1 /* UpdateConfig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 21F69FBD2C7630B3008B6A06 /* UpdateConfig.cpp */; };
215F082A2C947F4400CD343B /* CardMover.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 215F08262C947F4400CD343B /* CardMover.cpp */; };
215F082E2C94C5C000CD343B /* FilterMover.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 215F082C2C94C5C000CD343B /* FilterMover.cpp */; };
215F08372C95808B00CD343B /* ReceiverModelCard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 215F08362C95808B00CD343B /* ReceiverModelCard.cpp */; };
215F08462C9633A800CD343B /* EverythingSendFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 215F08452C9633A800CD343B /* EverythingSendFilter.cpp */; };
219F30422C769283009834E9 /* ConfigTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 219F30402C769282009834E9 /* ConfigTests.cpp */; };
21B67CA32C769CB400FD64FC /* libActiveLib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 21F69EF52C64FE91008B6A06 /* libActiveLib.a */; };
21B67CA42C769CB400FD64FC /* libArchicad27.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 21F69ECD2C64C035008B6A06 /* libArchicad27.a */; };
@@ -288,6 +290,13 @@
215F08292C947F4400CD343B /* CardMover.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CardMover.h; sourceTree = "<group>"; };
215F082C2C94C5C000CD343B /* FilterMover.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FilterMover.cpp; sourceTree = "<group>"; };
215F082D2C94C5C000CD343B /* FilterMover.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FilterMover.h; sourceTree = "<group>"; };
215F08332C95808B00CD343B /* ReceiverModelCard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReceiverModelCard.h; sourceTree = "<group>"; };
215F08362C95808B00CD343B /* ReceiverModelCard.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReceiverModelCard.cpp; sourceTree = "<group>"; };
215F083D2C96270100CD343B /* RecordID.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RecordID.h; sourceTree = "<group>"; };
215F08412C962F5E00CD343B /* ArchicadSelectionFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArchicadSelectionFilter.h; sourceTree = "<group>"; };
215F08442C9633A800CD343B /* EverythingSendFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EverythingSendFilter.h; sourceTree = "<group>"; };
215F08452C9633A800CD343B /* EverythingSendFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EverythingSendFilter.cpp; sourceTree = "<group>"; };
215F084A2C9782F100CD343B /* ArchicadEverythingFilter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ArchicadEverythingFilter.h; sourceTree = "<group>"; };
2161FD902BF2600C006D9527 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
219388682C4E5DE2002A0180 /* CMakeLists.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
219F30352C768F0A009834E9 /* Connector-AC27-Test.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Connector-AC27-Test.bundle"; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -912,6 +921,14 @@
name = Frameworks;
sourceTree = "<group>";
};
215F083E2C96270100CD343B /* Identity */ = {
isa = PBXGroup;
children = (
215F083D2C96270100CD343B /* RecordID.h */,
);
path = Identity;
sourceTree = "<group>";
};
219F30412C769282009834E9 /* ConnectorTests */ = {
isa = PBXGroup;
children = (
@@ -951,6 +968,7 @@
21B67CCB2C77670400FD64FC /* Database */ = {
isa = PBXGroup;
children = (
215F083E2C96270100CD343B /* Identity */,
21B67CC72C77670400FD64FC /* ModelCardDatabase.cpp */,
21B67CC82C77670400FD64FC /* ModelCardDatabase.h */,
);
@@ -1033,6 +1051,8 @@
21D0BDDF2C9393980077E104 /* Filter */,
21D0BDA72C8F33AC0077E104 /* ModelCard.cpp */,
21D0BDA42C8F33AC0077E104 /* ModelCard.h */,
215F08362C95808B00CD343B /* ReceiverModelCard.cpp */,
215F08332C95808B00CD343B /* ReceiverModelCard.h */,
21D0BDDA2C93897B0077E104 /* SenderModelCard.cpp */,
21D0BDDB2C93897B0077E104 /* SenderModelCard.h */,
);
@@ -1042,8 +1062,12 @@
21D0BDDF2C9393980077E104 /* Filter */ = {
isa = PBXGroup;
children = (
215F084A2C9782F100CD343B /* ArchicadEverythingFilter.h */,
215F08412C962F5E00CD343B /* ArchicadSelectionFilter.h */,
21D0BDE12C943C630077E104 /* DirectSelectionSendFilter.cpp */,
21D0BDE22C943C630077E104 /* DirectSelectionSendFilter.h */,
215F08452C9633A800CD343B /* EverythingSendFilter.cpp */,
215F08442C9633A800CD343B /* EverythingSendFilter.h */,
215F082C2C94C5C000CD343B /* FilterMover.cpp */,
215F082D2C94C5C000CD343B /* FilterMover.h */,
21D0BDDD2C9393980077E104 /* SendFilter.cpp */,
@@ -1371,6 +1395,7 @@
files = (
21D0BDAB2C8F363E0077E104 /* CardSetting.cpp in Sources */,
21B67CE32C78D1FB00FD64FC /* SayHiArg.cpp in Sources */,
215F08462C9633A800CD343B /* EverythingSendFilter.cpp in Sources */,
21F69FBB2C762EF0008B6A06 /* ConfigBridge.cpp in Sources */,
21F69F8A2C70D2C4008B6A06 /* AccountBridge.cpp in Sources */,
21D0BD8E2C8EE4490077E104 /* Send.cpp in Sources */,
@@ -1395,6 +1420,7 @@
21D0BDE02C9393980077E104 /* SendFilter.cpp in Sources */,
21D0BDA82C8F33AC0077E104 /* ModelCard.cpp in Sources */,
215F082A2C947F4400CD343B /* CardMover.cpp in Sources */,
215F08372C95808B00CD343B /* ReceiverModelCard.cpp in Sources */,
21D0BDD72C935DAE0077E104 /* RemoveModel.cpp in Sources */,
21B67CDC2C78C88000FD64FC /* SayHi.cpp in Sources */,
215F082E2C94C5C000CD343B /* FilterMover.cpp in Sources */,
@@ -0,0 +1,16 @@
#ifndef CONNECTOR_DATABASE_ID
#define CONNECTOR_DATABASE_ID
#include "Speckle/Utility/Guid.h"
namespace connector::database {
//BIM element record identifier
using ElementID = speckle::utility::Guid;
//A list of element IDs
using ElementIDList = std::vector<ElementID>;
}
#endif //CONNECTOR_DATABASE_ID
@@ -14,7 +14,7 @@ using namespace speckle::utility;
namespace {
using WrappedValue = active::serialise::CargoHold<ContainerWrap<Vector, Account>, Vector<Account>>;
using WrappedValue = active::serialise::CargoHold<ContainerWrap<Vector<Account>>, Vector<Account>>;
}
@@ -19,7 +19,7 @@ namespace {
/*--------------------------------------------------------------------
Default constructor
--------------------------------------------------------------------*/
AddModel::AddModel() : BridgeMethod{"AddModel", [&](ModelCardEventWrapper card) {
AddModel::AddModel() : BridgeMethod{"AddModel", [&](const ModelCardEventWrapper& card) {
return run(card.get());
}} {}
@@ -29,7 +29,7 @@ AddModel::AddModel() : BridgeMethod{"AddModel", [&](ModelCardEventWrapper card)
card: The card to add
--------------------------------------------------------------------*/
void AddModel::run(ModelCard& card) const {
void AddModel::run(const ModelCard& card) const {
if (auto modelCardDBase = connector()->getModelCardDatabase(); modelCardDBase != nullptr)
modelCardDBase->write(card);
} //AddModel::run
@@ -32,7 +32,7 @@ namespace connector::interfac::browser::bridge {
Add a model card to document storage
@param card The card to add
*/
void run(connector::record::ModelCard& card) const;
void run(const connector::record::ModelCard& card) const;
};
}
@@ -15,7 +15,7 @@ using namespace speckle::utility;
namespace {
using WrappedValue = active::serialise::CargoHold<ContainerWrap<Vector, ModelCard>, Vector<ModelCard>>;
using WrappedValue = active::serialise::CargoHold<ContainerWrap<Vector<ModelCard>>, Vector<ModelCard>>;
}
@@ -20,7 +20,7 @@ namespace {
/*--------------------------------------------------------------------
Default constructor
--------------------------------------------------------------------*/
RemoveModel::RemoveModel() : BridgeMethod{"RemoveModel", [&](ModelCardEventWrapper card) {
RemoveModel::RemoveModel() : BridgeMethod{"RemoveModel", [&](const ModelCardEventWrapper& card) {
return run(card.get());
}} {}
@@ -30,7 +30,7 @@ RemoveModel::RemoveModel() : BridgeMethod{"RemoveModel", [&](ModelCardEventWrapp
card: The card to add
--------------------------------------------------------------------*/
void RemoveModel::run(ModelCard& card) const {
void RemoveModel::run(const ModelCard& card) const {
if (auto modelCardDBase = connector()->getModelCardDatabase(); modelCardDBase != nullptr)
modelCardDBase->erase(card.getID());
} //RemoveModel::run
@@ -32,7 +32,7 @@ namespace connector::interfac::browser::bridge {
Add a model card to document storage
@param card The card to add
*/
void run(connector::record::ModelCard& card) const;
void run(const connector::record::ModelCard& card) const;
};
}
@@ -20,7 +20,7 @@ namespace {
/*--------------------------------------------------------------------
Default constructor
--------------------------------------------------------------------*/
UpdateModel::UpdateModel() : BridgeMethod{"UpdateModel", [&](ModelCardEventWrapper card) {
UpdateModel::UpdateModel() : BridgeMethod{"UpdateModel", [&](const ModelCardEventWrapper& card) {
return run(card.get());
}} {}
@@ -30,7 +30,7 @@ UpdateModel::UpdateModel() : BridgeMethod{"UpdateModel", [&](ModelCardEventWrapp
card: The card to add
--------------------------------------------------------------------*/
void UpdateModel::run(ModelCard& card) const {
void UpdateModel::run(const ModelCard& card) const {
if (auto modelCardDBase = connector()->getModelCardDatabase(); modelCardDBase != nullptr)
modelCardDBase->write(card);
} //UpdateModel::run
@@ -32,7 +32,7 @@ namespace connector::interfac::browser::bridge {
Add a model card to document storage
@param card The card to add
*/
void run(connector::record::ModelCard& card) const;
void run(const connector::record::ModelCard& card) const;
};
}
@@ -10,7 +10,7 @@ using namespace speckle::utility;
/*--------------------------------------------------------------------
Default constructor
--------------------------------------------------------------------*/
UpdateConfig::UpdateConfig() : BridgeMethod{"UpdateConfig", [&](UpdateArgs args) {
UpdateConfig::UpdateConfig() : BridgeMethod{"UpdateConfig", [&](const UpdateArgs& args) {
run(args);
}} {}
@@ -4,7 +4,8 @@
#include "Active/Serialise/CargoHold.h"
#include "Active/Serialise/Package/Wrapper/ContainerWrap.h"
#include "Active/Serialise/Package/Wrapper/PackageWrap.h"
#include "Connector/Record/Model/Filter/SendFilter.h"
#include "Connector/Record/Model/Filter/ArchicadEverythingFilter.h"
#include "Connector/Record/Model/Filter/ArchicadSelectionFilter.h"
using namespace active::container;
using namespace active::serialise;
@@ -14,7 +15,7 @@ using namespace speckle::utility;
namespace {
using WrappedValue = active::serialise::CargoHold<ContainerWrap<Vector, SendFilter>, Vector<SendFilter>>;
using WrappedValue = active::serialise::CargoHold<ContainerWrap<Vector<SendFilter>>, Vector<SendFilter>>;
}
@@ -33,6 +34,7 @@ GetSendFilters::GetSendFilters() : BridgeMethod{"GetSendFilters", [&]() {
--------------------------------------------------------------------*/
std::unique_ptr<Cargo> GetSendFilters::run() const {
Vector<SendFilter> filters;
///TODO: Get real filters
filters.emplace_back(ArchicadEverythingFilter{});
filters.emplace_back(ArchicadSelectionFilter{});
return std::make_unique<WrappedValue>(filters);
} //GetSendFilters::run
@@ -85,7 +85,7 @@ namespace {
/*--------------------------------------------------------------------
Default constructor
--------------------------------------------------------------------*/
TriggerEvent::TriggerEvent() : BridgeMethod{"TriggerEvent", [&](TriggerEventWrapper arg) {
TriggerEvent::TriggerEvent() : BridgeMethod{"TriggerEvent", [&](const TriggerEventWrapper& arg) {
return run(arg);
}} {}
@@ -95,7 +95,7 @@ TriggerEvent::TriggerEvent() : BridgeMethod{"TriggerEvent", [&](TriggerEventWrap
eventName: The event name
--------------------------------------------------------------------*/
void TriggerEvent::run(speckle::utility::String eventName) const {
void TriggerEvent::run(const speckle::utility::String& eventName) const {
if (!hasBridge())
return;
if (eventName == "emptyTestEvent")
@@ -31,7 +31,7 @@ namespace connector::interfac::browser::bridge {
Trigger an event based on a specified name
@param eventName The event name
*/
void run(speckle::utility::String eventName) const;
void run(const speckle::utility::String& eventName) const;
};
}
@@ -5,6 +5,7 @@ Distributed under the MIT License (See accompanying file LICENSE.txt or copy at
#include "Connector/Record/Model/CardMover.h"
#include "Connector/Record/Model/ReceiverModelCard.h"
#include "Connector/Record/Model/SenderModelCard.h"
using namespace active::serialise;
@@ -15,10 +16,10 @@ namespace {
///The tag used to identify a Speckle type name value
const char* attributeTag = "typeDiscriminator";
///Identity for a SenderModelCard
const char* senderCardTypeName = "SenderModelCard";
///Identity for a ReceiverModelCard
const char* receiverCardTypeName = "ReceiverModelCard";
///Identity for a SenderModelCard
const char* senderCardTypeName = "SenderModelCard";
}
@@ -52,5 +53,6 @@ CardMover::CardMover(const active::serialise::Package& outgoing) : Mover{outgoin
void CardMover::validateHandler() {
if (!m_handler->empty())
return;
m_handler->add<ReceiverModelCard>(receiverCardTypeName);
m_handler->add<SenderModelCard>(senderCardTypeName);
} //CardMover::validateHandler
@@ -6,7 +6,7 @@
namespace connector::record {
/*!
Wrapper to box/unbox objects during (de)serialisation, reading/writing a specified attribute to determine object type
Wrapper to box/unbox objects during (de)serialisation, including reading/writing a specified attribute to determine object type
Note that a derived class could also define the package handler, allowing the wrapper to be created via a default constructor that is
automatically bound to a set of internally defined object types
@@ -2,6 +2,7 @@
#include "Active/Serialise/Item/Wrapper/ValueWrap.h"
#include "Active/Serialise/Item/Wrapper/AnyValueWrap.h"
#include "Active/Serialise/Package/Wrapper/ContainerWrap.h"
#include <array>
@@ -74,7 +75,7 @@ Cargo::Unique CardSetting::getCargo(const Inventory::Item& item) const {
case valueID:
return std::make_unique<AnyValueWrap>(*m_value);
case enumID:
return std::make_unique<ValueWrap<String>>(m_type);
return std::make_unique<ContainerWrap<std::vector<speckle::utility::String>>>(m_enum);
default:
return nullptr; //Requested an unknown index
}
@@ -0,0 +1,38 @@
#ifndef CONNECTOR_RECORD_ARCHICAD_EVERYTHING_FILTER
#define CONNECTOR_RECORD_ARCHICAD_EVERYTHING_FILTER
#include "Connector/Database/Identity/RecordID.h"
#include "Connector/Record/Model/Filter/EverythingSendFilter.h"
namespace connector::record {
/*!
A send filter consisting of a list of selected Archicad element IDs
*/
class ArchicadEverythingFilter : public EverythingSendFilter {
public:
// MARK: - Types
using base = EverythingSendFilter;
// MARK: - Constructors
/*!
Default constructor
@param sum A summary
@param isDef True if this is the default filter
*/
ArchicadEverythingFilter(const speckle::utility::String& sum = {}, bool isDef = false) : base{sum, isDef} {}
/*!
Record cloning
@return A clone of this record
*/
ArchicadEverythingFilter* clonePtr() const override { return new ArchicadEverythingFilter(*this); };
// MARK: - Functions (const)
};
}
#endif //CONNECTOR_RECORD_ARCHICAD_EVERYTHING_FILTER
@@ -0,0 +1,38 @@
#ifndef CONNECTOR_RECORD_ARCHICAD_SELECTION_FILTER
#define CONNECTOR_RECORD_ARCHICAD_SELECTION_FILTER
#include "Connector/Database/Identity/RecordID.h"
#include "Connector/Record/Model/Filter/DirectSelectionSendFilter.h"
namespace connector::record {
/*!
A send filter consisting of a list of selected Archicad element IDs
*/
class ArchicadSelectionFilter : public DirectSelectionSendFilter {
public:
// MARK: - Types
using base = DirectSelectionSendFilter;
// MARK: - Constructors
/*!
Default constructor
@param sum A summary
@param isDef True if this is the default filter
*/
ArchicadSelectionFilter(const speckle::utility::String& sum = {}, bool isDef = false) : base{sum, isDef} {}
/*!
Record cloning
@return A clone of this record
*/
ArchicadSelectionFilter* clonePtr() const override { return new ArchicadSelectionFilter(*this); };
// MARK: - Functions (const)
};
}
#endif //CONNECTOR_RECORD_ARCHICAD_SELECTION_FILTER
@@ -1,10 +1,13 @@
#include "Connector/Record/Model/Filter/DirectSelectionSendFilter.h"
#include "Active/Serialise/Item/Wrapper/ValueWrap.h"
#include "Active/Serialise/Package/Wrapper/ContainerWrap.h"
#include <algorithm>
#include <array>
using namespace active::serialise;
using namespace connector::database;
using namespace connector::record;
using namespace speckle::utility;
@@ -12,16 +15,12 @@ namespace {
///Serialisation fields
enum FieldIndex {
nameID,
summaryID,
defaultID,
selectedElemID,
};
///Serialisation field IDs
static std::array fieldID = {
Identity{"name"},
Identity{"summary"},
Identity{"isDefault"},
Identity{"selectedObjectIds"},
};
}
@@ -37,12 +36,10 @@ bool DirectSelectionSendFilter::fillInventory(Inventory& inventory) const {
using enum Entry::Type;
inventory.merge(Inventory{
{
{ fieldID[nameID], nameID, element },
{ fieldID[summaryID], summaryID, element },
{ fieldID[defaultID], defaultID, element },
{ fieldID[selectedElemID], selectedElemID, element },
},
}.withType(&typeid(DirectSelectionSendFilter)));
return true;
return base::fillInventory(inventory);
} //DirectSelectionSendFilter::fillInventory
@@ -55,15 +52,11 @@ bool DirectSelectionSendFilter::fillInventory(Inventory& inventory) const {
--------------------------------------------------------------------*/
Cargo::Unique DirectSelectionSendFilter::getCargo(const Inventory::Item& item) const {
if (item.ownerType != &typeid(DirectSelectionSendFilter))
return nullptr;
return base::getCargo(item);
using namespace active::serialise;
switch (item.index) {
case nameID:
return std::make_unique<ValueWrap<String>>(m_name);
case summaryID:
return std::make_unique<ValueWrap<String>>(m_summary);
case defaultID:
return std::make_unique<ValueWrap<bool>>(m_isDefault);
case selectedElemID:
return std::make_unique<ContainerWrap<ElementIDList>>(m_selectedElements);
default:
return nullptr; //Requested an unknown index
}
@@ -74,7 +67,5 @@ Cargo::Unique DirectSelectionSendFilter::getCargo(const Inventory::Item& item) c
Set to the default package content
--------------------------------------------------------------------*/
void DirectSelectionSendFilter::setDefault() {
m_name.clear();
m_summary.clear();
m_isDefault = false;
m_selectedElements.clear();
} //DirectSelectionSendFilter::setDefault
@@ -1,59 +1,42 @@
#ifndef CONNECTOR_RECORD_DIRECT_SELECT_SEND_FILTER
#define CONNECTOR_RECORD_DIRECT_SELECT_SEND_FILTER
#include "Active/Serialise/Package/Package.h"
#include "Active/Utility/Cloner.h"
#include "Speckle/Utility/String.h"
#include "Connector/Database/Identity/RecordID.h"
#include "Connector/Record/Model/Filter/SendFilter.h"
namespace connector::record {
/*!
Base class for element filters applied when a model is sent to a Speckle server
A send filter consisting of a list of selected element IDs
*/
class DirectSelectionSendFilter : public active::serialise::Package, public active::utility::Cloner {
class DirectSelectionSendFilter : public SendFilter {
public:
// MARK: - Types
using base = active::serialise::Package;
using base = SendFilter;
// MARK: - Constructors
/*!
Default constructor
@param nm The filter name
@param sum A summary
@param isDef True if this is the default filter
*/
DirectSelectionSendFilter(const speckle::utility::String& nm = {}, const speckle::utility::String& sum = {}, bool isDef = false) :
m_name{nm}, m_summary{sum}, m_isDefault{isDef} {}
/*!
Destructor
*/
virtual ~DirectSelectionSendFilter() {}
DirectSelectionSendFilter(const speckle::utility::String& sum = {}, bool isDef = false) : base{"Selection", sum, isDef} {}
/*!
Record cloning
@return A clone of this record
*/
virtual DirectSelectionSendFilter* clonePtr() const override { return new DirectSelectionSendFilter(*this); };
DirectSelectionSendFilter* clonePtr() const override { return new DirectSelectionSendFilter(*this); };
// MARK: - Functions (const)
/*!
Get the filter name
@return The filter name
*/
const speckle::utility::String& getName() const { return m_name; };
/*!
Get a summary description of the filter function, e.g. "All selected elements"
@return The filter summary description
*/
const speckle::utility::String& getSummary() const { return m_name; };
/*!
Determine if this is the default filter for model sends
@return True if this is the default filter
*/
bool isDefault() const { return m_isDefault; };
Get the filtered element IDs
@return The filter elements
*/
const database::ElementIDList& getElementIDs() const override { return m_selectedElements; }
// MARK: - Serialisation
@@ -75,12 +58,8 @@ namespace connector::record {
void setDefault() override;
private:
///The filter name
speckle::utility::String m_name;
///A summary
speckle::utility::String m_summary;
///True if this is the default filter
bool m_isDefault = false;
///A list of selected element IDs
database::ElementIDList m_selectedElements;
};
}
@@ -0,0 +1,71 @@
#include "Connector/Record/Model/Filter/EverythingSendFilter.h"
#include "Active/Serialise/Item/Wrapper/ValueWrap.h"
#include "Active/Serialise/Package/Wrapper/ContainerWrap.h"
#include <algorithm>
#include <array>
using namespace active::serialise;
using namespace connector::database;
using namespace connector::record;
using namespace speckle::utility;
namespace {
///Serialisation fields
enum FieldIndex {
selectedElemID,
};
///Serialisation field IDs
static std::array fieldID = {
Identity{"selectedObjectIds"},
};
}
/*--------------------------------------------------------------------
Fill an inventory with the package items
inventory: The inventory to receive the package items
return: True if the package has added items to the inventory
--------------------------------------------------------------------*/
bool EverythingSendFilter::fillInventory(Inventory& inventory) const {
using enum Entry::Type;
inventory.merge(Inventory{
{
{ fieldID[selectedElemID], selectedElemID, element },
},
}.withType(&typeid(EverythingSendFilter)));
return base::fillInventory(inventory);
} //EverythingSendFilter::fillInventory
/*--------------------------------------------------------------------
Get the specified cargo
item: The inventory item to retrieve
return: The requested cargo (nullptr on failure)
--------------------------------------------------------------------*/
Cargo::Unique EverythingSendFilter::getCargo(const Inventory::Item& item) const {
if (item.ownerType != &typeid(EverythingSendFilter))
return base::getCargo(item);
using namespace active::serialise;
switch (item.index) {
case selectedElemID:
return std::make_unique<ContainerWrap<ElementIDList>>(m_emptyList);
default:
return nullptr; //Requested an unknown index
}
} //EverythingSendFilter::getCargo
/*--------------------------------------------------------------------
Set to the default package content
--------------------------------------------------------------------*/
void EverythingSendFilter::setDefault() {
m_emptyList.clear();
} //EverythingSendFilter::setDefault
@@ -0,0 +1,73 @@
#ifndef CONNECTOR_RECORD_EVERYTHING_SEND_FILTER
#define CONNECTOR_RECORD_EVERYTHING_SEND_FILTER
#include "Connector/Database/Identity/RecordID.h"
#include "Connector/Record/Model/Filter/SendFilter.h"
namespace connector::record {
/*!
A send filter consisting of a list of selected element IDs
*/
class EverythingSendFilter : public SendFilter {
public:
// MARK: - Types
using base = SendFilter;
// MARK: - Constructors
/*!
Default constructor
@param sum A summary
@param isDef True if this is the default filter
*/
EverythingSendFilter(const speckle::utility::String& sum = {}, bool isDef = false) : base{"Everything", sum, isDef} {}
/*!
Record cloning
@return A clone of this record
*/
EverythingSendFilter* clonePtr() const override { return new EverythingSendFilter(*this); };
// MARK: - Functions (const)
/*!
Get the filtered element IDs
@return The filter elements
*/
const database::ElementIDList& getElementIDs() const override { return m_emptyList; }
/*!
Determine if the filter has expired because an element in the selection has changed
@param changed The list of changed element IDs
@return True if the one of the changed elements is in the selection
*/
virtual bool checkExpiry(const database::ElementIDList& changed) const override { return true; }
// MARK: - Serialisation
/*!
Fill an inventory with the package items
@param inventory The inventory to receive the package items
@return True if the package has added items to the inventory
*/
bool fillInventory(active::serialise::Inventory& inventory) const override;
/*!
Get the specified cargo
@param item The inventory item to retrieve
@return The requested cargo (nullptr on failure)
*/
Cargo::Unique getCargo(const active::serialise::Inventory::Item& item) const override;
/*!
Set to the default package content
*/
void setDefault() override;
private:
///Enables a const empty list to be returned
database::ElementIDList m_emptyList;
};
}
#endif //CONNECTOR_RECORD_EVERYTHING_SEND_FILTER
@@ -5,7 +5,8 @@ Distributed under the MIT License (See accompanying file LICENSE.txt or copy at
#include "Connector/Record/Model/Filter/FilterMover.h"
#include "Connector/Record/Model/Filter/DirectSelectionSendFilter.h"
#include "Connector/Record/Model/Filter/ArchicadEverythingFilter.h"
#include "Connector/Record/Model/Filter/ArchicadSelectionFilter.h"
using namespace active::serialise;
using namespace active::utility;
@@ -16,8 +17,10 @@ namespace {
///The tag used to identify a Speckle type name value
const char* attributeTag = "typeDiscriminator";
///Identity for a SenderModelCard
const char* DirectSelectionTypeName = "DirectSelectionSendFilter";
const char* ArchicadSelectionTypeName = "ArchicadSelectionFilter";
///Identity for a SenderModelCard
const char* ArchicadEverythingTypeName = "ArchicadEverythingFilter";
}
///The handler for model card packages
@@ -60,5 +63,6 @@ FilterMover::FilterMover(active::serialise::PackageUniqueWrap&& package) : Mover
void FilterMover::validateHandler() {
if (!m_handler->empty())
return;
m_handler->add<DirectSelectionSendFilter>(DirectSelectionTypeName);
m_handler->add<ArchicadEverythingFilter>(ArchicadEverythingTypeName);
m_handler->add<DirectSelectionSendFilter>(ArchicadSelectionTypeName);
} //FilterMover::validateHandler
@@ -6,7 +6,7 @@
namespace connector::record {
/*!
Wrapper to box/unbox objects during (de)serialisation, reading/writing a specified attribute to determine object type
Wrapper to box/unbox objects during (de)serialisation, including reading/writing a specified attribute to determine object type
Note that a derived class could also define the package handler, allowing the wrapper to be created via a default constructor that is
automatically bound to a set of internally defined object types
@@ -5,6 +5,7 @@
#include <array>
using namespace active::serialise;
using namespace connector::database;
using namespace connector::record;
using namespace speckle::utility;
@@ -26,6 +27,23 @@ namespace {
}
/*--------------------------------------------------------------------
Determine if the filter has expired because an element in the selection has changed
changed: The list of changed element IDs
return: True if the one of the changed elements is in the selection
--------------------------------------------------------------------*/
bool SendFilter::checkExpiry(const ElementIDList& changed) const {
ElementIDList intersect;
ElementIDList mine{getElementIDs()}, theirs{changed};
std::sort(mine.begin(), mine.end());
std::sort(theirs.begin(), theirs.end());
std::set_intersection (mine.begin(), mine.end(), theirs.begin(), theirs.end(), std::back_inserter(intersect));
return !intersect.empty();
} //SendFilter::checkExpiry
/*--------------------------------------------------------------------
Fill an inventory with the package items
@@ -3,6 +3,7 @@
#include "Active/Serialise/Package/Package.h"
#include "Active/Utility/Cloner.h"
#include "Connector/Database/Identity/RecordID.h"
#include "Speckle/Utility/String.h"
namespace connector::record {
@@ -32,45 +33,56 @@ namespace connector::record {
*/
virtual ~SendFilter() {}
/*!
Record cloning
@return A clone of this record
Object cloning
@return A clone of this object
*/
virtual SendFilter* clonePtr() const override { return new SendFilter(*this); };
virtual SendFilter* clonePtr() const override = 0;
// MARK: - Functions (const)
/*!
Get the filter name
@return The filter name
Get the filter name
@return The filter name
*/
const speckle::utility::String& getName() const { return m_name; };
/*!
Get a summary description of the filter function, e.g. "All selected elements"
@return The filter summary description
Get a summary description of the filter function, e.g. "All selected elements"
@return The filter summary description
*/
const speckle::utility::String& getSummary() const { return m_name; };
/*!
Determine if this is the default filter for model sends
@return True if this is the default filter
Determine if this is the default filter for model sends
@return True if this is the default filter
*/
bool isDefault() const { return m_isDefault; };
/*!
Get the filtered element IDs
@return The filter elements
*/
virtual const database::ElementIDList& getElementIDs() const = 0;
/*!
Determine if the filter has expired because an element in the selection has changed
@param changed The list of changed element IDs
@return True if the one of the changed elements is in the selection
*/
virtual bool checkExpiry(const database::ElementIDList& changed) const;
// MARK: - Serialisation
/*!
Fill an inventory with the package items
@param inventory The inventory to receive the package items
@return True if the package has added items to the inventory
Fill an inventory with the package items
@param inventory The inventory to receive the package items
@return True if the package has added items to the inventory
*/
bool fillInventory(active::serialise::Inventory& inventory) const override;
/*!
Get the specified cargo
@param item The inventory item to retrieve
@return The requested cargo (nullptr on failure)
Get the specified cargo
@param item The inventory item to retrieve
@return The requested cargo (nullptr on failure)
*/
Cargo::Unique getCargo(const active::serialise::Inventory::Item& item) const override;
/*!
Set to the default package content
Set to the default package content
*/
void setDefault() override;
@@ -75,7 +75,7 @@ Cargo::Unique ModelCard::getCargo(const Inventory::Item& item) const {
case serverURLID:
return std::make_unique<ValueWrap<String>>(m_serverURL);
case settingsID:
return std::make_unique<ContainerWrap<Vector, CardSetting>>(m_settings);
return std::make_unique<ContainerWrap<Vector<CardSetting>>>(m_settings);
default:
return nullptr; //Requested an unknown index
}
@@ -87,11 +87,11 @@ namespace connector::record {
private:
///The model ID
speckle::utility::String m_modelID;
speckle::database::RecordID m_modelID;
///The project ID
speckle::utility::String m_projectID;
speckle::database::RecordID m_projectID;
///The user account ID
speckle::utility::String m_accountID;
speckle::database::RecordID m_accountID;
///The server URL
speckle::utility::String m_serverURL;
///Settings for the model rendering, e.g. level of detail (LoD)
@@ -0,0 +1,102 @@
#include "Connector/Record/Model/ReceiverModelCard.h"
#include "Active/Serialise/Item/Wrapper/ValueWrap.h"
#include "Active/Serialise/Package/Wrapper/ContainerWrap.h"
#include <array>
using namespace active::serialise;
using namespace connector::database;
using namespace connector::record;
using namespace speckle::database;
using namespace speckle::utility;
namespace {
///Serialisation fields
enum FieldIndex {
projectNameID,
modelNameID,
selectedVersionID,
latestVersionID,
warningDismissedID,
bakedObjectsID,
};
///Serialisation field IDs
static std::array fieldID = {
Identity{"projectName"},
Identity{"modelName"},
Identity{"selectedVersionID"},
Identity{"latestVersionID"},
Identity{"hasDismissedUpdateWarning"},
Identity{"bakedObjectIds"},
};
}
/*--------------------------------------------------------------------
Fill an inventory with the package items
inventory: The inventory to receive the package items
return: True if the package has added items to the inventory
--------------------------------------------------------------------*/
bool ReceiverModelCard::fillInventory(Inventory& inventory) const {
using enum Entry::Type;
inventory.merge(Inventory{
{
{ fieldID[projectNameID], projectNameID, element },
{ fieldID[modelNameID], modelNameID, element },
{ fieldID[selectedVersionID], selectedVersionID, element },
{ fieldID[latestVersionID], latestVersionID, element },
{ fieldID[warningDismissedID], warningDismissedID, element },
{ fieldID[bakedObjectsID], bakedObjectsID, element },
},
}.withType(&typeid(ReceiverModelCard)));
return base::fillInventory(inventory);
} //ReceiverModelCard::fillInventory
/*--------------------------------------------------------------------
Get the specified cargo
item: The inventory item to retrieve
return: The requested cargo (nullptr on failure)
--------------------------------------------------------------------*/
Cargo::Unique ReceiverModelCard::getCargo(const Inventory::Item& item) const {
if (item.ownerType != &typeid(ReceiverModelCard))
return base::getCargo(item);
using namespace active::serialise;
switch (item.index) {
case projectNameID:
return std::make_unique<StringWrap>(m_projectName);
case modelNameID:
return std::make_unique<StringWrap>(m_modelName);
case selectedVersionID:
return std::make_unique<ValueWrap<RecordID>>(m_selectedVersionID);
case latestVersionID:
return std::make_unique<ValueWrap<RecordID>>(m_latestVersionID);
case warningDismissedID:
return std::make_unique<BoolWrap>(m_hasDismissedUpdateWarning);
case bakedObjectsID:
return std::make_unique<ContainerWrap<ElementIDList>>(m_bakedObjectIDs);
default:
return nullptr; //Requested an unknown index
}
} //ReceiverModelCard::getCargo
/*--------------------------------------------------------------------
Set to the default package content
--------------------------------------------------------------------*/
void ReceiverModelCard::setDefault() {
base::setDefault();
m_projectName.clear();
m_modelName.clear();
m_selectedVersionID.clear();
m_latestVersionID.clear();
m_hasDismissedUpdateWarning = false;
m_bakedObjectIDs.clear();
} //ReceiverModelCard::setDefault
@@ -0,0 +1,116 @@
#ifndef CONNECTOR_RECORD_RECEIVER_MODEL_CARD
#define CONNECTOR_RECORD_RECEIVER_MODEL_CARD
#include "Connector/Database/Identity/RecordID.h"
#include "Connector/Record/Model/ModelCard.h"
namespace connector::record {
class SendFilter;
/*!
A connector model send card - carries information about what was sent with the model
*/
class ReceiverModelCard : public connector::record::ModelCard {
public:
// MARK: - Types
using base = connector::record::ModelCard;
// MARK: - Constructors
/*!
Default constructor
*/
ReceiverModelCard() {}
/*!
Constructor
@param projectName The project name
@param modelName The model name
@param selectedVersion The selected version ID
@param latestVersion The latest version ID
@param hasDimissedWarning True if the user has already dismissed an alert to update
@param bakedObjects The IDs of objects accepted in the receive
*/
ReceiverModelCard(const speckle::utility::String& projectName, const speckle::utility::String& modelName,
const speckle::database::RecordID& selectedVersion, const speckle::database::RecordID& latestVersion,
bool hasDimissedWarning, database::ElementIDList&& bakedObjects) :
m_projectName{projectName}, m_modelName{modelName}, m_selectedVersionID{selectedVersion}, m_latestVersionID{latestVersion},
m_hasDismissedUpdateWarning{hasDimissedWarning}, m_bakedObjectIDs{bakedObjects} {}
/*!
Record cloning
@return A clone of this record
*/
virtual ReceiverModelCard* clonePtr() const override { return new ReceiverModelCard(*this); };
// MARK: - Functions (const)
/*!
Get the project name
@return The project name
*/
const speckle::utility::String& getProjectName() const { return m_projectName; }
/*!
Get the model name
@return The model name
*/
const speckle::utility::String& getModelName() const { return m_modelName; }
/*!
Get the selected version ID
@return The selected version ID
*/
const speckle::database::RecordID& getSelectedVersionID() const { return m_selectedVersionID; }
/*!
Get the latest version ID
@return The latest version ID
*/
const speckle::database::RecordID& getLatestVersionID() const { return m_latestVersionID; }
/*!
Determine if the user has already dismissed an alert to update
@return True if the user has already dismissed an alert to update
*/
bool hasDismissedUpdateWarning() const { return m_hasDismissedUpdateWarning; }
/*!
Get the IDs of objects accepted in the receive
@return The accepted object IDs
*/
const database::ElementIDList& getBakedObjectIDs() const { return m_bakedObjectIDs; }
// MARK: - Serialisation
/*!
Fill an inventory with the package items
@param inventory The inventory to receive the package items
@return True if the package has added items to the inventory
*/
bool fillInventory(active::serialise::Inventory& inventory) const override;
/*!
Get the specified cargo
@param item The inventory item to retrieve
@return The requested cargo (nullptr on failure)
*/
Cargo::Unique getCargo(const active::serialise::Inventory::Item& item) const override;
/*!
Set to the default package content
*/
void setDefault() override;
private:
///The received project name
speckle::utility::String m_projectName;
///The received model name
speckle::utility::String m_modelName;
///The ID of the version selected in the receive
speckle::database::RecordID m_selectedVersionID;
///The ID of the latest version
speckle::database::RecordID m_latestVersionID;
///True if the user has already dismissed an alert to update
bool m_hasDismissedUpdateWarning = false;
///IDs of objects accepted in the receive
database::ElementIDList m_bakedObjectIDs;
};
}
#endif //CONNECTOR_RECORD_RECEIVER_MODEL_CARD
@@ -1,6 +1,5 @@
#include "Connector/Record/Model/SenderModelCard.h"
#include "Active/Serialise/Package/Wrapper/PackageWrap.h"
#include "Active/Serialise/Package/Wrapper/PackageUniqueWrap.h"
#include "Connector/Record/Model/Filter/FilterMover.h"
#include "Connector/Record/Model/Filter/SendFilter.h"
@@ -5,10 +5,16 @@
namespace speckle::database {
//Common Speckle record identifier type
using RecordID = speckle::utility::String;
//Common Speckle table identifier type
using TableID = speckle::utility::String;
//Common Speckle database identifier type
using DBaseID = speckle::utility::String;
//A list of record IDs
using RecordIDList = std::vector<RecordID>;
}
#endif //SPECKLE_DATABASE_ID
@@ -6,7 +6,6 @@
#include "Active/Database/Storage/RecordCache.h"
#include "Active/File/Path.h"
#include "Active/Serialise/Cargo.h"
#include "Active/Serialise/CargoHold.h"
#include "Active/Serialise/Package/Wrapper/PackageWrap.h"
#include "Active/Serialise/Transport.h"
#include "Active/Utility/BufferIn.h"
@@ -21,7 +21,7 @@ using namespace speckle::utility;
/*--------------------------------------------------------------------
Constructor
--------------------------------------------------------------------*/
GetCallResult::GetCallResult() : JSFunction{"GetCallResult", [&](auto args) {
GetCallResult::GetCallResult() : JSFunction{"GetCallResult", [&](const auto& args) {
return getResult(args);
}} {
} //GetCallResult::GetCallResult
@@ -34,7 +34,7 @@ GetCallResult::GetCallResult() : JSFunction{"GetCallResult", [&](auto args) {
return: The requested result (nullptr on failure)
--------------------------------------------------------------------*/
std::unique_ptr<WrappedResultArg> GetCallResult::getResult(WrappedResultArg& argument) const {
std::unique_ptr<WrappedResultArg> GetCallResult::getResult(const WrappedResultArg& argument) const {
if (!hasBridge())
return nullptr;
//Retrieve the requested result
@@ -34,7 +34,7 @@ namespace speckle::interfac::browser::bridge {
@param argument The method arguments specifying the target bridge and requestID
@return The requested result (nullptr on failure)
*/
std::unique_ptr<WrappedResultArg> getResult(WrappedResultArg& argument) const;
std::unique_ptr<WrappedResultArg> getResult(const WrappedResultArg& argument) const;
};
}
@@ -20,7 +20,7 @@ namespace speckle::interfac::browser {
struct FuncBase {};
template<typename Argument, typename Return>
struct FuncTypedef {
typedef std::function<std::unique_ptr<Return>(Argument)> type;
typedef std::function<std::unique_ptr<Return>(const Argument&)> type;
};
template<typename Return>
struct FuncTypedef<void, Return> {
@@ -28,7 +28,7 @@ namespace speckle::interfac::browser {
};
template<typename Argument>
struct FuncTypedef<Argument, void> {
typedef std::function<void(Argument)> type;
typedef std::function<void(const Argument&)> type;
};
template<>
struct FuncTypedef<void, void> {