Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Crocker <dcrocker@eschertech.com>2020-01-05 20:27:13 +0300
committerDavid Crocker <dcrocker@eschertech.com>2020-01-05 20:27:13 +0300
commit1d61e272e01727afa810f8aa5acedc051206772d (patch)
treeabd0044c1ea8c1ada382fddf5f5723799bb7eb86 /src
parent4f1c0947b1a0680679d8e8468f3e2e47be2bfc44 (diff)
Refactored object model to allow multiple tables per class
Diffstat (limited to 'src')
-rw-r--r--src/GCodes/GCodeBuffer/StringParser.cpp2
-rw-r--r--src/GCodes/GCodes.cpp6
-rw-r--r--src/GCodes/GCodes2.cpp2
-rw-r--r--src/Heating/Heat.cpp10
-rw-r--r--src/Movement/BedProbing/Grid.cpp6
-rw-r--r--src/Movement/BedProbing/RandomProbePointSet.cpp6
-rw-r--r--src/Movement/Move.cpp14
-rw-r--r--src/Movement/StraightProbeSettings.cpp12
-rw-r--r--src/Networking/ESP8266WiFi/WiFiInterface.cpp12
-rw-r--r--src/Networking/LwipEthernet/LwipEthernetInterface.cpp12
-rw-r--r--src/Networking/Network.cpp6
-rw-r--r--src/Networking/W5500Ethernet/W5500Interface.cpp10
-rw-r--r--src/ObjectModel/ObjectModel.cpp87
-rw-r--r--src/ObjectModel/ObjectModel.h51
-rw-r--r--src/RepRap.cpp16
15 files changed, 154 insertions, 98 deletions
diff --git a/src/GCodes/GCodeBuffer/StringParser.cpp b/src/GCodes/GCodeBuffer/StringParser.cpp
index 0587ca92..ce2dc64a 100644
--- a/src/GCodes/GCodeBuffer/StringParser.cpp
+++ b/src/GCodes/GCodeBuffer/StringParser.cpp
@@ -2239,7 +2239,7 @@ ExpressionValue StringParser::ParseIdentifierExpression(bool evaluate)
return rslt;
}
- return reprap.GetObjectValue(*this, varName.c_str());
+ return reprap.GetObjectValue(0, *this, varName.c_str());
}
ParseException StringParser::ConstructParseException(const char *str) const
diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp
index 8f077dad..efb0f1a9 100644
--- a/src/GCodes/GCodes.cpp
+++ b/src/GCodes/GCodes.cpp
@@ -54,12 +54,14 @@
// Macro to build a standard lambda function that includes the necessary type conversions
#define OBJECT_MODEL_FUNC(_ret) OBJECT_MODEL_FUNC_BODY(GCodes, _ret)
-const ObjectModelTableEntry GCodes::objectModelTable[] =
+constexpr ObjectModelTableEntry GCodes::objectModelTable[] =
{
// These entries must be in alphabetical order
- { "speedFactor", OBJECT_MODEL_FUNC(&(self->speedFactor)), TYPE_OF(float), ObjectModelTableEntry::none }
+ { "speedFactor", OBJECT_MODEL_FUNC(&(self->speedFactor)), TYPE_OF(float), 0, ObjectModelEntryFlags::none }
};
+constexpr uint8_t GCodes::objectModelTableDescriptor[] = { 1, 1 };
+
DEFINE_GET_OBJECT_MODEL_TABLE(GCodes)
#endif
diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp
index 066fe937..454fb840 100644
--- a/src/GCodes/GCodes2.cpp
+++ b/src/GCodes/GCodes2.cpp
@@ -2693,7 +2693,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply)
}
else
{
- reprap.ReportAsJson(outBuf, filter.c_str(), ObjectModel::flagsNone);
+ reprap.ReportAsJson(outBuf, 0, filter.c_str(), ObjectModel::flagsNone);
}
}
break;
diff --git a/src/Heating/Heat.cpp b/src/Heating/Heat.cpp
index 76616120..72c1ffad 100644
--- a/src/Heating/Heat.cpp
+++ b/src/Heating/Heat.cpp
@@ -71,16 +71,18 @@ static const ObjectModelArrayDescriptor heatersArrayDescriptor =
// Macro to build a standard lambda function that includes the necessary type conversions
#define OBJECT_MODEL_FUNC(_ret) OBJECT_MODEL_FUNC_BODY(Heat, _ret)
-const ObjectModelTableEntry Heat::objectModelTable[] =
+constexpr ObjectModelTableEntry Heat::objectModelTable[] =
{
// These entries must be in alphabetical order
- { "ColdExtrudeTemperature", OBJECT_MODEL_FUNC(&(self->extrusionMinTemp)), TYPE_OF(float), ObjectModelTableEntry::none},
- { "ColdRetractTemperature", OBJECT_MODEL_FUNC(&(self->retractionMinTemp)), TYPE_OF(float), ObjectModelTableEntry::none},
+ { "ColdExtrudeTemperature", OBJECT_MODEL_FUNC(&(self->extrusionMinTemp)), TYPE_OF(float), 0, ObjectModelEntryFlags::none},
+ { "ColdRetractTemperature", OBJECT_MODEL_FUNC(&(self->retractionMinTemp)), TYPE_OF(float), 0, ObjectModelEntryFlags::none},
#if 0
- { "Heaters", OBJECT_MODEL_FUNC_NOSELF(&heatersArrayDescriptor), TYPE_OF(ObjectModel) | IsArray, ObjectModelTableEntry::none }
+ { "Heaters", OBJECT_MODEL_FUNC_NOSELF(&heatersArrayDescriptor), TYPE_OF(ObjectModel) | IsArray, 0, ObjectModelEntryFlags::none }
#endif
};
+constexpr uint8_t Heat::objectModelTableDescriptor[] = { 1, 2 };
+
DEFINE_GET_OBJECT_MODEL_TABLE(Heat)
#endif
diff --git a/src/Movement/BedProbing/Grid.cpp b/src/Movement/BedProbing/Grid.cpp
index cddc2109..00932db4 100644
--- a/src/Movement/BedProbing/Grid.cpp
+++ b/src/Movement/BedProbing/Grid.cpp
@@ -26,12 +26,14 @@ const char * const GridDefinition::HeightMapLabelLines[] =
// Macro to build a standard lambda function that includes the necessary type conversions
#define OBJECT_MODEL_FUNC(_ret) OBJECT_MODEL_FUNC_BODY(GridDefinition, _ret)
-const ObjectModelTableEntry GridDefinition::objectModelTable[] =
+constexpr ObjectModelTableEntry GridDefinition::objectModelTable[] =
{
// These entries must be in alphabetical order
- { "radius", OBJECT_MODEL_FUNC(&(self->radius)), TYPE_OF(float), ObjectModelTableEntry::none }
+ { "radius", OBJECT_MODEL_FUNC(&(self->radius)), TYPE_OF(float), 0, ObjectModelEntryFlags::none }
};
+constexpr uint8_t GridDefinition::objectModelTableDescriptor[] = { 1, 1 };
+
DEFINE_GET_OBJECT_MODEL_TABLE(GridDefinition)
#endif
diff --git a/src/Movement/BedProbing/RandomProbePointSet.cpp b/src/Movement/BedProbing/RandomProbePointSet.cpp
index 95b45cf0..1d26e3df 100644
--- a/src/Movement/BedProbing/RandomProbePointSet.cpp
+++ b/src/Movement/BedProbing/RandomProbePointSet.cpp
@@ -18,12 +18,14 @@
// Macro to build a standard lambda function that includes the necessary type conversions
#define OBJECT_MODEL_FUNC(_ret) OBJECT_MODEL_FUNC_BODY(RandomProbePointSet, _ret)
-const ObjectModelTableEntry RandomProbePointSet::objectModelTable[] =
+constexpr ObjectModelTableEntry RandomProbePointSet::objectModelTable[] =
{
// These entries must be in alphabetical order
- { "numPointsProbed", OBJECT_MODEL_FUNC(&(self->numBedCompensationPoints)), TYPE_OF(uint32_t), ObjectModelTableEntry::none }
+ { "numPointsProbed", OBJECT_MODEL_FUNC(&(self->numBedCompensationPoints)), TYPE_OF(uint32_t), 0, ObjectModelEntryFlags::none }
};
+constexpr uint8_t RandomProbePointSet::objectModelTableDescriptor[] = { 1, 1 };
+
DEFINE_GET_OBJECT_MODEL_TABLE(RandomProbePointSet)
#endif
diff --git a/src/Movement/Move.cpp b/src/Movement/Move.cpp
index b64a5ba6..2a536465 100644
--- a/src/Movement/Move.cpp
+++ b/src/Movement/Move.cpp
@@ -54,16 +54,18 @@
// Macro to build a standard lambda function that includes the necessary type conversions
#define OBJECT_MODEL_FUNC(_ret) OBJECT_MODEL_FUNC_BODY(Move, _ret)
-const ObjectModelTableEntry Move::objectModelTable[] =
+constexpr ObjectModelTableEntry Move::objectModelTable[] =
{
// These entries must be in alphabetical order
- { "drcEnabled", OBJECT_MODEL_FUNC(&(self->drcEnabled)), TYPE_OF(bool), ObjectModelTableEntry::none },
- { "drcMinimumAcceleration", OBJECT_MODEL_FUNC(&(self->drcMinimumAcceleration)), TYPE_OF(float), ObjectModelTableEntry::none },
- { "drcPeriod", OBJECT_MODEL_FUNC(&(self->drcPeriod)), TYPE_OF(float), ObjectModelTableEntry::none },
- { "maxPrintingAcceleration", OBJECT_MODEL_FUNC(&(self->maxPrintingAcceleration)), TYPE_OF(float), ObjectModelTableEntry::none },
- { "maxTravelAcceleration", OBJECT_MODEL_FUNC(&(self->maxTravelAcceleration)), TYPE_OF(float), ObjectModelTableEntry::none },
+ { "drcEnabled", OBJECT_MODEL_FUNC(&(self->drcEnabled)), TYPE_OF(bool), 0, ObjectModelEntryFlags::none },
+ { "drcMinimumAcceleration", OBJECT_MODEL_FUNC(&(self->drcMinimumAcceleration)), TYPE_OF(float), 0, ObjectModelEntryFlags::none },
+ { "drcPeriod", OBJECT_MODEL_FUNC(&(self->drcPeriod)), TYPE_OF(float), 0, ObjectModelEntryFlags::none },
+ { "maxPrintingAcceleration", OBJECT_MODEL_FUNC(&(self->maxPrintingAcceleration)), TYPE_OF(float), 0, ObjectModelEntryFlags::none },
+ { "maxTravelAcceleration", OBJECT_MODEL_FUNC(&(self->maxTravelAcceleration)), TYPE_OF(float), 0, ObjectModelEntryFlags::none },
};
+constexpr uint8_t Move::objectModelTableDescriptor[] = { 1, 5 };
+
DEFINE_GET_OBJECT_MODEL_TABLE(Move)
#endif
diff --git a/src/Movement/StraightProbeSettings.cpp b/src/Movement/StraightProbeSettings.cpp
index c77cc0a2..0a1dbb5a 100644
--- a/src/Movement/StraightProbeSettings.cpp
+++ b/src/Movement/StraightProbeSettings.cpp
@@ -17,15 +17,17 @@
// Macro to build a standard lambda function that includes the necessary type conversions
#define OBJECT_MODEL_FUNC(_ret) OBJECT_MODEL_FUNC_BODY(StraightProbeSettings, _ret)
-const ObjectModelTableEntry StraightProbeSettings::objectModelTable[] =
+constexpr ObjectModelTableEntry StraightProbeSettings::objectModelTable[] =
{
// These entries must be in alphabetical order
- { "movingAxes", OBJECT_MODEL_FUNC(&(self->movingAxes)), TYPE_OF(uint32_t), ObjectModelTableEntry::none },
- { "probeToUse", OBJECT_MODEL_FUNC(&(self->probeToUse)), TYPE_OF(uint32_t), ObjectModelTableEntry::none },
- //{ "target", OBJECT_MODEL_FUNC(&(self->target)), TYPE_OF(const float *), ObjectModelTableEntry::none },
- { "type", OBJECT_MODEL_FUNC(&(self->type)), TYPE_OF(uint32_t), ObjectModelTableEntry::none }
+ { "movingAxes", OBJECT_MODEL_FUNC(&(self->movingAxes)), TYPE_OF(uint32_t), 0, ObjectModelEntryFlags::none },
+ { "probeToUse", OBJECT_MODEL_FUNC(&(self->probeToUse)), TYPE_OF(uint32_t), 0, ObjectModelEntryFlags::none },
+ //{ "target", OBJECT_MODEL_FUNC(&(self->target)), TYPE_OF(const float *), 0, ObjectModelEntryFlags::none },
+ { "type", OBJECT_MODEL_FUNC(&(self->type)), TYPE_OF(uint32_t), 0, ObjectModelEntryFlags::none }
};
+constexpr uint8_t StraightProbeSettings::objectModelTableDescriptor[] = { 1, 3 };
+
DEFINE_GET_OBJECT_MODEL_TABLE(StraightProbeSettings)
#endif
diff --git a/src/Networking/ESP8266WiFi/WiFiInterface.cpp b/src/Networking/ESP8266WiFi/WiFiInterface.cpp
index 4e68acc5..12465a73 100644
--- a/src/Networking/ESP8266WiFi/WiFiInterface.cpp
+++ b/src/Networking/ESP8266WiFi/WiFiInterface.cpp
@@ -155,15 +155,17 @@ WiFiInterface::WiFiInterface(Platform& p) noexcept : platform(p), uploader(nullp
// Macro to build a standard lambda function that includes the necessary type conversions
#define OBJECT_MODEL_FUNC(_ret) OBJECT_MODEL_FUNC_BODY(WiFiInterface, _ret)
-const ObjectModelTableEntry WiFiInterface::objectModelTable[] =
+constexpr ObjectModelTableEntry WiFiInterface::objectModelTable[] =
{
// These entries must be in alphabetical order
- { "gateway", OBJECT_MODEL_FUNC(&(self->gateway)), TYPE_OF(IPAddress), ObjectModelTableEntry::none },
- { "ip", OBJECT_MODEL_FUNC(&(self->ipAddress)), TYPE_OF(IPAddress), ObjectModelTableEntry::none },
- { "name", OBJECT_MODEL_FUNC_NOSELF("wifi"), TYPE_OF(const char *), ObjectModelTableEntry::none },
- { "netmask", OBJECT_MODEL_FUNC(&(self->netmask)), TYPE_OF(IPAddress), ObjectModelTableEntry::none },
+ { "gateway", OBJECT_MODEL_FUNC(&(self->gateway)), TYPE_OF(IPAddress), 0, ObjectModelEntryFlags::none },
+ { "ip", OBJECT_MODEL_FUNC(&(self->ipAddress)), TYPE_OF(IPAddress), 0, ObjectModelEntryFlags::none },
+ { "name", OBJECT_MODEL_FUNC_NOSELF("wifi"), TYPE_OF(const char *), 0, ObjectModelEntryFlags::none },
+ { "netmask", OBJECT_MODEL_FUNC(&(self->netmask)), TYPE_OF(IPAddress), 0, ObjectModelEntryFlags::none },
};
+constexpr uint8_t WiFiInterface::objectModelTableDescriptor[] = { 1, 4 };
+
DEFINE_GET_OBJECT_MODEL_TABLE(WiFiInterface)
#endif
diff --git a/src/Networking/LwipEthernet/LwipEthernetInterface.cpp b/src/Networking/LwipEthernet/LwipEthernetInterface.cpp
index 0a46d850..aefc7580 100644
--- a/src/Networking/LwipEthernet/LwipEthernetInterface.cpp
+++ b/src/Networking/LwipEthernet/LwipEthernetInterface.cpp
@@ -108,15 +108,17 @@ LwipEthernetInterface::LwipEthernetInterface(Platform& p) noexcept : platform(p)
// Macro to build a standard lambda function that includes the necessary type conversions
#define OBJECT_MODEL_FUNC(_ret) OBJECT_MODEL_FUNC_BODY(LwipEthernetInterface, _ret)
-const ObjectModelTableEntry LwipEthernetInterface::objectModelTable[] =
+constexpr ObjectModelTableEntry LwipEthernetInterface::objectModelTable[] =
{
// These entries must be in alphabetical order
- { "gateway", OBJECT_MODEL_FUNC(&(self->gateway)), TYPE_OF(IPAddress), ObjectModelTableEntry::none },
- { "ip", OBJECT_MODEL_FUNC(&(self->ipAddress)), TYPE_OF(IPAddress), ObjectModelTableEntry::none },
- { "name", OBJECT_MODEL_FUNC_NOSELF("ethernet"), TYPE_OF(const char *), ObjectModelTableEntry::none },
- { "netmask", OBJECT_MODEL_FUNC(&(self->netmask)), TYPE_OF(IPAddress), ObjectModelTableEntry::none },
+ { "gateway", OBJECT_MODEL_FUNC(&(self->gateway)), TYPE_OF(IPAddress), 0, ObjectModelEntryFlags::none },
+ { "ip", OBJECT_MODEL_FUNC(&(self->ipAddress)), TYPE_OF(IPAddress), 0, ObjectModelEntryFlags::none },
+ { "name", OBJECT_MODEL_FUNC_NOSELF("ethernet"), TYPE_OF(const char *), 0, ObjectModelEntryFlags::none },
+ { "netmask", OBJECT_MODEL_FUNC(&(self->netmask)), TYPE_OF(IPAddress), 0, ObjectModelEntryFlags::none },
};
+constexpr uint8_t LwipEthernetInterface::objectModelTableDescriptor[] = { 1, 4 };
+
DEFINE_GET_OBJECT_MODEL_TABLE(LwipEthernetInterface)
#endif
diff --git a/src/Networking/Network.cpp b/src/Networking/Network.cpp
index 6b8d55c9..d5875306 100644
--- a/src/Networking/Network.cpp
+++ b/src/Networking/Network.cpp
@@ -78,12 +78,14 @@ static const ObjectModelArrayDescriptor interfaceArrayDescriptor =
// Macro to build a standard lambda function that includes the necessary type conversions
#define OBJECT_MODEL_FUNC(_ret) OBJECT_MODEL_FUNC_BODY(Network, _ret)
-const ObjectModelTableEntry Network::objectModelTable[] =
+constexpr ObjectModelTableEntry Network::objectModelTable[] =
{
// These entries must be in alphabetical order
- { "interfaces", OBJECT_MODEL_FUNC_NOSELF(&interfaceArrayDescriptor), TYPE_OF(ObjectModel) | IsArray, ObjectModelTableEntry::none }
+ { "interfaces", OBJECT_MODEL_FUNC_NOSELF(&interfaceArrayDescriptor), TYPE_OF(ObjectModel) | IsArray, 0, ObjectModelEntryFlags::none }
};
+constexpr uint8_t Network::objectModelTableDescriptor[] = { 1, 1 };
+
DEFINE_GET_OBJECT_MODEL_TABLE(Network)
#endif
diff --git a/src/Networking/W5500Ethernet/W5500Interface.cpp b/src/Networking/W5500Ethernet/W5500Interface.cpp
index 25498260..87b7348d 100644
--- a/src/Networking/W5500Ethernet/W5500Interface.cpp
+++ b/src/Networking/W5500Ethernet/W5500Interface.cpp
@@ -49,12 +49,14 @@ W5500Interface::W5500Interface(Platform& p) noexcept
const ObjectModelTableEntry W5500Interface::objectModelTable[] =
{
// These entries must be in alphabetical order
- { "gateway", OBJECT_MODEL_FUNC(&(self->gateway)), TYPE_OF(IPAddress), ObjectModelTableEntry::none },
- { "ip", OBJECT_MODEL_FUNC(&(self->ipAddress)), TYPE_OF(IPAddress), ObjectModelTableEntry::none },
- { "name", OBJECT_MODEL_FUNC_NOSELF("ethernet"), TYPE_OF(const char *), ObjectModelTableEntry::none },
- { "netmask", OBJECT_MODEL_FUNC(&(self->netmask)), TYPE_OF(IPAddress), ObjectModelTableEntry::none },
+ { "gateway", OBJECT_MODEL_FUNC(&(self->gateway)), TYPE_OF(IPAddress), 0, ObjectModelEntryFlags::none },
+ { "ip", OBJECT_MODEL_FUNC(&(self->ipAddress)), TYPE_OF(IPAddress), 0, ObjectModelEntryFlags::none },
+ { "name", OBJECT_MODEL_FUNC_NOSELF("ethernet"), TYPE_OF(const char *), 0, ObjectModelEntryFlags::none },
+ { "netmask", OBJECT_MODEL_FUNC(&(self->netmask)), TYPE_OF(IPAddress), 0, ObjectModelEntryFlags::none },
};
+constexpr uint8_t W5500Interface::objectModelTableDescriptor[] = { 1, 4 };
+
DEFINE_GET_OBJECT_MODEL_TABLE(W5500Interface)
#endif
diff --git a/src/ObjectModel/ObjectModel.cpp b/src/ObjectModel/ObjectModel.cpp
index fa7cc8e8..20b20b91 100644
--- a/src/ObjectModel/ObjectModel.cpp
+++ b/src/ObjectModel/ObjectModel.cpp
@@ -20,36 +20,59 @@ ObjectModel::ObjectModel() noexcept
}
// Report this object
-bool ObjectModel::ReportAsJson(OutputBuffer* buf, const char* filter, ReportFlags flags) noexcept
+bool ObjectModel::ReportAsJson(OutputBuffer* buf, uint8_t tableNumber, const char* filter, ReportFlags flags) noexcept
{
buf->cat('{');
- size_t numEntries;
- const ObjectModelTableEntry *omte = GetObjectModelTable(numEntries);
bool added = false;
- while (numEntries != 0)
+ const uint8_t *descriptor;
+ const ObjectModelTableEntry *tbl = GetObjectModelTable(descriptor);
+ if (tableNumber < descriptor[0])
{
- if (omte->Matches(filter, flags))
+ size_t numEntries = descriptor[tableNumber + 1];
+ while (tableNumber != 0)
{
- if (added)
+ --tableNumber;
+ tbl += descriptor[tableNumber + 1];
+ }
+
+ while (numEntries != 0)
+ {
+ if (tbl->Matches(filter, flags))
{
- buf->cat(',');
+ if (added)
+ {
+ buf->cat(',');
+ }
+ tbl->ReportAsJson(buf, this, GetNextElement(filter), flags);
+ added = true;
}
- omte->ReportAsJson(buf, this, GetNextElement(filter), flags);
- added = true;
+ --numEntries;
+ ++tbl;
}
- --numEntries;
- ++omte;
}
buf->cat('}');
- return true;
+ return added;
}
// Find the requested entry
-const ObjectModelTableEntry* ObjectModel::FindObjectModelTableEntry(const char* idString) noexcept
+const ObjectModelTableEntry* ObjectModel::FindObjectModelTableEntry(uint8_t tableNumber, const char* idString) noexcept
{
- size_t numElems;
- const ObjectModelTableEntry *tbl = GetObjectModelTable(numElems);
- size_t low = 0, high = numElems;
+// size_t numElems;
+ const uint8_t *descriptor;
+ const ObjectModelTableEntry *tbl = GetObjectModelTable(descriptor);
+ if (tableNumber >= descriptor[0])
+ {
+ return nullptr;
+ }
+
+ const size_t numEntries = descriptor[tableNumber + 1];
+ while (tableNumber != 0)
+ {
+ --tableNumber;
+ tbl += descriptor[tableNumber + 1];
+ }
+
+ size_t low = 0, high = numEntries;
while (high > low)
{
const size_t mid = (high - low)/2 + low;
@@ -67,7 +90,7 @@ const ObjectModelTableEntry* ObjectModel::FindObjectModelTableEntry(const char*
high = mid;
}
}
- return (low < numElems && tbl[low].IdCompare(idString) == 0) ? &tbl[low] : nullptr;
+ return (low < numEntries && tbl[low].IdCompare(idString) == 0) ? &tbl[low] : nullptr;
}
/*static*/ const char* ObjectModel::GetNextElement(const char *id) noexcept
@@ -85,11 +108,11 @@ const ObjectModelTableEntry* ObjectModel::FindObjectModelTableEntry(const char*
bool ObjectModelTableEntry::Matches(const char* filterString, ObjectModelFilterFlags filterFlags) const noexcept
{
- return IdCompare(filterString) == 0 && (flags & filterFlags) == filterFlags;
+ return IdCompare(filterString) == 0 && ((uint16_t)flags & (uint16_t)filterFlags) == (uint16_t)filterFlags;
}
// Private function to report a value of primitive type
-void ObjectModelTableEntry::ReportItemAsJson(OutputBuffer *buf, const char *filter, ObjectModel::ReportFlags flags, void *nParam, TypeCode type) noexcept
+void ObjectModelTableEntry::ReportItemAsJson(OutputBuffer *buf, const char *filter, ObjectModel::ReportFlags flags, void *nParam, uint8_t tableNumber, TypeCode type) noexcept
{
switch (type)
{
@@ -98,7 +121,7 @@ void ObjectModelTableEntry::ReportItemAsJson(OutputBuffer *buf, const char *filt
{
++filter;
}
- ((ObjectModel*)nParam)->ReportAsJson(buf, filter, flags);
+ ((ObjectModel*)nParam)->ReportAsJson(buf, tableNumber, filter, flags);
break;
case TYPE_OF(float):
@@ -211,7 +234,7 @@ bool ObjectModelTableEntry::ReportAsJson(OutputBuffer* buf, ObjectModel *self, c
{
buf->cat(',');
}
- ReportItemAsJson(buf, filter, flags, arr->GetElement(self, i), type & ~IsArray);
+ ReportItemAsJson(buf, filter, flags, arr->GetElement(self, i), tableNumber, type & ~IsArray);
}
buf->cat(']');
}
@@ -226,13 +249,13 @@ bool ObjectModelTableEntry::ReportAsJson(OutputBuffer* buf, ObjectModel *self, c
return false; // invalid syntax, or index out of range
}
buf->cat('[');
- ReportItemAsJson(buf, endptr + 1, flags, arr->GetElement(self, val), type & ~IsArray);
+ ReportItemAsJson(buf, endptr + 1, flags, arr->GetElement(self, val), tableNumber, type & ~IsArray);
buf->cat(']');
}
}
else
{
- ReportItemAsJson(buf, filter, flags, param(self), type);
+ ReportItemAsJson(buf, filter, flags, param(self), tableNumber, type);
}
return true;
}
@@ -257,11 +280,11 @@ int ObjectModelTableEntry::IdCompare(const char *id) const noexcept
}
// Get the value of an object when we don't know what its type is
-ExpressionValue ObjectModel::GetObjectValue(const StringParser& sp, const char *idString)
+ExpressionValue ObjectModel::GetObjectValue(uint8_t tableNumber, const StringParser& sp, const char *idString)
{
ExpressionValue val;
- const ObjectModelTableEntry *e = FindObjectModelTableEntry(idString);
+ const ObjectModelTableEntry *e = FindObjectModelTableEntry(tableNumber, idString);
if (e == nullptr)
{
throw sp.ConstructParseException("unknown variable %s", idString);
@@ -300,7 +323,7 @@ ExpressionValue ObjectModel::GetObjectValue(const StringParser& sp, const char *
switch (val.type)
{
case TYPE_OF(ObjectModel):
- return ((ObjectModel*)param)->GetObjectValue(sp, idString);
+ return ((ObjectModel*)param)->GetObjectValue(e->tableNumber, sp, idString);
case TYPE_OF(float):
case TYPE_OF(Float2):
@@ -337,9 +360,9 @@ ExpressionValue ObjectModel::GetObjectValue(const StringParser& sp, const char *
}
// Template specialisations
-bool ObjectModel::GetObjectValue(float& val, const char *idString)
+bool ObjectModel::GetObjectValue(uint8_t tableNumber, float& val, const char *idString)
{
- const ObjectModelTableEntry *e = FindObjectModelTableEntry(idString);
+ const ObjectModelTableEntry *e = FindObjectModelTableEntry(tableNumber, idString);
if (e == nullptr)
{
return NoType;
@@ -354,7 +377,7 @@ bool ObjectModel::GetObjectValue(float& val, const char *idString)
switch (e->type)
{
case TYPE_OF(ObjectModel):
- return ((ObjectModel*)e->param(this))->GetObjectValue(val, GetNextElement(idString));
+ return ((ObjectModel*)e->param(this))->GetObjectValue(e->tableNumber, val, GetNextElement(idString));
case TYPE_OF(float):
val = *((const float*)e->param(this));
@@ -374,9 +397,9 @@ bool ObjectModel::GetObjectValue(float& val, const char *idString)
}
// Specialisation of above for int, allowing conversion from unsigned to signed
-bool ObjectModel::GetObjectValue(int32_t& val, const char *idString)
+bool ObjectModel::GetObjectValue(uint8_t tableNumber, int32_t& val, const char *idString)
{
- const ObjectModelTableEntry *e = FindObjectModelTableEntry(idString);
+ const ObjectModelTableEntry *e = FindObjectModelTableEntry(tableNumber, idString);
if (e == nullptr)
{
return NoType;
@@ -391,7 +414,7 @@ bool ObjectModel::GetObjectValue(int32_t& val, const char *idString)
switch (e->type)
{
case TYPE_OF(ObjectModel):
- return ((ObjectModel*)e->param(this))->GetObjectValue(val, GetNextElement(idString));
+ return ((ObjectModel*)e->param(this))->GetObjectValue(e->tableNumber, val, GetNextElement(idString));
case TYPE_OF(int32_t):
val = *((const int32_t*)e->param(this));
diff --git a/src/ObjectModel/ObjectModel.h b/src/ObjectModel/ObjectModel.h
index c053a594..78cb55d9 100644
--- a/src/ObjectModel/ObjectModel.h
+++ b/src/ObjectModel/ObjectModel.h
@@ -45,6 +45,12 @@ template<> constexpr TypeCode TypeOf<IPAddress>() noexcept { return 11; }
#define TYPE_OF(_t) (TypeOf<_t>())
+// Function used for compile-time check for the correct number of entries in an object model table
+static inline constexpr size_t ArraySum(const uint8_t *arr, size_t numEntries)
+{
+ return (numEntries == 0) ? 0 : arr[0] + ArraySum(arr + 1, numEntries - 1);
+}
+
// Forward declarations
class ObjectModelTableEntry;
class ObjectModel;
@@ -85,28 +91,28 @@ public:
ObjectModel() noexcept;
// Construct a JSON representation of those parts of the object model requested by the user
- bool ReportAsJson(OutputBuffer *buf, const char *filter, ReportFlags rflags) noexcept;
+ bool ReportAsJson(OutputBuffer *buf, uint8_t tableNumber, const char *filter, ReportFlags rflags) noexcept;
// Return the type of an object
- TypeCode GetObjectType(const char *idString) noexcept;
+ TypeCode GetObjectType(uint8_t tableNumber, const char *idString) noexcept;
// Get the value of an object when we don't know what its type is
- ExpressionValue GetObjectValue(const StringParser& sp, const char *idString) THROWS_PARSE_ERROR;
+ ExpressionValue GetObjectValue(uint8_t tableNumber, const StringParser& sp, const char *idString) THROWS_PARSE_ERROR;
// Specialisation of above for float, allowing conversion from integer to float
- bool GetObjectValue(float& val, const char *idString) THROWS_PARSE_ERROR;
+ bool GetObjectValue(uint8_t tableNumber, float& val, const char *idString) THROWS_PARSE_ERROR;
// Specialisation of above for int, allowing conversion from unsigned to signed
- bool GetObjectValue(int32_t& val, const char *idString) THROWS_PARSE_ERROR;
+ bool GetObjectValue(uint8_t tableNumber, int32_t& val, const char *idString) THROWS_PARSE_ERROR;
// Get the object model table entry for the current level object in the query
- const ObjectModelTableEntry *FindObjectModelTableEntry(const char *idString) noexcept;
+ const ObjectModelTableEntry *FindObjectModelTableEntry(uint8_t tableNumber, const char *idString) noexcept;
// Skip the current element in the ID or filter string
static const char* GetNextElement(const char *id) noexcept;
protected:
- virtual const ObjectModelTableEntry *GetObjectModelTable(size_t& numEntries) const noexcept = 0;
+ virtual const ObjectModelTableEntry *GetObjectModelTable(const uint8_t*& descriptor) const noexcept = 0;
private:
// Get pointers to various types from the object model, returning null if failed
@@ -125,6 +131,14 @@ public:
void * (*GetElement)(ObjectModel*, size_t) noexcept;
};
+// Flags field of a table entry
+enum class ObjectModelEntryFlags : uint16_t
+{
+ none = 0, // nothing special
+ live = 1, // fast changing data, included in common status response
+ canAlter = 2, // we can alter this value
+};
+
// Object model table entry
// It must be possible to construct these in the form of initialised data in flash memory, to avoid using large amounts of RAM.
// Therefore we can't use a class hierarchy to represent different types of entry. Instead we use a type code and a void* parameter.
@@ -132,14 +146,6 @@ class ObjectModelTableEntry
{
public:
// Type declarations
- // Flags field of a table entry
- enum ObjectModelEntryFlags : uint16_t
- {
- none = 0, // nothing special
- live = 1, // fast changing data, included in common status response
- canAlter = 2, // we can alter this value
- };
-
// Type of the function pointer in the table entry, that returns a pointer to the data
typedef void *(*ParamFuncPtr_t)(ObjectModel*) noexcept;
@@ -147,6 +153,7 @@ public:
const char * name; // name of this field
ParamFuncPtr_t param; // function that yields a pointer to this value
TypeCode type; // code for the type of this value
+ uint8_t tableNumber; // which object model table we want, for objects that have more than one table
ObjectModelEntryFlags flags; // information about this value
// Member functions. These must all be 'const'.
@@ -164,7 +171,7 @@ public:
int IdCompare(const char *id) const noexcept;
// Private function to report a value of primitive type
- static void ReportItemAsJson(OutputBuffer *buf, const char *filter, ObjectModel::ReportFlags flags, void *nParam, TypeCode type) noexcept;
+ static void ReportItemAsJson(OutputBuffer *buf, const char *filter, ObjectModel::ReportFlags flags, void *nParam, uint8_t tableNumber, TypeCode type) noexcept;
};
// Use this macro to inherit form ObjectModel
@@ -172,13 +179,17 @@ public:
// Use this macro in the 'protected' section of every class declaration that derived from ObjectModel
#define DECLARE_OBJECT_MODEL \
- const ObjectModelTableEntry *GetObjectModelTable(size_t& numEntries) const noexcept override; \
- static const ObjectModelTableEntry objectModelTable[];
+ const ObjectModelTableEntry *GetObjectModelTable(const uint8_t*& descriptor) const noexcept override; \
+ static const ObjectModelTableEntry objectModelTable[]; \
+ static const uint8_t objectModelTableDescriptor[];
#define DEFINE_GET_OBJECT_MODEL_TABLE(_class) \
- const ObjectModelTableEntry *_class::GetObjectModelTable(size_t& numEntries) const noexcept \
+ const ObjectModelTableEntry *_class::GetObjectModelTable(const uint8_t*& descriptor) const noexcept \
{ \
- numEntries = ARRAY_SIZE(objectModelTable); \
+ static_assert(ARRAY_SIZE(_class::objectModelTableDescriptor) == _class::objectModelTableDescriptor[0] + 1, "Bad descriptor length"); \
+ static_assert(ARRAY_SIZE(_class::objectModelTable) == ArraySum(_class::objectModelTableDescriptor + 1, ARRAY_SIZE(_class::objectModelTableDescriptor) - 1), \
+ "Mismatched object model table and descriptor"); \
+ descriptor = objectModelTableDescriptor; \
return objectModelTable; \
}
diff --git a/src/RepRap.cpp b/src/RepRap.cpp
index 13b2b8ea..33539c26 100644
--- a/src/RepRap.cpp
+++ b/src/RepRap.cpp
@@ -127,18 +127,20 @@ extern "C" void hsmciIdle(uint32_t stBits, uint32_t dmaBits) noexcept
// Macro to build a standard lambda function that includes the necessary type conversions
#define OBJECT_MODEL_FUNC(_ret) OBJECT_MODEL_FUNC_BODY(RepRap, _ret)
-const ObjectModelTableEntry RepRap::objectModelTable[] =
+constexpr ObjectModelTableEntry RepRap::objectModelTable[] =
{
// These entries are temporary pending design of the object model
//TODO design the object model
- { "gcodes", OBJECT_MODEL_FUNC(&(self->GetGCodes())), TYPE_OF(ObjectModel), ObjectModelTableEntry::none },
- { "heat", OBJECT_MODEL_FUNC(&(self->GetHeat())), TYPE_OF(ObjectModel), ObjectModelTableEntry::none },
- { "meshProbe", OBJECT_MODEL_FUNC(&(self->GetMove().GetGrid())), TYPE_OF(ObjectModel), ObjectModelTableEntry::none },
- { "move", OBJECT_MODEL_FUNC(&(self->GetMove())), TYPE_OF(ObjectModel), ObjectModelTableEntry::none },
- { "network", OBJECT_MODEL_FUNC(&(self->GetNetwork())), TYPE_OF(ObjectModel), ObjectModelTableEntry::none },
- { "randomProbe", OBJECT_MODEL_FUNC(&(self->GetMove().GetProbePoints())), TYPE_OF(ObjectModel), ObjectModelTableEntry::none },
+ { "gcodes", OBJECT_MODEL_FUNC(&(self->GetGCodes())), TYPE_OF(ObjectModel), 0, ObjectModelEntryFlags::none },
+ { "heat", OBJECT_MODEL_FUNC(&(self->GetHeat())), TYPE_OF(ObjectModel), 0, ObjectModelEntryFlags::none },
+ { "meshProbe", OBJECT_MODEL_FUNC(&(self->GetMove().GetGrid())), TYPE_OF(ObjectModel), 0, ObjectModelEntryFlags::none },
+ { "move", OBJECT_MODEL_FUNC(&(self->GetMove())), TYPE_OF(ObjectModel), 0, ObjectModelEntryFlags::none },
+ { "network", OBJECT_MODEL_FUNC(&(self->GetNetwork())), TYPE_OF(ObjectModel), 0, ObjectModelEntryFlags::none },
+ { "randomProbe", OBJECT_MODEL_FUNC(&(self->GetMove().GetProbePoints())), TYPE_OF(ObjectModel), 0, ObjectModelEntryFlags::none },
};
+constexpr uint8_t RepRap::objectModelTableDescriptor[] = { 1, 6 };
+
DEFINE_GET_OBJECT_MODEL_TABLE(RepRap)
#endif