diff options
author | David Crocker <dcrocker@eschertech.com> | 2018-10-17 00:08:50 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2018-10-17 00:08:50 +0300 |
commit | 1347ea638627e7969ea1fa6f059d497c8692925a (patch) | |
tree | 77bc84037f64dd6efe63ce045e61b12e3eb95d32 /src/ObjectModel/ObjectModel.h | |
parent | bc93fe18d311e25e68b553ceeea9dd1b35262bf6 (diff) |
Nearly version 2.02RC3
New G/M code features since 2.02RC2:
G10 L2 and G10 L20 can now be used with no P parameter, meaning use the current coordinate system
G60 now saves the current tool as well as the current user coordinates
M116 now accepts an optional S parameter to specify the acceptable temperature difference
M205 is supported to set the jerk limits (in mm/sec) as an alternative to M566
M208 now accepts Xaa:bb Ycc:dd etc. as an alternative to separate M208 S0 and M208 s1 commands
M305 temperature sensor type 300-307 now supports a C parameter to select the input channel and a D parameter to select differential mode
M408 now accepts a P parameter. P0 (default) gives the previous behaviour. P1 S"filter" now returns those parts of the object model that match "filter".
M557 now supports a P parameter to set the number of X and Y points, as an alternative to using the S parameter to set the spacing
M558: zero or negative Z probe tolerance (S parameter) with A parameter > 1 now means always average all readings
M558 now accepts a C parameter to select the endstop number when the mode is 4. M558 P6 is translated to M558 P4 C4, and M558 P7 is translated to M558 P4 C2.
M600 is now supported
T R# (where # is a restore point number) is now supported
-
Other changed behaviour since 2.02RC2:
When storage module debug is enabled, failing to open a file is now a warning not an error because it is a normal accurrence when optional files are not present (e.g. tool change files, start.g, stop.g)
Increased number of restore points from 3 to 6
When the WiFi module is in client mode it tries to auto-reconnect continuously if the connection is lost
Implemented the object model framework and a few variables
Z leadscrew or manual be levelling adjustment results are now logged even if the process failed, if logging is enabled
Mesh probing results are now logged, if logging is enabled
Error and warning messages generated by incorrect GCode commands are now logged, if logging is enabled
-
Bug fixes since 2.02RC2:
The motor phase open circuit message is clearer, is now a warning instead of an error, and spurious instances of it should be reduced
M918 with no parameters now reports current settings (Duet 2 Maestro)
Further limited the amount of CPU time used to refresh the 12864 display
Fixed incorrect check for G2/G3 missing parameter
Fix CoreXYUV stall detection
Absolute babystepping was be restricted to 1mm change
After using G10 L2 or G10 L20 to change workplace coordinate offsets, the user positions of axes other than X and Y were not updated
M915 now recognises the E parameter
M915 output was truncated if no drives were specified
On the Duet 2 Maestro, if a BLTouch Z probe was used then the pin didn't always stay retracted after the probe was triggered
On the Duet 2 Maestro, if the SD card menu on the 12864 display was used then the network kept disconnecting
If G30 S-1 was sent with the Z probe type set to zero then reported trigger height was an undefined value
Fixed potential buffer overflow issues in 12864 menu code
-
Other changes:
Introduced class IPAddres and refactored most usage oif IP addresses
Diffstat (limited to 'src/ObjectModel/ObjectModel.h')
-rw-r--r-- | src/ObjectModel/ObjectModel.h | 107 |
1 files changed, 90 insertions, 17 deletions
diff --git a/src/ObjectModel/ObjectModel.h b/src/ObjectModel/ObjectModel.h index dddc6e21..d76f9ce5 100644 --- a/src/ObjectModel/ObjectModel.h +++ b/src/ObjectModel/ObjectModel.h @@ -9,25 +9,39 @@ #define SRC_OBJECTMODEL_OBJECTMODEL_H_ #include "RepRapFirmware.h" +#include <General/IPAddress.h> -#ifdef SUPPORT_OBJECT_MODEL +#if SUPPORT_OBJECT_MODEL typedef uint32_t ObjectModelFilterFlags; typedef uint8_t TypeCode; +constexpr TypeCode IsArray = 128; // this is or'ed in to a type code to indicate an array +constexpr TypeCode NoType = 0; // code for an invalid or unknown type + +// Forward declarations +class ObjectModelTableEntry; +class ObjectModel; + +union ExpressionValue +{ + float fVal; + int32_t iVal; + uint32_t uVal; + const char *sVal; + const ObjectModel *omVal; +}; // Dummy types, used to define type codes class Bitmap32 { }; class Enum32 { }; -// Forward declarations -class ObjectModelTableEntry; - class ObjectModel { public: enum ReportFlags : uint16_t { - shortForm = 1 + flagsNone, + flagShortForm = 1 }; ObjectModel(); @@ -35,6 +49,12 @@ public: // Construct a JSON representation of those parts of the object model requested by the user bool ReportAsJson(OutputBuffer *buf, const char *filter, ReportFlags rflags); + // Return the type of an object + TypeCode GetObjectType(const char *idString); + + // Get the value of an object when we don't know what its type is + TypeCode GetObjectValue(ExpressionValue& val, const char *idString); + // Get values of various types from the object model, returning true if successful template<class T> bool GetObjectValue(T& val, const char *idString); @@ -68,7 +88,6 @@ public: static const char* GetNextElement(const char *id); protected: - virtual const char *GetModuleName() const = 0; virtual const ObjectModelTableEntry *GetObjectModelTable(size_t& numEntries) const = 0; private: @@ -81,6 +100,7 @@ private: }; // Function template used to get constexpr type IDs +// Each type must return a unique type code in the range 1 to 127 template<class T> constexpr TypeCode TypeOf(); template<> constexpr TypeCode TypeOf<bool> () { return 1; } @@ -90,52 +110,75 @@ template<> constexpr TypeCode TypeOf<float>() { return 4; } template<> constexpr TypeCode TypeOf<Bitmap32>() { return 5; } template<> constexpr TypeCode TypeOf<Enum32>() { return 6; } template<> constexpr TypeCode TypeOf<ObjectModel>() { return 7; } +template<> constexpr TypeCode TypeOf<const char *>() { return 8; } +template<> constexpr TypeCode TypeOf<IPAddress>() { return 9; } #define TYPE_OF(_t) (TypeOf<_t>()) +// Entry to describe an array +class ObjectModelArrayDescriptor +{ +public: + size_t (*GetNumElements)(ObjectModel*); + void * (*GetElement)(ObjectModel*, size_t); +}; + // 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. -// Only const member functions are allowed in this class class ObjectModelTableEntry { public: + // Type declarations + // Flags field of a table entry enum ObjectModelEntryFlags : uint16_t { - none = 0, + none = 0, // nothing special live = 1, // fast changing data, included in common status response canAlter = 2, // we can alter this value - isArray = 4 // value is an array of the basic type }; + // Type of the function pointer in the table entry, that returns a pointer to the data typedef void *(*ParamFuncPtr_t)(ObjectModel*); + // Member data. This must be public so that we can brace-initialise table entries. + 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 + ObjectModelEntryFlags flags; // information about this value + + // Member functions. These must all be 'const'. + // Return true if this object table entry matches a filter or query bool Matches(const char *filter, ObjectModelFilterFlags flags) const; - // Add the value of this element to the buffer, returning true if it matched and we did + // See whether we should add the value of this element to the buffer, returning true if it matched the filter and we did add it bool ReportAsJson(OutputBuffer* buf, ObjectModel *self, const char* filter, ObjectModel::ReportFlags flags) const; + // Return the name of this field const char* GetName() const { return name; } + // Compare the name of this field with the filter string that we are trying to match int IdCompare(const char *id) const; + // Return true if this field is an object, not a primitive type bool IsObject() const { return type == TYPE_OF(ObjectModel); } + + // Follow the path specified by the ifString until we reach the end of it const ObjectModelTableEntry *FindLeafEntry(ObjectModel *self, const char *idString) const; - // Check the type is correct, call the function if necessary and return the pointer + // Check the type is correct, call the function and return the pointer void* GetValuePointer(ObjectModel *self, TypeCode t) const; - // Note: all data members must be public so that we can brace-initialise these. This doesn't matter because they are always 'const'. - const char * name; - ParamFuncPtr_t param; - TypeCode type; - ObjectModelEntryFlags flags; + // Private function to report a value of primitive type + static void ReportItemAsJson(OutputBuffer *buf, const char *filter, ObjectModel::ReportFlags flags, void *nParam, TypeCode type); }; +// Function to retrieve a value by searching the object model +// Returns true if success template<class T> bool ObjectModel::GetObjectValue(T& val, const char *idString) { - const ObjectModelTableEntry *e = FindObjectModelLeafEntry(idString); + const ObjectModelTableEntry * const e = FindObjectModelLeafEntry(idString); if (e == nullptr) { return false; @@ -149,12 +192,42 @@ template<class T> bool ObjectModel::GetObjectValue(T& val, const char *idString) return true; } +// Specialisation of above for float, allowing conversion from integer to float +template<> bool ObjectModel::GetObjectValue(float& val, const char *idString); + +// Specialisation of above for int, allowing conversion from unsigned to signed +template<> bool ObjectModel::GetObjectValue(int32_t& val, const char *idString); + template<class T> T* ObjectModel::GetObjectPointer(const char* idString) { const ObjectModelTableEntry *e = FindObjectModelLeafEntry(idString); return (e == nullptr) ? nullptr : (T*)(e->GetValuePointer(this, TYPE_OF(T))); } +// Use this macro to inherit form ObjectModel +#define INHERIT_OBJECT_MODEL : public ObjectModel + +// 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 override; \ + static const ObjectModelTableEntry objectModelTable[]; + +#define DEFINE_GET_OBJECT_MODEL_TABLE(_class) \ + const ObjectModelTableEntry *_class::GetObjectModelTable(size_t& numEntries) const \ + { \ + numEntries = ARRAY_SIZE(objectModelTable); \ + return objectModelTable; \ + } + +#define OBJECT_MODEL_FUNC_BODY(_class,_ret) [] (ObjectModel* arg) { _class * const self = static_cast<_class*>(arg); return (void *)(_ret); } +#define OBJECT_MODEL_FUNC_NOSELF(_ret) [] (ObjectModel* arg) { return (void *)(_ret); } + +#else + +#define INHERIT_OBJECT_MODEL // nothing +#define DECLARE_OBJECT_MODEL // nothing +#define DEFINE_GET_OBJECT_MODEL_TABLE // nothing + #endif #endif /* SRC_OBJECTMODEL_OBJECTMODEL_H_ */ |