diff options
author | David Crocker <dcrocker@eschertech.com> | 2020-01-05 20:27:13 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2020-01-05 20:27:13 +0300 |
commit | 1d61e272e01727afa810f8aa5acedc051206772d (patch) | |
tree | abd0044c1ea8c1ada382fddf5f5723799bb7eb86 /src | |
parent | 4f1c0947b1a0680679d8e8468f3e2e47be2bfc44 (diff) |
Refactored object model to allow multiple tables per class
Diffstat (limited to 'src')
-rw-r--r-- | src/GCodes/GCodeBuffer/StringParser.cpp | 2 | ||||
-rw-r--r-- | src/GCodes/GCodes.cpp | 6 | ||||
-rw-r--r-- | src/GCodes/GCodes2.cpp | 2 | ||||
-rw-r--r-- | src/Heating/Heat.cpp | 10 | ||||
-rw-r--r-- | src/Movement/BedProbing/Grid.cpp | 6 | ||||
-rw-r--r-- | src/Movement/BedProbing/RandomProbePointSet.cpp | 6 | ||||
-rw-r--r-- | src/Movement/Move.cpp | 14 | ||||
-rw-r--r-- | src/Movement/StraightProbeSettings.cpp | 12 | ||||
-rw-r--r-- | src/Networking/ESP8266WiFi/WiFiInterface.cpp | 12 | ||||
-rw-r--r-- | src/Networking/LwipEthernet/LwipEthernetInterface.cpp | 12 | ||||
-rw-r--r-- | src/Networking/Network.cpp | 6 | ||||
-rw-r--r-- | src/Networking/W5500Ethernet/W5500Interface.cpp | 10 | ||||
-rw-r--r-- | src/ObjectModel/ObjectModel.cpp | 87 | ||||
-rw-r--r-- | src/ObjectModel/ObjectModel.h | 51 | ||||
-rw-r--r-- | src/RepRap.cpp | 16 |
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 |