This is my approach to the general cdev command parsing problem.
I have an abstract base class which supports get/set/monitor and derive
specific classes from this for all data types I need.
There is one static Attrib::execute function which finds the object and calls the get/set.
Virtual function dispatching does the rest.
I also provide an '=' operator so that in the code I can just say varQ = 1.2 , and monitor are
automatically triggered, time stamps inserted etc.
This works great, and adding a new monitorable variable is only 1 line of code.
The disadvantage is that each get/set/monitarable variable is a new object, which may be a
problem if you start to have 10^5 objects (i.e. for the model server)
-Johannes
// Objects that are get/set/monitored from cdev
// If possible, each class support the = operator, at which time monitors are triggered
#ifndef SLOW_Attrib_HH
#define SLOW_Attrib_HH
#include <time.h>
#include <cdevMonitorTable.h>
#include "StringHash.h"
#include "string.hh"
#include "list.hh"
class Attrib;
class MonitorAttrib;
typedef void (Attrib::*pAttribmf1)(cdevData*);
// Abstract base class for cdev device/attributes
class Attrib {
public:
Attrib();
Attrib(string);
Attrib(string, string);
virtual ~Attrib();
virtual void setDevice(string);
virtual void setDeviceAttribute(string, string);
virtual void insertCommand(string key, int);
virtual int executeCommand(string key, cdevData*);
virtual int executeMessage(cdevData*);
static Attrib* findDevice(string);
static Attrib* findDeviceAttribute(string, string);
static int execute(cdevMonitorTable *table, cdevMessage*, int &saveMessage, int &sendMessage);
virtual void setAttribute(MonitorAttrib *rhs); // add a dependant Attribute
protected:
string Device;
string Attribute;
StringHash Commands; // commands and messages etc.
LinkedListV Attribs; // dependent Attribs;
void triggerDependants();
void addCurrentTimeStamp(cdevData*);
void addTimeStamp(cdevData*);
void setTimeStamp();
private:
static StringHash Hash;
cdev_TS_STAMP timestamp; // set in operator=
};
class MonitorAttrib : public Attrib {
public:
MonitorAttrib();
MonitorAttrib(string, string);
virtual ~MonitorAttrib();
virtual void insertCommand(string key, int);
virtual int executeCommand(string key, cdevData*);
virtual int findCommandInteger(string key);
virtual void disableSet(); // do not allows cdev sets
virtual void triggerAlways(); // trigger even when the value did not change
void insertMonitor( cdevMonitorTable *table, cdevMessage *message);
void removeMonitor( cdevMonitorTable *table, cdevMessage *message);
virtual void triggerMonitor();
virtual int get(cdevData *); // in&out data
virtual int set(cdevData *);
virtual void setDeviceAttribute(string, string);
// virtual void loadFromDatabase();
static MonitorAttrib* findDeviceAttribute(string, string);
protected:
StringHash MonitorCommands; // commands and messages etc.
int EnableSet;
int TriggerAlways;
private:
cdevMonitorNode *Monitors;
static StringHash MonitorHash;
};
// Attribute class which holds an int
class IntAttrib : public MonitorAttrib {
public:
IntAttrib();
IntAttrib(string, string);
virtual int operator=(const int rhs);
virtual int operator!=(const int rhs);
inline operator int() {return Value;}
virtual int get(cdevData *);
virtual int set(cdevData *);
protected:
int Value;
};
// Attribute class which holds a pointer to an int
class pIntAttrib : public MonitorAttrib {
public:
pIntAttrib();
pIntAttrib(string, string);
int * operator=(int* rhs);
virtual int get(cdevData *);
virtual int set(cdevData *);
private:
int* Value;
};
// Attribute class which holds a double
class DoubleAttrib : public MonitorAttrib {
public:
DoubleAttrib();
DoubleAttrib(string, string);
double operator=(const double rhs);
inline operator double() {return Value;}
virtual int get(cdevData *);
virtual int set(cdevData *);
private:
double Value;
};
// Attribute class which holds a pointer to a double
class pDoubleAttrib : public MonitorAttrib {
public:
pDoubleAttrib();
pDoubleAttrib(string, string);
double* operator=(double* rhs);
virtual int get(cdevData *);
virtual int set(cdevData *);
private:
double* Value;
};
class DoubleVector {
public:
friend class DoubleVectorAttrib;
friend class LockMatrix;
DoubleVector();
DoubleVector(int);
~DoubleVector();
void reserve(int);
int length() { return size;}
double& operator[](int);
DoubleVector& operator*=(double);
DoubleVector& operator=(DoubleVector &rhs);
DoubleVector& operator=(double &rhs);
DoubleVector& operator=(cdevData &rhs);
int operator==(DoubleVector &rhs);
int operator==(double &rhs);
DoubleVector *range(int,int);
friend ostream& operator<<(ostream& s, DoubleVector& c);
double* getData() {return Data;}
private:
double *Data;
int size;
};
// Attribute class which holds a vector of doubles
class DoubleVectorAttrib : public MonitorAttrib {
public:
DoubleVectorAttrib();
~DoubleVectorAttrib();
DoubleVectorAttrib(string, string);
void reserve(int);
DoubleVector & operator=(DoubleVector &rhs);
DoubleVector & operator=(double &rhs);
double& operator[](int);
virtual int get(cdevData *);
virtual int set(cdevData *);
private:
DoubleVector Value;
};
// Attribute class which holds a string
class StringAttrib : public MonitorAttrib {
public:
StringAttrib();
StringAttrib(string, string);
string &operator=(const string & rhs);
inline operator string() {return Value;}
virtual int get(cdevData *);
virtual int set(cdevData *);
private:
string Value;
};
// Attribute class which holds a time_t
class TimeAttrib : public MonitorAttrib {
public:
TimeAttrib();
TimeAttrib(string, string);
virtual void setTime();
virtual int get(cdevData *);
virtual int set(cdevData *) {return -1;}
private:
time_t Value;
};
// Attribute class which holds a collection of strings
class StringListAttrib : public MonitorAttrib {
public:
StringListAttrib();
StringListAttrib(string, string);
int toCharHandle(char **&);
virtual void appendstring(string);
virtual void removestring(string);
int size() {return Value.get_count();}
virtual int get(cdevData *);
virtual int set(cdevData *);
private:
LinkedListV Value;
};
#endif