Actually added the files for msgPrintControl
This commit is contained in:
133
src/msgPrintControl.h
Normal file
133
src/msgPrintControl.h
Normal file
@@ -0,0 +1,133 @@
|
||||
#ifndef msgPrintControl_H
|
||||
#define msgPrintControl_H
|
||||
|
||||
#include <asynDriver.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
/**
|
||||
* @brief Class to identify a message print location. See the docstring of
|
||||
* `msgPrintControl` on how to use this key.
|
||||
*
|
||||
*/
|
||||
class msgPrintControlKey {
|
||||
public:
|
||||
std::string controller_;
|
||||
// -1 is a non-axis specific message
|
||||
int axisNo_;
|
||||
const char *functionName_;
|
||||
int line_;
|
||||
|
||||
msgPrintControlKey(char *controller_, int axisNo, const char *fileName,
|
||||
int line);
|
||||
|
||||
bool operator==(const msgPrintControlKey &other) const {
|
||||
return axisNo_ == other.axisNo_ && line_ == other.line_ &&
|
||||
strcmp(functionName_, other.functionName_) == 0 &&
|
||||
controller_ == other.controller_;
|
||||
}
|
||||
|
||||
void format(char *buffer, size_t bufferSize);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Implementation of the hash functionality for msgPrintControlKey
|
||||
*
|
||||
*/
|
||||
namespace std {
|
||||
template <> struct hash<msgPrintControlKey> {
|
||||
size_t operator()(const msgPrintControlKey &obj) const {
|
||||
// Combine the hashes of the members (x and y)
|
||||
size_t h1 = std::hash<std::string>{}(obj.controller_);
|
||||
size_t h2 = hash<int>{}(obj.axisNo_);
|
||||
size_t h3 = std::hash<const char *>{}(obj.functionName_);
|
||||
size_t h4 = hash<int>{}(obj.line_);
|
||||
// Combine the hashes (simple XOR and shifting technique)
|
||||
return h1 ^ (h2 << 1) ^ (h3 << 2) ^ (h4 << 3);
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
/**
|
||||
* @brief Class to control the number of repetitions of error messages
|
||||
*
|
||||
* This class is used to prevent excessive repetitions of identical error
|
||||
* messages. For example, if the communication between a controller and an
|
||||
* axis fails, a corresponding error message is created in each poll. This
|
||||
* could "flood" the IOC shell with noise. To prevent this, this class keeps
|
||||
* track of the number of subsequent error message repetition. Each message is
|
||||
* uniquely identified by "msgPrintControlKey". The function shouldBePrinted
|
||||
* can be used in order to see if a message should be printed or not:
|
||||
*
|
||||
* ```
|
||||
* const char* controller = "MCU" // Name of the controller
|
||||
* int axisNo = 0; // Number of the axis
|
||||
* bool wantToPrint = evaluateConditions(...); *
|
||||
* if (msgPrintControl.shouldBePrinted(controller, axisNo, __PRETTY_FUNCTION__,
|
||||
* __LINE__, wantToPrint)) { asynPrint(...)
|
||||
* }
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
class msgPrintControl {
|
||||
public:
|
||||
msgPrintControl(size_t maxRepetitions);
|
||||
|
||||
/**
|
||||
* @brief Checks if the error message associated with "key" has been printed
|
||||
* more than "maxRepetitions_" times in a row. If yes, returns false,
|
||||
* otherwise true. Counter is reset if wantToPrint is false.
|
||||
*
|
||||
* If the conditions for printing a message are met, "wantToPrint" must be
|
||||
* set to true. The function then checks if "maxRepetitions_" has been
|
||||
* exceeded. If yes, the function returns no, indicating that the message
|
||||
* should not be printed. If no, the number of repetitions stored in the map
|
||||
* is incremented and the function returns true, indicating that the message
|
||||
* should be printed.
|
||||
*
|
||||
* If the conditions for printing a message are not met, "wantToPrint" must
|
||||
* be set to false. This resets the map entry.
|
||||
*
|
||||
* @param key Key associated with the message, used to
|
||||
* identify individual messages
|
||||
* @param wantToPrint If the message associated with key should be
|
||||
* printed, this value should be true, otherwise false.
|
||||
* @return bool If true, the message should be printed, if
|
||||
* false, it should not.
|
||||
*/
|
||||
bool shouldBePrinted(msgPrintControlKey &key, bool wantToPrint,
|
||||
asynUser *pasynUser);
|
||||
|
||||
/**
|
||||
* @brief Like `shouldBePrinted(msgPrintControlKey key, bool wantToPrint)`,
|
||||
* but constructs the key from the first four arguments.
|
||||
*
|
||||
* @param controller_
|
||||
* @param axisNo
|
||||
* @param fileName
|
||||
* @param line
|
||||
* @param wantToPrint
|
||||
* @return true
|
||||
* @return false
|
||||
*/
|
||||
bool shouldBePrinted(char *controller, int axisNo, const char *functionName,
|
||||
int line, bool wantToPrint, asynUser *pasynUser);
|
||||
|
||||
void resetCount(msgPrintControlKey &key);
|
||||
|
||||
/**
|
||||
* @brief Maximum number of times a message is printed before it is
|
||||
* suppressed.
|
||||
*
|
||||
*/
|
||||
size_t maxRepetitions_;
|
||||
|
||||
char *getSuffix();
|
||||
|
||||
private:
|
||||
std::unordered_map<msgPrintControlKey, size_t> map_;
|
||||
char suffix_[200] = {0};
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user