git-svn-id: svn://db.shs.com.ru/libs@380 a8b55f48-bf90-11e4-a774-851b48703e85

This commit is contained in:
2018-05-22 13:49:16 +00:00
parent d3e81d5efa
commit 7a8dd9efba
28 changed files with 1052 additions and 137 deletions

View File

@@ -18,8 +18,8 @@ endif()
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${PIP_INCLUDES})
#file(GLOB HDRS_UTILS "*.h")
#file(GLOB CPPS_UTILS "*.cpp")
set(CPPS_UTILS "cdutils_core.cpp" "cdutils_types.cpp" "cdutils_parser.cpp" "cdutils_interface.cpp" "cdutils_k.cpp")
set(HDRS_UTILS "cdutils_core.h" "cdutils_types.h" "cdutils_parser.h" "cdutils_interface.h" "cdutils_k.h" "cdutils_protocol.h")
file(GLOB CPPS_UTILS "cdutils_*.cpp")
file(GLOB HDRS_UTILS "cdutils_*.h")
if (DEFINED ENV{QNX_HOST})
add_library(${PROJECT_NAME} STATIC ${CPPS_UTILS} ${HDRS_UTILS})
else()

55
cd_utils/cdutils_c.cpp Normal file
View File

@@ -0,0 +1,55 @@
#include "cdutils_c.h"
#include "cdutils_core.h"
using namespace CDUtils;
CInterface C;
CInterface::CInterface(): Interface(CDType::cdC) {
CONNECTU(core, C_Sended, this, sended);
CONNECTU(core, C_SendFail, this, sendFailed);
CONNECTU(core, C_Received, this, received);
CONNECTU(core, C_ReceiveFail, this, receiveFailed);
}
void CInterface::send() {
core->C_Send();
}
void CInterface::request() {
core->C_Request();
}
void CInterface::sendCommand(const CDType & c) {
core->sendCommand(c);
}
void CInterface::connect(const CDType & c, PIObject * o, Handler eh) {
core->registerCHandler(c, o, eh);
}
void CInterface::autoConnect(PIObject * o, const PIString & prefix) {
if (!o) return;
PIString cn = o->className();
if (!PIObject::__meta_data().contains(cn)) return;
PIMap<PIString, Handler> eh_map;
PIObject::__MetaData & md(PIObject::__meta_data()[cn]);
PIMap<const void * , __MetaFunc>::const_iterator it;
for (it = md.eh_func.constBegin(); it != md.eh_func.constEnd(); ++it) {
eh_map[it.value().func_name] = (Handler)it.value().addr;
//piCout << "func" << it.value().func_name;
}
PIVector<CDType * > cl = C.root().children();
piForeachC (CDType * c, cl) {
PIString cp = prefix + c->pathString().join("_");
if (cp.isEmpty()) continue;
if (!eh_map.contains(cp)) continue;
connect(*c, o, eh_map[cp]);
}
}

34
cd_utils/cdutils_c.h Normal file
View File

@@ -0,0 +1,34 @@
#ifndef CDUTILS_C_H
#define CDUTILS_C_H
#include "cdutils_interface.h"
namespace CDUtils {
class CInterface: public Interface
{
PIOBJECT(CDUtils::CInterface)
public:
CInterface();
EVENT(sended)
EVENT(sendFailed)
EVENT(received)
EVENT(receiveFailed)
EVENT1(keepNamesRequest, bool*, cn)
EVENT_HANDLER(void, send);
EVENT_HANDLER(void, request);
void sendCommand(const CDType & c);
void connect(const CDType & c, PIObject * o, Handler eh);
void autoConnect(PIObject * o, const PIString & prefix = PIStringAscii("c_"));
};
}
extern CDUtils::CInterface C;
#endif // CDUTILS_C_H

View File

