Updated JSBridgeArgument to receive args as a JS array rather than an object
This commit is contained in:
@@ -20,17 +20,22 @@ namespace {
|
||||
|
||||
///The indices of the package items
|
||||
enum FieldIndex {
|
||||
args,
|
||||
};
|
||||
|
||||
|
||||
///The indices of the arguments array rows
|
||||
enum RowIndex {
|
||||
objectName,
|
||||
methodName,
|
||||
requestID,
|
||||
};
|
||||
|
||||
|
||||
///The package inventory
|
||||
auto myInventory = Inventory {
|
||||
{
|
||||
{ {"binding_name"}, objectName, attribute },
|
||||
{ {"name"}, methodName, attribute },
|
||||
{ {"request_id"}, requestID, attribute },
|
||||
{ {"arg"}, args, array }, //The JS arguments are expressed as a flat array - use the array indices to map to expected vars
|
||||
},
|
||||
}.withType(&typeid(JSBridgeArgumentWrap));;
|
||||
|
||||
@@ -50,11 +55,8 @@ JSBridgeArgumentWrap::~JSBridgeArgumentWrap() {
|
||||
|
||||
return: True if items have been added to the inventory
|
||||
--------------------------------------------------------------------*/
|
||||
bool JSBridgeArgumentWrap::fillInventory(active::serialise::Inventory& inventory) const {
|
||||
if (!m_isReadingAttributes.has_value() || *m_isReadingAttributes)
|
||||
inventory.merge(myInventory);
|
||||
if (m_argument)
|
||||
m_argument->fillInventory(inventory);
|
||||
bool JSBridgeArgumentWrap::fillInventory(Inventory& inventory) const {
|
||||
inventory.merge(myInventory);
|
||||
return true;
|
||||
} //JSBridgeArgumentWrap::fillInventory
|
||||
|
||||
@@ -66,16 +68,28 @@ bool JSBridgeArgumentWrap::fillInventory(active::serialise::Inventory& inventory
|
||||
|
||||
return: The requested cargo (nullptr on failure)
|
||||
--------------------------------------------------------------------*/
|
||||
Cargo::Unique JSBridgeArgumentWrap::getCargo(const active::serialise::Inventory::Item& item) const {
|
||||
Cargo::Unique JSBridgeArgumentWrap::getCargo(const Inventory::Item& item) const {
|
||||
if (item.ownerType != &typeid(JSBridgeArgumentWrap))
|
||||
return nullptr;
|
||||
switch (item.index) {
|
||||
case FieldIndex::objectName:
|
||||
return std::make_unique<ValueWrap<String>>(m_objectName);
|
||||
case FieldIndex::methodName:
|
||||
return std::make_unique<ValueWrap<String>>(m_methodName);
|
||||
case FieldIndex::requestID:
|
||||
return std::make_unique<ValueWrap<String>>(m_requestID);
|
||||
case FieldIndex::args: {
|
||||
switch (item.available) { //NB: Args are not labelled - in this instance we use the array row index to couple to an argument var
|
||||
case RowIndex::objectName:
|
||||
return std::make_unique<ValueWrap<String>>(m_objectName);
|
||||
case RowIndex::methodName:
|
||||
return std::make_unique<ValueWrap<String>>(m_methodName);
|
||||
case RowIndex::requestID:
|
||||
return std::make_unique<ValueWrap<String>>(m_requestID);
|
||||
default:
|
||||
//Once the argument attributes have been obtained (object, method etc) we need to ensure the argument object exists
|
||||
if (!m_argument)
|
||||
finaliseArgument();
|
||||
Inventory::Item childItem{item};
|
||||
//The index of the child item starts at zero, so deduct the indices already received by the wrapper
|
||||
childItem.available -= (RowIndex::requestID + 1);
|
||||
return m_argument->getCargo(childItem);
|
||||
}
|
||||
}
|
||||
default:
|
||||
return nullptr; //Requested an unknown index
|
||||
}
|
||||
@@ -99,23 +113,18 @@ void JSBridgeArgumentWrap::setDefault() {
|
||||
return: True if the data has been validated
|
||||
--------------------------------------------------------------------*/
|
||||
bool JSBridgeArgumentWrap::validate() {
|
||||
return !m_objectName.empty() && !m_methodName.empty() && !m_requestID.empty() && (!m_argument | m_argument->validate());
|
||||
//Only successful if we built an argument object and its content is valid
|
||||
return !m_argument && m_argument->validate();
|
||||
} //JSBridgeArgumentWrap::validate
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
Finalise the package attributes (called when isAttributeFirst = true and attributes have been imported)
|
||||
|
||||
return: True if the attributes have been successfully finalised (returning false will cause an exception to be thrown)
|
||||
Finalise the output argument object based on the current object, method etc
|
||||
--------------------------------------------------------------------*/
|
||||
bool JSBridgeArgumentWrap::finaliseAttributes() {
|
||||
if (!m_isReadingAttributes.has_value() || !*m_isReadingAttributes ||m_objectName.empty() || m_methodName.empty())
|
||||
return false;
|
||||
m_isReadingAttributes = false;
|
||||
void JSBridgeArgumentWrap::finaliseArgument() const {
|
||||
//Use the deserialised target bridge and method to establish the required arguments (if any)
|
||||
m_argument.reset(JSBridgeArgumentWrap::makeArgument(m_objectName, m_methodName));
|
||||
m_argument.reset(JSBridgeArgumentWrap::makeArgument(m_objectName, m_methodName, m_requestID));
|
||||
//If the function doesn't take an argument, we still need to pass along the base class with object name, method etc
|
||||
if (!m_argument)
|
||||
m_argument = std::make_unique<JSBridgeArgument>(m_objectName, m_methodName, m_requestID);
|
||||
return true;
|
||||
} //JSBridgeArgumentWrap::finaliseAttributes
|
||||
} //JSBridgeArgumentWrap::finaliseArgument
|
||||
|
||||
@@ -12,12 +12,15 @@ namespace speckle::interfac::browser::bridge {
|
||||
|
||||
/*!
|
||||
Factory function to make an argument object
|
||||
@param bridge The target bridge name
|
||||
@param method The target method to receive the argument
|
||||
@param request The request ID for the result
|
||||
@return A new argument object
|
||||
*/
|
||||
template<typename T>
|
||||
void* constructArgument() {
|
||||
void* constructArgument(const speckle::utility::String& bridge, const speckle::utility::String& method, const speckle::utility::String& request) {
|
||||
try {
|
||||
return new T();
|
||||
return new T(bridge, method, request);
|
||||
} catch(...) {
|
||||
return nullptr; //Object constructors should throw an exception if incoming data isn't viable (NB: only use for unrecoverable problems)
|
||||
}
|
||||
@@ -103,11 +106,6 @@ namespace speckle::interfac::browser::bridge {
|
||||
@return True if the data has been validated
|
||||
*/
|
||||
bool validate() override;
|
||||
/*!
|
||||
Finalise the package attributes (called when isAttributeFirst = true and attributes have been imported)
|
||||
@return True if the attributes have been successfully finalised (returning false will cause an exception to be thrown)
|
||||
*/
|
||||
bool finaliseAttributes() override;
|
||||
|
||||
/*!
|
||||
Make an argument object for a specified bridge method
|
||||
@@ -115,9 +113,10 @@ namespace speckle::interfac::browser::bridge {
|
||||
@param method The name of the target method
|
||||
@return An argument object (nullptr on failure)
|
||||
*/
|
||||
static JSBridgeArgument* makeArgument(const speckle::utility::String& bridge, const speckle::utility::String& method) {
|
||||
static JSBridgeArgument* makeArgument(const speckle::utility::String& bridge, const speckle::utility::String& method,
|
||||
const speckle::utility::String& request) {
|
||||
if (auto maker = m_argumentFactory.find(JSBridgeArgumentWrap::encode(bridge, method)); (maker != m_argumentFactory.end()))
|
||||
return reinterpret_cast<JSBridgeArgument*>(maker->second());
|
||||
return reinterpret_cast<JSBridgeArgument*>(maker->second(bridge, method, request));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -141,9 +140,13 @@ namespace speckle::interfac::browser::bridge {
|
||||
static speckle::utility::String encode(const speckle::utility::String& bridge, const speckle::utility::String& method) {
|
||||
return bridge + ":" + method;
|
||||
}
|
||||
/*!
|
||||
Finalise the output argument object based on the current object, method etc
|
||||
*/
|
||||
void finaliseArgument() const;
|
||||
|
||||
//Factory function for producing instances from a serialised document object
|
||||
using Production = std::function<void*()>;
|
||||
using Production = std::function<void*(const speckle::utility::String&, const speckle::utility::String&, const speckle::utility::String&)>;
|
||||
///Factory functions to construct arguments from linked bridge/method names
|
||||
static std::unordered_map<speckle::utility::String, Production> m_argumentFactory;
|
||||
|
||||
@@ -154,7 +157,7 @@ namespace speckle::interfac::browser::bridge {
|
||||
///An ID to be paired with the method return value
|
||||
speckle::utility::String m_requestID;
|
||||
///The function arguments
|
||||
std::shared_ptr<JSBridgeArgument> m_argument;
|
||||
mutable std::shared_ptr<JSBridgeArgument> m_argument;
|
||||
///True while the attribute are being deserialised
|
||||
std::optional<bool> m_isReadingAttributes = true;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user