-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscxmlexternmonitor.h
143 lines (116 loc) · 6.49 KB
/
scxmlexternmonitor.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#ifndef SCXMLEXTERNMONITOR_H
#define SCXMLEXTERNMONITOR_H
#include <iostream>
#include <QLoggingCategory>
#include <QUdpSocket>
#include <QNetworkDatagram>
#include <QDomDocument>
#include <QDateTime>
#include <QRegExp>
#include <QJsonDocument>
#include <QJsonObject>
/*******************************/
/* !!! DEPRECATION WARNING !!! */
/*******************************/
/* !!! This SCXML monitor is deprecated !!! */
/* Use: https://github.com/alexzhornyak/ScxmlEditor-Tutorial/tree/master/Include/scxmlexternmonitor2.h */
#define MLOG(VAL) std::wcout << L ## #VAL << L"> " << QDateTime::currentDateTime().toString("HH:mm:ss.zzz").toStdWString() << " QtScxmlTester.exe "
typedef enum {
smttUnknown, smttAfterEnter, smttBeforeEnter, smttAfterExit, smttBeforeExit, smttStep, smttBeforeExecContent, smttAfterExecContent,
smttBeforeInvoke, smttAfterInvoke, smttBeforeUnInvoke, smttAfterUnInvoke, smttBeforeTakingTransition, smttAfterTakingTransition, smttMAXSIZE
}TScxmlMsgType;
struct Settings {
bool bScxmlMonitorLog = false;
// network
long nRemotePort = 11005;
long nLocalPort = 11001;
QHostAddress haRemoteHost = QHostAddress::LocalHost;
};
static QString g_ScxmlStateMachineName = "";
static Settings g_Settings;
static QUdpSocket g_Socket;
static const QRegExp rxEnterExit("^[^\\(\\)]*\\(0x[a-f0-9]*, name = \"([^\\(\\)]*)\"\\) (entering|exiting) states \\(([^\\(\\)]*)\\)$");
static const QRegExp rxSelectTransitionsEvent("^[^\\(\\)]*\\(0x[a-f0-9]*, name = \"([^\\(\\)]*)\"\\) selectTransitions with event (\\{[^\\{\\}]*\\})$");
static const QRegExp rxSelectEventlessTransition("^[^\\(\\)]*\\(0x[a-f0-9]*, name = \"([^\\(\\)]*)\"\\) selectEventlessTransitions$");
static const QRegExp rxBeforeInvoke("^[^\\(\\)]*\\(0x[a-f0-9]*, name = \"([^\\(\\)]*)\"\\) preparing to start [^\\(\\)]*\\(0x[a-f0-9]*, name = \"([^\\(\\)]*)\"\\)$");
static const QRegExp rxBeforeUnInvoke("^[^\\(\\)]*\\(0x[a-f0-9]*, name = \"([^\\(\\)]*)\"\\) exiting SCXML processing$");
void sendTestingMessage(const QString &sInterpreter, const QString &sName, const TScxmlMsgType AType) {
const QString sMsg = QString::number(AType) + "@" + sInterpreter + "@" + sName;
QByteArray ba;
ba+=sMsg;
g_Socket.writeDatagram(ba, g_Settings.haRemoteHost, static_cast<quint16>(g_Settings.nRemotePort));
}
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
switch (type) {
case QtDebugMsg:
case QtInfoMsg:
if (QString::compare(context.category, "qt.scxml.statemachine")==0) {
if (msg.contains("failed to parse") || msg.contains("had error")) {
MLOG(ERROR) << msg.toStdWString() << std::endl;
} else if (g_Settings.bScxmlMonitorLog) {
MLOG(INFO) << msg.toStdWString() << std::endl;
}
if (rxSelectEventlessTransition.indexIn(msg)!=-1) {
const int iCaptureCount = rxSelectEventlessTransition.captureCount();
if (iCaptureCount==1) {
sendTestingMessage(rxSelectEventlessTransition.capturedTexts()[1], "*", smttBeforeTakingTransition);
} else
MLOG(ERROR) << L"RegExp [selectEventlessTransitions] wait 1 captures, but got " << iCaptureCount << std::endl;
} else if (rxSelectTransitionsEvent.indexIn(msg)!=-1) {
const int iCaptureCount = rxSelectTransitionsEvent.captureCount();
if (iCaptureCount==2) {
const QString sInterpreter = rxSelectTransitionsEvent.capturedTexts()[1];
QJsonDocument d = QJsonDocument::fromJson( rxSelectTransitionsEvent.capturedTexts()[2].toUtf8());
QJsonObject docObj = d.object();
sendTestingMessage(sInterpreter, docObj.value("name").toString(), smttBeforeTakingTransition);
} else
MLOG(ERROR) << L"RegExp [SelectTransitionsEvent] wait 2 captures, but got " << iCaptureCount << std::endl;
} else if (rxEnterExit.indexIn(msg)!=-1) {
const int iCaptureCount = rxEnterExit.captureCount();
if (iCaptureCount==3) {
const QString sInterpreter = rxEnterExit.capturedTexts()[1];
const bool active = QString::compare(rxEnterExit.capturedTexts()[2], "entering") == 0;
const QStringList &states = rxEnterExit.capturedTexts()[3].split(",",Qt::SkipEmptyParts);
foreach (QString it_str, states) {
it_str.replace('\"', "");
sendTestingMessage(sInterpreter, it_str.trimmed(), active ? smttBeforeEnter : smttBeforeExit);
}
} else
MLOG(ERROR) << L"RegExp [Enter-Exit] wait 3 captures, but got " << iCaptureCount << std::endl;
} else if (rxBeforeInvoke.indexIn(msg)!=-1) {
const int iCaptureCount = rxBeforeInvoke.captureCount();
if (iCaptureCount==2) {
const QString sInterpreter = rxBeforeInvoke.capturedTexts()[1];
const QString sInvoke = rxBeforeInvoke.capturedTexts()[2];
sendTestingMessage(sInterpreter, sInvoke, smttBeforeInvoke);
} else
MLOG(ERROR) << L"RegExp [Before Invoke] wait 2 captures, but got " << iCaptureCount << std::endl;
} else if (rxBeforeUnInvoke.indexIn(msg)!=-1) {
const int iCaptureCount = rxBeforeUnInvoke.captureCount();
if (iCaptureCount==1) {
const QString sInvoke = rxBeforeUnInvoke.capturedTexts()[1];
// we are receiving info only about scxml processing,
// we will inform about UnInvoke only if invoke name differs from main statemachine name
if (g_ScxmlStateMachineName!=sInvoke) {
sendTestingMessage(g_ScxmlStateMachineName, sInvoke, smttBeforeUnInvoke);
}
} else
MLOG(ERROR) << L"RegExp [selectEventlessTransitions] wait 1 captures, but got " << iCaptureCount << std::endl;
}
} else {
MLOG(INFO) << msg.toStdWString() << std::endl;
}
break;
case QtWarningMsg:
MLOG(WARNING) << msg.toStdWString() << std::endl;
break;
case QtCriticalMsg:
case QtFatalMsg:
MLOG(ERROR) << msg.toStdWString() << std::endl;
break;
default:
MLOG(UNKNOWN) << msg.toStdWString() << std::endl;
}
}
#endif // SCXMLEXTERNMONITOR_H