@@ -64,6 +64,7 @@ CDCore::CDCore() {
/*PIString s(app_config);
connection.configureFromString(&s);
connection.start();*/
need_rebuild_x = x_pult_side = false;
k_.cd_type_ = CDType::cdK;
x_.cd_type_ = CDType::cdX;
c_.cd_type_ = CDType::cdC;
@@ -160,27 +161,44 @@ void CDCore::cd_send(CDSection * cd, CDPacketType pt, bool direct) {
void CDCore::initApp() {
init(appConfig());
init(appConfig(), false);
}
void CDCore::initPult() {
init(pultConfig());
init(pultConfig(), true);
}
void CDCore::init(const PIString & configuration) {
void CDCore::init(const PIString & configuration, bool pult) {
PIString c = configuration;
//piCoutObj << "init" << c;
connection.stop();
connection.removeAllDevices();
connection.configureFromString(&c);
connection.start();
x_pult_side = pult;
}
void CDCore::startPing() {
x_timer.start(1.0);
void CDCore::startX(double freq) {
x_timer.start(1000. / piMaxd(freq, 0.01));
}
void CDCore::sendCommand(const CDType & c) {
piCoutObj << "C_sendCommand" << c;
PIByteArray sba = makeHeader(CD_Command, 0);
sba << c.path();
sendDirect(sba);
}
void CDCore::registerCHandler(const CDType & c, PIObject * o, Handler h) {
PIString sp = pathToString(c.path());
if (sp.isEmpty() || !h) return;
piCout << "register" << sp;
c_handlers[sp] = OHPair(o, h);
}
@@ -237,6 +255,32 @@ void CDUtils::CDCore::K_DirectChange(PIDeque<int> path, PIString value) {
}
void CDCore::X_Send() {
piCoutObj << "X_Send";
cd_send(&x_, CD_XSend);
}
void CDCore::X_Request() {
piCoutObj << "X_Request";
PIByteArray sba = makeHeader(CD_XQuery, 0);
sendThreaded(sba);
}
void CDCore::C_Send() {
piCoutObj << "C_Send";
cd_send(&c_, CD_CSend);
}
void CDCore::C_Request() {
piCoutObj << "C_Request";
PIByteArray sba = makeHeader(CD_CQuery, 0);
sendThreaded(sba);
}
void CDCore::sendThread() {
if (send_data.size_s() < 4) return;
PacketHeader h;
@@ -250,17 +294,43 @@ void CDCore::sendThread() {
case CD_KQuery:
if (!ok) K_ReceiveFail();
break;
case CD_XSend:
if (ok) X_Sended();
else X_SendFail();
break;
case CD_XQuery:
if (!ok) X_ReceiveFail();
break;
case CD_CSend:
if (ok) C_Sended();
else C_SendFail();
break;
case CD_CQuery:
if (!ok) C_ReceiveFail();
break;
default: break;
}
}
void CDCore::xTimerTick() {
PacketHeader ph;
ph.type = CD_Ping;
ph.session_id = 0;
x_mutex.lock();
PIByteArray ba;
ba << ph;
if (x_pult_side) {
ba = makeHeader(CD_XRequest, 0);
if (need_rebuild_x) {
x_selected = x_.collectX();
need_rebuild_x = false;
}
ba << x_selected;
} else {
ba = makeHeader(CD_XValues, 0);
ba << x_selected;
piForeachC (PIDeque<int> & p, x_selected) {
x_[p].writeX(ba);
}
}
x_mutex.unlock();
connection.writeByName("cd", ba);
}
@@ -323,11 +393,72 @@ void CDCore::procReceivedPacket(PIByteArray & ba) {
ba >> p;
k_[p.path].setValue(p.value);
} break;
case CD_XRequest: {
x_mutex.lock();
x_selected.clear();
ba >> x_selected;
x_.setSelectedX(false);
piForeachC (PIDeque<int> & p, x_selected) {
x_[p].x_enabled = true;
}
x_mutex.unlock();
} break;
case CD_XValues: {
x_mutex.lock();
x_selected.clear();
ba >> x_selected;
piForeachC (PIDeque<int> & p, x_selected) {
x_[p].readX(ba);
}
x_mutex.unlock();
} break;
case CD_CQuery:
C_Send();
break;
case CD_CSend: {
piCoutObj << "C received";
PIByteArray c;
ba >> c;
c << uchar(0);
PIString s = PIString::fromUTF8((const char *)c.data());
PIIOString ios(&s);
cd_read(&c_, &ios);
C_Received();
} break;
case CD_Command: {
piCoutObj << "C command";
PIDeque<int> p;
ba >> p;
if (p.isEmpty()) return;
PIString sp = pathToString(p);
OHPair h = c_handlers.value(sp, OHPair(0, 0));
//piCoutObj << "found" << sp << h.first;
if (h.first && h.second) h.second(h.first);
} break;
default: break;
}
}
PIString CDCore::pathToString(const PIDeque<int> & p) {
PIString ret;
for (int i = 0; i < p.size_s(); ++i) {
if (!ret.isEmpty()) ret += ".";
ret << p[i];
}
return ret;
}
PIDeque<int> CDCore::stringToPath(const PIString & p) {
PIDeque<int> ret;
PIStringList sl = p.split(".");
piForeachC (PIString & s, sl)
ret << s.toInt();
return ret;
}
void CDUtils::CDCore::dataReceived(const PIString & from, const PIByteArray & data) {
//piCoutObj << "dataReceived" << from << data.size();
PIIODevice * d = connection.deviceByName("cd");

View File

@@ -27,6 +27,7 @@ class CDCore: public PIObject
friend class __Core_Initializer__;
friend class CDSection;
friend class Interface;
friend class XInterface;
public:
static CDCore * instance();
@@ -39,6 +40,22 @@ public:
EVENT_HANDLER(void, K_Request);
EVENT_HANDLER2(void, K_DirectChange, PIDeque<int>, path, PIString, value);
EVENT(X_Sended)
EVENT(X_SendFail)
EVENT(X_Received)
EVENT(X_ReceiveFail)
EVENT(X_ChangedGlobal)
EVENT_HANDLER(void, X_Send);
EVENT_HANDLER(void, X_Request);
EVENT(C_Sended)
EVENT(C_SendFail)
EVENT(C_Received)
EVENT(C_ReceiveFail)
EVENT(C_ChangedGlobal)
EVENT_HANDLER(void, C_Send);
EVENT_HANDLER(void, C_Request);
void cd_write (CDSection * cd, PIIODevice * d);
void cd_read (CDSection * cd, PIIODevice * d);
void cd_parse (CDSection * cd, PIIODevice * d);
@@ -47,13 +64,17 @@ public:
void cd_send (CDSection * cd, CDPacketType pt, bool direct = false);
void initApp();
void initPult();
void init(const PIString & configuration);
void startPing();
void init(const PIString & configuration, bool pult = false);
void startX(double freq = 20.);
void sendCommand(const CDType & c);
void registerCHandler(const CDType & c, PIObject * o, Handler h);
bool inProgress() {return sendt.isRunning();}
CDSection & k() {return k_;}
CDSection * root(CDType::cdT cdt);
PIString typeLetter(CDType::cdT cdt);
static PIString pathToString(const PIDeque<int> & p);
static PIDeque<int> stringToPath(const PIString & p);
static PIString pultConfig() {return PIString(pult_config);}
static PIString appConfig() {return PIString(app_config);}
@@ -72,6 +93,8 @@ private:
void sendThreaded(PIByteArray & ba);
void procReceivedPacket(PIByteArray & ba);
typedef PIPair<PIObject * , Handler> OHPair;
static const char app_config[], pult_config[];
PIConnection connection;
PIDataTransfer datatr;
@@ -79,6 +102,10 @@ private:
PIThread sendt;
PITimer x_timer;
CDSection k_, x_, c_;
PIMutex x_mutex;
PIVector<PIDeque<int> > x_selected;
PIMap<PIString, OHPair> c_handlers;
bool need_rebuild_x, x_pult_side;
};

View File

@@ -9,6 +9,7 @@ using namespace CDUtils;
Interface::Interface(CDType::cdT type_) {
core = CDCore::instance();
s = core->root(type_);
type = type_;
//piCoutObj << (void*)this << core;
file_ = core->typeLetter(type_) + PIStringAscii(".dat");
file_size = 0;
@@ -108,11 +109,6 @@ void Interface::reinitConnection(const PIString &configuration) {
}
void Interface::startPing() {
core->startPing();
}
void Interface::write(PIIODevice * d) {
core->cd_write(s, d);
}

View File

@@ -32,11 +32,11 @@ public:
int count(bool recursive = true) const;
const PIString file() const {return file_;}
int fileSize() const {return file_size;}
CDType::cdT cdType() const {return type;}
void setFileName(const PIString & _file);
bool configure(const PIString & config);
void reinitConnection(const PIString & configuration);
void startPing();
void write(PIIODevice * d);
void read(PIIODevice * d);
void parse(PIIODevice * d);
@@ -63,4 +63,4 @@ protected:
}
#endif // CDUTILS_K_H
#endif // CDUTILS_INTERFACE_H

View File

@@ -14,8 +14,11 @@ enum CDPacketType {CD_Ping,
CD_XQuery,
CD_XSend,
CD_XRequest,
CD_XValues,
CD_CQuery,
CD_CSend,
CD_Command,
};

View File

@@ -14,9 +14,11 @@ CDType::CDType() {
index_ = -1;
value_d = 0.;
value_i = 0;
value_b = calculated = false;
value_b = calculated = x_enabled = false;
cd_type_ = cdNull;
parent = 0;
avg_size = 1;
mode_ = X_Current;
// debug_cnt = cdtype_debug_cnt;
// cdtype_debug_cnt++;
// piCout << "[CDType]" << "create Null" << debug_cnt;
@@ -36,8 +38,10 @@ CDType::CDType(int i, const PIString & n, const PIString & t, const PIString & v
value_i = v.toInt();
value_b = v.toBool();
cd_type_ = cd_t;
calculated = false;
calculated = x_enabled = false;
parent = 0;
avg_size = 1;
mode_ = X_Current;
if (type_ == "e") {
enum_values = parseEnumComment(comment_);
// piCout << enum_values.size() << enum_values;
@@ -51,17 +55,18 @@ CDType::CDType(int i, const PIString & n, const PIString & t, const PIString & v
}
CDType &CDType::operator =(double x) {
CDType & CDType::operator =(double x) {
value_d = x;
value_i = x;
value_b = x > 0.;
if (mode_ == X_All_Avg) {
avg_h << x;
double val = 0;
if (avg_h.size_s() >= avg_size) {
for (int i=0; i<avg_h.size_s(); i++) {
for (int i = 0; i < avg_h.size_s(); i++)
val += avg_h[i];
}
val /= avg_h.size();
avg_h.pop_front();
avg_h.clear();
}
if (history.size() < cd_x_history_max_size)
history << val;
@@ -99,6 +104,52 @@ void CDType::setFormula(const PIString & f) {
}
PIStringList CDType::pathString() const {
PIStringList ret;
CDSection * ps = CDCore::instance()->root(cd_type_);
if (!ps) return ret;
for (int i = 0; i < path_.size_s() - 1; ++i) {
ps = &(ps->section(path_[i]));
if (!ps->alias.isEmpty()) ret << ps->alias;
else ret << PIString::fromNumber(path_[i]);
}
if (!name_.isEmpty()) ret << name_;
else ret << PIString::fromNumber(index_);
return ret;
}
void CDType::readX(PIByteArray & ba) {
if (ba.size() < 5) return;
uchar t(0); ba >> t;
switch ((XMode)t) {
case X_Current:
ba >> value_d;
value_i = value_d;
value_b = value_d > 0.;
break;
case X_All_Avg:
ba >> history;
break;
default: break;
}
}
void CDType::writeX(PIByteArray & ba) {
ba << uchar(mode_);
switch (mode_) {
case X_Current:
ba << value_d;
break;
case X_All_Avg:
ba << history;
break;
default: break;
}
}
bool CDType::calculate(PIEvaluator * e, PIVector<const CDType * > stack) {
if (stack.contains(this)) {
error_ = "Circular dependencies: ";
@@ -436,8 +487,8 @@ void CDSection::read(const void * ep) {
break;
case CDType::cdX:
c = CDType(id, e->getValue("name").value(), PIString(), PIString(), PIString() , e->getValue("name").comment(), cd_type_);
c.setXMode((CDType::XMode)e->getValue("mode").value().toInt());
c.setAvg((CDType::XMode)e->getValue("avg").value().toInt());
c.setXMode((CDType::XMode)e->getValue("mode", int(CDType::X_Current)).value().toInt());
c.setAvg((CDType::XMode)e->getValue("avg", 1).value().toInt());
break;
case CDType::cdC:
c = CDType(id, e->getValue("name").value(), PIString(), PIString(), PIString() , e->getValue("name").comment(), cd_type_);
@@ -601,6 +652,30 @@ void CDSection::calculateRecursive(PIEvaluator * e) {
}
void CDSection::setSelectedX(bool yes) {
PIMap<int, CDType>::iterator i;
for (i = cd.begin(); i != cd.end(); ++i)
i.value().x_enabled = yes;
PIMap<int, CDSection>::iterator j;
for (j = s.begin(); j != s.end(); ++j)
j.value().setSelectedX(yes);
}
PIVector<PIDeque<int> > CDSection::collectX() const {
PIVector<PIDeque<int> > ret;
PIMap<int, CDType>::const_iterator i;
for (i = cd.begin(); i != cd.end(); ++i) {
if (i.value().x_enabled)
ret << i.value().path();
}
PIMap<int, CDSection>::const_iterator j;
for (j = s.constBegin(); j != s.constEnd(); ++j)
ret << j.value().collectX();
return ret;
}
void CDSection::makePath(PIDeque<int> p) {
PIDeque<int> tp;
PIMap<int, CDType>::iterator i;

View File

@@ -8,8 +8,8 @@
class PIIODevice;
class PIEvaluator;
class CD_Pult;
class CDKItem;
class CDKItemModel;
class CDItem;
class CDItemModel;
namespace CDUtils {
@@ -27,6 +27,7 @@ class CDType {
friend class CDSection;
friend class CDCore;
friend class Interface;
friend class XInterface;
public:
enum cdT {cdNull, cdK, cdX, cdC};
enum XMode {X_Current, X_All_Avg};
@@ -53,10 +54,15 @@ public:
void setEnumValues(const PIVariantTypes::Enum & ev) {enum_values = ev;}
const PIString & errorString() const {return error_;}
PIDeque<int> path() const {return path_;}
PIStringList pathString() const;
void setXMode(XMode mode) {mode_ = mode;}
void setAvg(int avg) {avg_size = avg;}
XMode xmode() const {return mode_;}
int avg() const {return avg_size;}
bool isSelectedX() const {return x_enabled;}
void readX(PIByteArray & ba);
void writeX(PIByteArray & ba);
protected:
bool calculate(PIEvaluator * e, PIVector<const CDType * > stack = PIVector<const CDType * >());
@@ -70,7 +76,7 @@ protected:
PIDeque<int> path_;
double value_d;
int value_i;
bool value_b, calculated;
bool value_b, calculated, x_enabled;
PIVector<double> history;
PIVector<double> avg_h;
int avg_size;
@@ -81,9 +87,10 @@ protected:
class CDSection {
friend class CDCore;
friend class Interface;
friend class XInterface;
friend class ::CD_Pult;
friend class ::CDKItem;
friend class ::CDKItemModel;
friend class ::CDItem;
friend class ::CDItemModel;
public:
CDSection(CDType::cdT type_ = CDType::cdNull);
@@ -125,6 +132,8 @@ protected:
bool isSameStructure(CDSection & v);
void prepareCalculate();
void calculateRecursive(PIEvaluator * e);
void setSelectedX(bool yes);
PIVector<PIDeque<int> > collectX() const;
PIMap<int, CDType> cd;
mutable PIMap<int, CDSection> s;

39
cd_utils/cdutils_x.cpp Normal file
View File

@@ -0,0 +1,39 @@
#include "cdutils_x.h"
#include "cdutils_core.h"
using namespace CDUtils;
XInterface X;
XInterface::XInterface(): Interface(CDType::cdX) {
CONNECTU(core, X_Sended, this, sended);
CONNECTU(core, X_SendFail, this, sendFailed);
CONNECTU(core, X_Received, this, received);
CONNECTU(core, X_ReceiveFail, this, receiveFailed);
}
void XInterface::send() {
core->X_Send();
}
void XInterface::request() {
core->X_Request();
}
void XInterface::setEnabled(const CDType & x, bool en) {
CDType & t((*s)[x.path()]);
if (t.cd_type() != CDType::cdX) return;
core->x_mutex.lock();
t.x_enabled = en;
core->need_rebuild_x = true;
core->x_mutex.unlock();
}
void XInterface::start(double freq) {
core->startX(freq);
}

37
cd_utils/cdutils_x.h Normal file
View File

@@ -0,0 +1,37 @@
#ifndef CDUTILS_X_H
#define CDUTILS_X_H
#include "cdutils_interface.h"
namespace CDUtils {
class XInterface: public Interface
{
PIOBJECT(CDUtils::XInterface)
public:
XInterface();
EVENT(sended)
EVENT(sendFailed)
EVENT(received)
EVENT(receiveFailed)
EVENT1(keepNamesRequest, bool*, xn)
EVENT_HANDLER(void, send);
EVENT_HANDLER(void, request);
void enable(const CDType & x) {setEnabled(x, true);}
void disable(const CDType & x) {setEnabled(x, false);}
void setEnabled(const CDType & x, bool en);
void setDisabled(const CDType & x, bool dis) {setEnabled(x, !dis);}
void start(double freq = 20.);
};
}
extern CDUtils::XInterface X;
#endif // CDUTILS_X_H

View File

@@ -1,7 +1,10 @@
#include "cdutils_k.h"
#include "cdutils_x.h"
#include "cdutils_c.h"
#include "cdutils_core.h"
#include "cdtest.h"
#include "pip.h"
#include <D:/k_description.h>
using namespace CDUtils;
@@ -13,6 +16,7 @@ class Core : public PIObject
CDCore::instance()->initApp();
// piCout << "testCore";
CONNECTU(&t, tickEvent, this, timerDone);
CONNECTU(&C, received, this, crecv);
t.start(1000);
}
@@ -44,14 +48,21 @@ class Core : public PIObject
}
void test() {
piCout << "count" << K.count();
/*piCout << "count" << K.count();
piCout << K[First];
piCout << K[Second];
piCout << K[Second];*/
}
EVENT_HANDLER(void, ksend) {piCout << "sended k";}
EVENT_HANDLER(void, krecv) {piCout << "received k";}
EVENT_HANDLER(void, crecv) {
piCout << "received c";
C.connect(C.section(KD::Logs).section(KD::Spec).section(KD::Formats)[KD::Binary], this, HANDLER(cmd));
C.autoConnect(this);
}
EVENT_HANDLER(void, timerDone) {test();}
EVENT_HANDLER(void, cmd) {piCout << "command cmd";}
EVENT_HANDLER(void, c_Pause) {piCout << "command pause";}
EVENT_HANDLER(void, c_Spectrometer_Connection) {piCout << "command spec_conn";}
private:
PIFile rf;