Changeset 11360
- Timestamp:
- 07/12/11 15:29:14 (13 years ago)
- Location:
- fact
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
fact/Evidence/GUI.cc
r11088 r11360 1 2 1 /* ============================================================ 3 2 … … 28 27 29 28 // Check if history service available 30 if (Hist == NULL || Hist->GetFormat() == NULL) { 29 if (strcmp(Service, "Edd/Rate_kBSec") == 0) Format = "F"; 30 else if (Hist == NULL || Hist->GetFormat() == NULL) { 31 31 QMessageBox::warning(NULL, "Edd Message", QString("Could not retrieve history for service ") + Service ,QMessageBox::Ok); 32 32 } … … 44 44 M->setStatusBar(new QStatusBar(M)); 45 45 M->setAttribute(Qt::WA_DeleteOnClose); 46 M->setWindowTitle("Edd History - " + QString(Service)); 46 47 47 48 QWidget *W; … … 63 64 QString Status; 64 65 65 if (Index != -1) Name = Name + " (" + QString::number(Index) + ")";66 if (Index != -1) Name = Name + "[" + QString::number(Index) + "]"; 66 67 67 68 if (Time == -1) Status = QString("%1: unavailable").arg(Name); … … 89 90 setFrame(false); 90 91 setAttribute(Qt::WA_DeleteOnClose); 91 setText("connecting..."); 92 93 // Connect to DIM handler 94 if (connect(Handler, SIGNAL(YEP(QString, int, QByteArray, QString, QString)), SLOT(Update(QString, int, QByteArray, QString, QString)), Qt::QueuedConnection) == false) { 95 printf("Failed connection for %s\n", Name.toAscii().data()); 96 } 97 92 QPalette Pal = palette(); 93 Pal.setColor(QPalette::Base, Qt::lightGray); 94 setPalette(Pal); 95 98 96 // Context menu 99 97 Menu = new QMenu(this); … … 103 101 104 102 // Subscribe to service 105 Handler->Subscribe(Name );103 Handler->Subscribe(Name, this, Index); 106 104 } 107 105 … … 109 107 EddLineDisplay::~EddLineDisplay() { 110 108 111 Handler->Unsubscribe(ServiceName );109 Handler->Unsubscribe(ServiceName, this); 112 110 } 113 111 114 112 // Update widget 115 void EddLineDisplay::Update(QString Name, int Time, QByteArray, QString Format, QString Text) { 116 117 if (ServiceName != Name) return; 113 void EddLineDisplay::Update(const QString &, int Time, const QByteArray &, const QString &Format, const QString &Text, int) { 118 114 119 115 // Check if service available 120 116 QPalette Pal = palette(); 121 if (!SetStatus(this, Name, Time, Format, Index)) {117 if (!SetStatus(this, ServiceName, Time, Format, Index)) { 122 118 setText("n/a"); 123 119 Pal.setColor(QPalette::Base, Qt::lightGray); … … 128 124 129 125 // Message service backgound colour determined by severity 130 if ( Name.endsWith("/Message")) {126 if (ServiceName.endsWith("/Message")) { 131 127 switch (Text.section(' ', 0, 0).toInt()) { 132 128 case 0: Pal.setColor(QPalette::Base, Qt::white); break; … … 136 132 default: break; 137 133 } 138 Text = Text.section(' ', 1); 139 } 140 else if (Format[0].toUpper() != 'C' && Format != "I:1;C") Text = Text.section(' ', Index, Index); 141 142 if (!ShowAsTime) setText(Text); 134 setText(Text.section(' ', 1)); 135 } 136 else if (!ShowAsTime) setText(Text); 143 137 else setText(QDateTime::fromTime_t(Text.toInt()).toString()); 144 138 … … 162 156 163 157 // If not, open new plot 164 EddLineDisplay::MenuOpenHistory();158 MenuOpenHistory(); 165 159 } 166 160 … … 335 329 connect(this, SIGNAL(legendClicked (QwtPlotItem *)), SLOT(LegendClicked(QwtPlotItem *))); 336 330 337 // Connect to DIM handler338 if (connect(Handler, SIGNAL(YEP(QString, int, QByteArray, QString, QString)), SLOT(Update(QString, int, QByteArray, QString, QString)), Qt::QueuedConnection) == false) {339 printf("Failed connection for %s\n", Service.toAscii().data());340 }341 342 331 // Additonal context menu items 343 332 QAction* Action = Menu->addAction("Paste service", this, SLOT(MenuPasteService())); … … 380 369 381 370 N.Name = Name; 382 N.Signal = NewCurve(Name+" ("+QString::number(Index)+")");371 N.Signal = NewCurve(Name+"["+QString::number(Index)+"]"); 383 372 N.Index = Index; 384 373 List.append(N); … … 404 393 } 405 394 Handler->DropHistory(Name); 406 Handler->Subscribe(Name );395 Handler->Subscribe(Name, this, Index); 407 396 408 397 SingleShot->start(100); … … 410 399 411 400 // Update widget (must happen in GUI thread) 412 void EddPlot::Update( QString Name, int Time, QByteArray, QString Format, QString Text) {413 414 for (int ItemNo=0; ItemNo<List.size(); ItemNo++) if (List[ItemNo].Name == Name) {401 void EddPlot::Update(const QString &Name, int Time, const QByteArray &, const QString &Format, const QString &Text, int Index) { 402 403 for (int ItemNo=0; ItemNo<List.size(); ItemNo++) if (List[ItemNo].Name==Name && List[ItemNo].Index==Index) { 415 404 416 405 // Append data if service available 417 406 if (SetStatus(this, Name, Time, Format)) { 418 QString Txt = Text; 419 Txt = Txt.section(' ', List[ItemNo].Index, List[ItemNo].Index); 420 AddPoint(ItemNo, Time, atof(Txt.toAscii().data())); 407 //QString Txt = Text; 408 //Txt = Txt.section(' ', List[ItemNo].Index, List[ItemNo].Index); 409 //AddPoint(ItemNo, Time, atof(Txt.toAscii().data())); 410 AddPoint(ItemNo, Time, atof(Text.toAscii().data())); 421 411 } 422 412 … … 479 469 480 470 setAxisScale(QwtPlot::xBottom, time(NULL)-60*60, time(NULL)+60); 481 setAxisAutoScale(QwtPlot::yLeft);471 //setAxisAutoScale(QwtPlot::yLeft); 482 472 replot(); 483 473 } … … 486 476 487 477 setAxisScale(QwtPlot::xBottom, time(NULL)-24*3600, time(NULL)+3600); 488 setAxisAutoScale(QwtPlot::yLeft);478 //setAxisAutoScale(QwtPlot::yLeft); 489 479 replot(); 490 480 } … … 495 485 496 486 for (int i=0; i<List.size(); i++) if (List[i].Signal == Curve) { 497 Handler->Unsubscribe(List[i].Name );487 Handler->Unsubscribe(List[i].Name, this); 498 488 List.removeAt(i); 499 489 } … … 926 916 Accumulate = true; 927 917 928 // Connect to DIM handler929 if (connect(Handler, SIGNAL(YEP(QString, int, QByteArray, QString, QString)), SLOT(Update(QString, int, QByteArray, QString, QString)), Qt::QueuedConnection) == false) {930 printf("Failed connection for %s\n", Name.toAscii().data());931 }932 933 918 if (!Pure) { 934 919 // Get history for this service … … 947 932 948 933 // DIM client 949 Handler->Subscribe(Name );934 Handler->Subscribe(Name, this); 950 935 } 951 936 … … 953 938 EddText::~EddText() { 954 939 955 Handler->Unsubscribe(Name );940 Handler->Unsubscribe(Name, this); 956 941 } 957 942 958 943 959 944 // Update widget (must happen in GUI thread) 960 void EddText::Update(QString Name, int Time, QByteArray, QString Format, QString Text) { 961 962 if (this->Name != Name) return; 945 void EddText::Update(const QString &, int Time, const QByteArray &, const QString &Format, const QString &Text, int) { 946 963 947 QPalette Pal = palette(); 964 948 … … 992 976 EddDim::EddDim() { 993 977 994 Mutex = new QMutex(QMutex::Recursive);995 978 Volume = 0; 996 979 Period = 10; 980 Mutex = new QMutex(QMutex::Recursive); 997 981 998 982 // Timer to calculate data rates … … 1002 986 1003 987 // Connect to DIM handler 1004 if (connect(this, SIGNAL(INT(QString, int, QByteArray, QString , QString)), SLOT(Update(QString, int, QByteArray, QString, QString))) == false) {988 if (connect(this, SIGNAL(INT(QString, int, QByteArray, QString)), SLOT(Update(QString, int, QByteArray, QString))) == false) { 1005 989 printf("Failed connection in EddDim()\n"); 1006 990 } 1007 1008 // To ensure responsiveness of GUI, subscriptions handled only when no GUI events (timeout 0)1009 Timer = new QTimer(this);1010 connect(Timer, SIGNAL(timeout()), SLOT(MakeSubscriptions()));1011 Timer->start();1012 991 } 1013 992 … … 1017 996 QList<QString> L = HistoryList.keys(); 1018 997 for(int i=0; i<L.size(); i++) delete HistoryList[L[i]].HistClass; 1019 1020 998 delete Mutex; 1021 999 } 1022 1000 1023 // Subscribe to DIM service (actual subscription handled in worker thread below)1024 void EddDim::Subscribe(QString Name ) {1001 // Subscribe to DIM service 1002 void EddDim::Subscribe(QString Name, class EddWidget *Instance, int Index) { 1025 1003 1026 1004 // Lock before accessing list 1027 1005 QMutexLocker Locker(Mutex); 1028 WaitingList.append(Name); 1029 } 1030 1031 // Subscriptions handled only when no GUI events waiting (launched by timer, see constructor) 1032 void EddDim::MakeSubscriptions() { 1033 1034 // Lock before accessing list 1035 QMutexLocker Locker(Mutex); 1036 1037 if (WaitingList.isEmpty()) return; 1038 1039 QString Name = WaitingList.first(); 1040 WaitingList.removeFirst(); 1041 1042 // If already subscribed to service, increase usage count 1006 1007 // Check if already subscribed to service 1043 1008 if (ServiceList.contains(Name)) { 1044 ServiceList[Name].Count++; 1045 //YEP(Name, ServiceList[Name].TimeStamp, ServiceList[Name].ByteArray, ServiceList[Name].Format, ServiceList[Name].Text); 1009 ServiceList[Name].Subscribers[Instance] = Index; 1010 if (Index>=0 && Index<ServiceList[Name].Items.size()) Instance->Update(Name, ServiceList[Name].TimeStamp, ServiceList[Name].ByteArray, ServiceList[Name].Format, ServiceList[Name].Items[Index]); 1011 else Instance->Update(Name, ServiceList[Name].TimeStamp, ServiceList[Name].ByteArray, ServiceList[Name].Format, ServiceList[Name].Text); 1012 1046 1013 return; 1047 1014 } … … 1050 1017 ServiceList[Name].ByteArray = QByteArray(); 1051 1018 ServiceList[Name].TimeStamp = -1; 1052 ServiceList[Name]. Count = 1;1019 ServiceList[Name].Subscribers[Instance] = Index; 1053 1020 ServiceList[Name].DIMService = new DimStampedInfo(Name.toAscii().data(), INT_MAX, NO_LINK, this); 1054 1021 } 1055 1022 1056 1023 1057 // Unsubs ribe from DIM service1058 void EddDim::Unsubscribe(QString Name ) {1024 // Unsubscribe from DIM service 1025 void EddDim::Unsubscribe(QString Name, class EddWidget *Instance) { 1059 1026 1060 1027 // Lock before accessing list 1061 1028 QMutexLocker Locker(Mutex); 1062 1029 1063 if (ServiceList.contains(Name)) ServiceList[Name].Count--; 1064 1065 if (ServiceList[Name].Count == 0) { 1030 if (!ServiceList.contains(Name)) return; 1031 1032 if (ServiceList[Name].Subscribers.contains(Instance)) { 1033 ServiceList[Name].Subscribers.remove(Instance); 1034 } 1035 1036 if (ServiceList[Name].Subscribers.isEmpty()) { 1066 1037 delete ServiceList[Name].DIMService; 1067 1038 ServiceList.remove(Name); 1068 1039 return; 1069 1040 } 1041 } 1042 1043 // Ignore service in update 1044 void EddDim::Ignore(QString Name, bool Ignore) { 1045 1046 QMutexLocker Locker(&IgnoreMutex); 1047 1048 IgnoreMap[Name] = Ignore; 1070 1049 } 1071 1050 … … 1118 1097 float Rate = Volume/1024.0/Period; 1119 1098 Volume = 0; 1120 YEP("Edd/Rate_kBSec", time(NULL), QByteArray::number(Rate), "F", QString::number(Rate)); 1121 } 1122 1123 // Force reemit of all buffered DIM data (work around for widget update problem) 1124 void EddDim::ForceEmit() { 1099 1100 // No unlock because Mutex is recursive 1101 Update("Edd/Rate_kBSec", time(NULL), QByteArray((char *) &Rate, sizeof(Rate)), "F"); 1102 } 1103 1104 1105 // Store service information for usage by Subscribe(), update statistics and emit signal to widgets 1106 void EddDim::Update(QString Name, int Time, QByteArray Data, QString Format) { 1125 1107 1126 1108 // Lock before accessing list 1127 1109 QMutexLocker Locker(Mutex); 1128 1110 1129 QMap<QString, struct Item>::const_iterator i = ServiceList.constBegin(); 1130 1131 while (i != ServiceList.constEnd()) { 1132 YEP(i.key(), i.value().TimeStamp, i.value().ByteArray, i.value().Format, i.value().Text); 1133 ++i; 1134 } 1135 } 1136 1137 // Store service information for usage by Subscribe(), update statistics and emit signal to widgets 1138 void EddDim::Update(QString Name, int Time, QByteArray Data, QString Format, QString Text) { 1139 1140 // Lock before accessing list 1141 QMutexLocker Locker(Mutex); 1111 Volume += Data.size(); 1142 1112 1143 1113 // Store service data 1144 1114 if (ServiceList.contains(Name)) { 1145 ServiceList[Name].TimeStamp = Time; 1146 ServiceList[Name].ByteArray = Data; 1147 ServiceList[Name].Format = Format; 1148 ServiceList[Name].Text = Text; 1149 } 1150 1151 // Emit signal to all widgets 1152 YEP(Name, Time, Data, Format, Text); 1153 } 1154 1155 // Handling of DIM service update 1156 // No locking allowed. Signal triggers only EddDim::Update() when the main event loop is idle. 1115 ServiceList[Name].TimeStamp = Time; 1116 ServiceList[Name].ByteArray = Data; 1117 ServiceList[Name].Format = Format; 1118 ServiceList[Name].Text = QString::fromStdString(EvidenceServer::ToString(Format.toAscii().data(), Data.data(), Data.size())); 1119 ServiceList[Name].Items = ServiceList[Name].Text.split(" "); 1120 1121 QMap<class EddWidget *, int>::const_iterator i = ServiceList[Name].Subscribers.constBegin(); 1122 while (i != ServiceList[Name].Subscribers.constEnd()) { 1123 if (i.value() >=0 && i.value() < ServiceList[Name].Items.size()) i.key()->Update(Name, Time, Data, Format, ServiceList[Name].Items[i.value()], i.value()); 1124 else i.key()->Update(Name, Time, Data, Format, ServiceList[Name].Text, i.value()); 1125 i++; 1126 } 1127 } 1128 } 1129 1130 // Handling of DIM service update (Data asynchronouly send to EddDim::Update()) 1157 1131 void EddDim::infoHandler() { 1158 1132 1133 QMutexLocker Locker(&IgnoreMutex); 1134 bool Ignore = IgnoreMap[getInfo()->getName()]; 1135 Locker.unlock(); 1136 1159 1137 if (!EvidenceServer::ServiceOK(getInfo())) INT(getInfo()->getName(), -1); 1160 else { 1161 // Signal to EddDim::Update() 1162 INT(getInfo()->getName(), getInfo()->getTimestamp(), QByteArray((char *) getInfo()->getData(), 1163 getInfo()->getSize()), getInfo()->getFormat(), QString::fromStdString(EvidenceServer::ToString(getInfo()->getFormat(), getInfo()->getData(), getInfo()->getSize()))); 1164 // No mutex protection for Volume (otherwise must be in Update()) 1165 Volume += getInfo()->getSize(); 1166 } 1138 else if (!Ignore) INT(getInfo()->getName(), getInfo()->getTimestamp(), QByteArray((char *) getInfo()->getData(), getInfo()->getSize()), getInfo()->getFormat()); 1167 1139 } 1168 1140 -
fact/Evidence/GUI.h
r11088 r11360 34 34 bool SetStatus(QWidget *, QString, int, QString, int = -1); 35 35 36 // General Edd Widget: has Update() method called by DIM interface 37 class EddWidget { 38 39 public: 40 virtual void Update(const QString &, int, const QByteArray &, const QString &, const QString &, int=-1) = 0; 41 }; 42 36 43 // Base class for Edd plot 37 44 // DeleteCurve() is pure virtual and needs to be implemented iin the application class … … 97 104 98 105 // General indicator for DIM service 99 class EddLineDisplay: public QLineEdit {106 class EddLineDisplay: public QLineEdit, public EddWidget { 100 107 Q_OBJECT 101 108 … … 112 119 113 120 public: 114 EddLineDisplay(QString, int= 0, QWidget * = NULL);121 EddLineDisplay(QString, int=-1, QWidget * = NULL); 115 122 ~EddLineDisplay(); 123 void Update(const QString &, int, const QByteArray &, const QString &, const QString &, int = -1); 116 124 117 125 bool ShowAsTime; 118 126 119 127 private slots: 120 void Update(QString, int, QByteArray, QString, QString);121 128 void contextMenuEvent(QContextMenuEvent *); 122 129 void MenuOpenHistory(); … … 143 150 144 151 // Graph class for history display 145 class EddPlot: public EddBasePlot {152 class EddPlot: public EddBasePlot, public EddWidget { 146 153 Q_OBJECT 147 154 … … 190 197 void AddService(QString, int = 0); 191 198 void DeleteCurve(QwtPlotCurve *); 192 193 private slots: 194 void Update(QString, int, QByteArray, QString, QString); 199 void Update(const QString &, int, const QByteArray &, const QString &, const QString &, int = -1); 200 201 private slots: 195 202 void LegendClicked(QwtPlotItem *); 196 203 void MenuPasteService(); … … 201 208 202 209 // Text history and output class 203 class EddText: public QTextEdit {210 class EddText: public QTextEdit, public EddWidget { 204 211 Q_OBJECT 205 212 … … 211 218 EddText(QString, bool = false, QWidget * = NULL); 212 219 ~EddText(); 220 void Update(const QString &, int, const QByteArray &, const QString &, const QString &, int = -1); 213 221 214 222 bool Accumulate; 215 216 private slots:217 void Update(QString, int, QByteArray, QString, QString);218 223 }; 219 224 … … 226 231 struct Item { 227 232 DimStampedInfo *DIMService; 228 int Count;233 QMap<class EddWidget *, int> Subscribers; 229 234 int TimeStamp; 230 235 QByteArray ByteArray; 231 236 QString Format; 232 237 QString Text; 238 QStringList Items; 233 239 }; 234 240 QMap<QString, struct Item> ServiceList; 235 QMutex *Mutex;236 QList<QString> WaitingList;241 QMap<QString, bool> IgnoreMap; 242 QMutex *Mutex, IgnoreMutex; 237 243 238 244 struct HistItem { … … 249 255 250 256 private slots: 251 void Update(QString, int, QByteArray, QString , QString);257 void Update(QString, int, QByteArray, QString); 252 258 void UpdateStatistics(); 253 void MakeSubscriptions();254 259 255 260 public: … … 257 262 ~EddDim(); 258 263 259 void Subscribe(QString); 260 void Unsubscribe (QString); 264 void Subscribe(QString, class EddWidget *, int = -1); 265 void Unsubscribe (QString, class EddWidget *); 266 void Ignore (QString, bool); 261 267 class EvidenceHistory *GetHistory(QString); 262 268 void DropHistory(QString); 263 void ForceEmit();264 269 265 270 signals: 266 void YEP(QString, int, QByteArray = QByteArray(), QString = QString(), QString = QString()); 267 void INT(QString, int, QByteArray = QByteArray(), QString = QString(), QString = QString()); 271 void INT(QString, int, QByteArray = QByteArray(), QString = QString()); 268 272 }; 269 273 -
fact/tools/Edd/Edd.cc
r11189 r11360 111 111 112 112 // Update event buffer 113 void EventScope::Update(QString Name, int Time, QByteArray Data, QString Format, QString) { 114 115 if (Name != this->Name) return; 113 void EventScope::Update(const QString &, int Time, const QByteArray &Data, const QString &Format, const QString &, int) { 116 114 117 115 // Check if service available 118 116 if (!SetStatus(this, Name, Time, Format)) return; 119 117 if (Data.size() < (int) sizeof(RunHeader)) return; 120 121 // Disconnect while processing to avoid queing of events122 disconnect(Handler, SIGNAL(YEP(QString, int, QByteArray, QString, QString)), this, SLOT(Update(QString, int, QByteArray, QString, QString)));118 119 // Ignore further data while processing this one 120 Handler->Ignore(Name, true); 123 121 124 122 // Clear temporary file and write event data to this file … … 132 130 // Open temporary raw data file 133 131 OpenRawFile(File.fileName()); 134 135 // Reconnect after processing 136 connect(Handler, SIGNAL(YEP(QString, int, QByteArray, QString, QString)), SLOT(Update(QString, int, QByteArray, QString, QString))); 132 133 134 // Process all pending events, then allow data again 135 QApplication::processEvents(); 136 Handler->Ignore(Name, false); 137 137 } 138 138 … … 191 191 192 192 // Display first event 193 NewEventNum( 0);193 NewEventNum(DAQPage->Channel->value()); 194 194 } 195 195 … … 316 316 void EventScope::SetActive(bool State) { 317 317 318 if (State && !Active) { 319 Handler->Subscribe(DRSBoard+"/EventData"); 320 connect(Handler, SIGNAL(YEP(QString, int, QByteArray, QString, QString)), SLOT(Update(QString, int, QByteArray, QString, QString))); 321 } 322 if (!State && Active) { 323 Handler->Unsubscribe(DRSBoard+"/EventData"); 324 disconnect(Handler, SIGNAL(YEP(QString, int, QByteArray, QString, QString)), this, SLOT(Update(QString, int, QByteArray, QString, QString))); 325 } 318 if (State && !Active) Handler->Subscribe(DRSBoard+"/EventData", this, -1); 319 if (!State && Active) Handler->Unsubscribe(DRSBoard+"/EventData", this); 320 326 321 Active = State; 327 322 } … … 929 924 connect(Timer, SIGNAL(timeout()), this, SLOT(CheckAlarm())); 930 925 Timer->start(5000); 931 932 // Force update of all widgets constructed (in thread for GUI responsiveness)933 QtConcurrent::run(Handler, &EddDim::ForceEmit);934 926 } 935 927 -
fact/tools/Edd/Edd.h
r11088 r11360 11 11 12 12 // Event oscilloscope 13 class EventScope: public EddBasePlot, public PixelMap {13 class EventScope: public EddBasePlot, public PixelMap, public EddWidget { 14 14 Q_OBJECT 15 15 … … 34 34 EventScope(class TP_DAQ *, QWidget * = NULL); 35 35 ~EventScope(); 36 36 37 void Update(const QString &, int, const QByteArray &, const QString &, const QString &, int=-1); 37 38 void UpdateFirst(int, int, int); 38 39 void AddTrace(int, int, int); … … 43 44 44 45 private slots: 45 void Update(QString, int, QByteArray, QString, QString);46 46 void PlotTraces(); 47 47 void DeleteCurve(QwtPlotCurve *);
Note:
See TracChangeset
for help on using the changeset viewer.