Privacy
An open-source, flexible 3D physical simulation framework
DataWidget.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2011, 2012, DFKI GmbH Robotics Innovation Center
3  *
4  * This file is part of the MARS simulation framework.
5  *
6  * MARS is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License
8  * as published by the Free Software Foundation, either version 3
9  * of the License, or (at your option) any later version.
10  *
11  * MARS is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with MARS. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 #include "DataWidget.h"
22 #include "MainDataGui.h"
23 
24 #include <mars/data_broker/DataBrokerInterface.h>
25 
26 #include <QVBoxLayout>
27 
28 #include <cassert>
29 
30 namespace mars {
31 
32  namespace data_broker_gui {
33 
34  using data_broker::DataItem;
35  using data_broker::DataInfo;
36  using data_broker::DataBrokerInterface;
37 
39 
41  DataBrokerInterface *_dataBroker,
43  QWidget *parent) :
44  main_gui::BaseWidget(parent, cfg, "DataBrokerWidget"),
45  mainLib(mainLib), libManager(libManager),
46  pDialog(new main_gui::PropertyDialog(parent)),
47  dataBroker(_dataBroker),
48  ignore_change(0) {
49 
50  startTimer(250);
51 
52  setStyleSheet("padding:0px;");
53  QVBoxLayout *vLayout = new QVBoxLayout();
54  vLayout->setContentsMargins(1, 1, 1, 1);
55  pDialog->setStyleSheet("margin: 0px;");
56  vLayout->addWidget(pDialog);
57  setLayout(vLayout);
58  libManager->getLibrary("data_broker");
60  pDialog->setPropCallback(dynamic_cast<main_gui::PropertyCallback*>(this));
61  showAll = false;
62  showAllProperty = pDialog->addGenericProperty("data_broker/ShowAll",
63  QVariant::Bool, showAll);
64 
65  if(dataBroker) {
66  dataBroker->registerSyncReceiver(this, "data_broker", "newStream",
68  std::vector<DataInfo> infoList;
69  std::vector<DataInfo>::iterator it;
70  infoList = dataBroker->getDataList();
71 
72  for(it=infoList.begin(); it!=infoList.end(); ++it) {
73  if(it->flags & data_broker::DATA_PACKAGE_WRITE_FLAG) {
74  addParam(*it);
75  dataBroker->registerTimedReceiver(this, it->groupName, it->dataName,
76  "_REALTIME_", 250);
77  // dataBroker->registerAsyncReceiver(this, it->groupName, it->dataName);
78  }
79  }
80  }
81  }
82 
84  dataBroker->unregisterAsyncReceiver(this, "*", "*");
85  dataBroker->unregisterTimedReceiver(this, "*", "*", "_REALTIME_");
86  dataBroker->unregisterSyncReceiver(this, "data_broker", "newStream");
87  libManager->releaseLibrary("data_broker");
88  }
89 
90  void DataWidget::addParam(const DataInfo _info) {
91  addMutex.lock();
92  paramWrapper newParam;
93  newParam.info = _info;
94  newParam.dataPackage = dataBroker->getDataPackage(_info.dataId);
95  addList[_info.dataId] = newParam;
96 
97  addMutex.unlock();
98  }
99 
101  const data_broker::DataPackage &dataPackage,
102  int callbackParam) {
103  changeMutex.lock();
104  if(callbackParam == CALLBACK_NEW_STREAM) {
105  DataInfo newInfo;
106  dataPackage.get("groupName", &newInfo.groupName);
107  dataPackage.get("dataName", &newInfo.dataName);
108  dataPackage.get("dataId", (long*)&newInfo.dataId);
109  dataPackage.get("flags", (int*)&newInfo.flags);
111  addParam(newInfo);
113  newInfo.dataName, "_REALTIME_", 250);
114  // dataBroker->registerAsyncReceiver(this, newInfo.groupName, newInfo.dataName);
115  }
116  } else {
117  map<unsigned long, paramWrapper>::iterator it;
118  it = paramList.find(info.dataId);
119  if(it != paramList.end()) {
120  listMutex.lock();
121  // assert(it->second.dataPackage.size());
122  it->second.dataPackage = dataPackage;
123  listMutex.unlock();
124  changeList.insert(info.dataId);
125  }
126  }
127  changeMutex.unlock();
128  }
129 
130  void DataWidget::timerEvent(QTimerEvent* event) {
131  (void)event;
132 
133  string path;
134 
135  // go throud the add list
136  addMutex.lock();
137  ignore_change = true;
138  map<unsigned long, paramWrapper>::iterator it;
139  map<unsigned long, paramWrapper> tmpList;
140  DataItem *item;
141  //DataItem *item2;
142 
143  for(it=addList.begin(); it!=addList.end(); ++it) {
144  it->second.dataPackage = dataBroker->getDataPackage(it->second.info.dataId);
145  for(unsigned int i = 0; i < it->second.dataPackage.size(); ++i) {
146  std::map<QString, QVariant> attr;
147  attr["singleStep"] = 0.01;
148  attr["decimals"] = 7;
149  path = "";
150  path.append(it->second.info.groupName);
151  path.append("/");
152  path.append(it->second.info.dataName);
153  if(it->second.dataPackage.size() > 1) {
154  path.append("/");
155  path.append(it->second.dataPackage[i].getName());
156  }
157  item = &it->second.dataPackage[i];
158  QtVariantProperty *guiElem;
159  switch(item->type) {
161  guiElem = pDialog->addGenericProperty(path,
162  QVariant::Double,
163  item->f, &attr);
164  break;
166  guiElem = pDialog->addGenericProperty(path,
167  QVariant::Double,
168  item->d, &attr);
169  break;
171  guiElem = pDialog->addGenericProperty(path, QVariant::Int,
172  item->i);
173  break;
175  guiElem = pDialog->addGenericProperty(path, QVariant::Int,
176  (int)item->l);
177  break;
179  guiElem = pDialog->addGenericProperty(path, QVariant::Bool,
180  item->b);
181  break;
183  guiElem = pDialog->addGenericProperty(path, QVariant::String,
184  QString::fromStdString(item->s));
185  break;
186  default:
187  guiElem = 0;
188  }
189  if(guiElem &&
190  !(it->second.info.flags & data_broker::DATA_PACKAGE_WRITE_FLAG)) {
191  guiElem->setEnabled(false);
192  }
193  it->second.guiElements.push_back(guiElem);
194  if(!it->second.guiElements.empty()) {
195  listMutex.lock();
196  paramList[it->first] = it->second;
197  guiToWrapper[guiElem] = &paramList[it->first];//it->second;
198  //guiToWrapper[&it->second.guiElements] = it->second;
199  listMutex.unlock();
200  }
201  }
202 
203  if(it->second.guiElements.empty()) {
204  tmpList[it->first] = it->second;
205  }
206  }
207  addList.clear();
208  addList = tmpList;
209 
210  ignore_change = false;
211  addMutex.unlock();
212  // and check for updates
213  changeMutex.lock();
214  ignore_change = true;
215  while(changeList.size() > 0) {
216  it = paramList.find(*changeList.begin());
217  if(it != paramList.end() && !it->second.guiElements.empty()) {
218  for(unsigned int i = 0; i < it->second.guiElements.size(); ++i) {
219  QtVariantProperty *guiElem = it->second.guiElements[i];
220  if(!guiElem) continue;
221  if(!pDialog->isPropertyVisible(guiElem)) continue;
222  item = &it->second.dataPackage[i];
223  //item2 = &guiToWrapper[it->second.guiElements.front()]->dataPackage[i];
224  switch(item->type) {
226  guiElem->setValue(QVariant(item->d));
227  //item2->d = item->d;
228  break;
230  guiElem->setValue(QVariant(item->f));
231  //item2->f = item->f;
232  break;
234  guiElem->setValue(QVariant(item->i));
235  //item2->i = item->i;
236  break;
238  guiElem->setValue(QVariant((int)item->l));
239  //item2->l = item->l;
240  break;
242  guiElem->setValue(QVariant(item->b));
243  //item2->b = item->b;
244  break;
246  guiElem->setValue(QVariant(QString::fromStdString(item->s)));
247  //item2->s = item->s;
248  break;
250  break;
251  // don't supply a default case so that the compiler might warn
252  // us if we forget to handle a new enum value.
253  }
254  }
255  }
256  changeList.erase(changeList.begin());
257  }
258  ignore_change = false;
259  changeMutex.unlock();
260  }
261 
262  void DataWidget::valueChanged(QtProperty *property, const QVariant &value) {
263  if(ignore_change) return;
264  map<QtVariantProperty*, paramWrapper>::iterator it;
265  map<QtVariantProperty*, paramWrapper*>::iterator it3;
266  double dValue;
267  float fValue;
268  long lValue;
269  int iValue;
270  bool bValue;
271  string sValue;
272  DataItem *item;
273  //DataItem *item2;
274 
275  if(property == showAllProperty) {
276  std::vector<DataInfo> infoList;
277  std::vector<DataInfo>::iterator it;
278  bool newShowAll = value.toBool();
279  assert(newShowAll != showAll);
280  dataBroker->unregisterAsyncReceiver(this, "*", "*");
281  dataBroker->unregisterTimedReceiver(this, "*", "*", "_REALTIME_");
282  changeMutex.lock();
283  addMutex.lock();
284  listMutex.lock();
285  changeList.clear();
286  addList.clear();
287  //map<unsigned long, paramWrapper>::iterator foo;
288  map<QtVariantProperty*, paramWrapper*>::iterator bar;
289  for(bar = guiToWrapper.begin(); bar != guiToWrapper.end(); ++bar) {
290  pDialog->removeGenericProperty(bar->first);
291  }
292  paramList.clear();
293  guiToWrapper.clear();
294  listMutex.unlock();
295  addMutex.unlock();
296  changeMutex.unlock();
297 
298  showAll = newShowAll;
299 
300  infoList = dataBroker->getDataList();
301  for(it=infoList.begin(); it!=infoList.end(); ++it) {
302  if(newShowAll || it->flags & data_broker::DATA_PACKAGE_WRITE_FLAG) {
303  addParam(*it);
304  dataBroker->registerTimedReceiver(this, it->groupName, it->dataName,
305  "_REALTIME_", 250);
306  //dataBroker->registerAsyncReceiver(this, it->groupName, it->dataName);
307  }
308  }
309  return;
310  }
311 
312  it3 = guiToWrapper.find((QtVariantProperty*)property);
313  if(it3 != guiToWrapper.end()) {
314  int idx = 0;
315  std::vector<QtVariantProperty*>::iterator it2;
316  for(it2 = it3->second->guiElements.begin();
317  it2 != it3->second->guiElements.end() && *it2 != property;
318  ++it2, ++idx) /* do nothing */ ;
319 
320  item = &it3->second->dataPackage[idx];
321  //item2 = &paramList[it->second.info.dataId].dataPackage[idx];
322 
323  switch(item->type) {
325  dValue = value.toDouble();
326  if(dValue != item->d) {
327  item->d = dValue;
328  //item2->d = dValue;
329  }
330  break;
332  fValue = value.toFloat();
333  if(fValue != item->f) {
334  item->f = fValue;
335  //item2->f = fValue;
336  }
337  break;
339  lValue = value.toLongLong();
340  if(lValue != item->l) {
341  item->l = lValue;
342  //item2->l = lValue;
343  }
344  break;
346  iValue = value.toInt();
347  if(iValue != item->i) {
348  item->i = iValue;
349  //item2->i = iValue;
350  }
351  break;
353  bValue = value.toBool();
354  if(bValue != item->b) {
355  item->b = bValue;
356  //item2->b = iValue;
357  }
358  break;
360  sValue = value.toString().toStdString();
361  if(sValue != item->s) {
362  item->s = sValue;
363  //item2->s = sValue;
364  }
365  break;
367  break;
368  // don't supply a default case so that the compiler might warn
369  // us if we forget to handle a new enum value.
370  }
371  dataBroker->pushData(it3->second->info.dataId,
372  it3->second->dataPackage);
373  }
374  }
375 
376  void DataWidget::closeEvent(QCloseEvent *e) {
377  mainLib->destroyWindow(this);
378  }
379 
380  } // end of namespace data_broker_widget
381 
382 } // end of namespace mars
map< unsigned long, paramWrapper > addList
Definition: DataWidget.h:101
virtual bool unregisterAsyncReceiver(ReceiverInterface *receiver, const std::string &groupName, const std::string &dataName)=0
unregister a receiver from receiving callbacks for certain group/data
std::string dataName
A name describing this DataPackage within the group The groupName-dataName combination should be uniq...
Definition: DataInfo.h:64
void timerEvent(QTimerEvent *event)
Definition: DataWidget.cpp:130
main_gui::PropertyDialog * pDialog
Definition: DataWidget.h:80
class containing a single value.
Definition: DataItem.h:60
void receiveData(const mars::data_broker::DataInfo &info, const mars::data_broker::DataPackage &data_package, int callbackParam)
The DataBroker will call this method to notify the receiver of whenever the condition for which the r...
Definition: DataWidget.cpp:100
void setPropCallback(PropertyCallback *pc)
Sets the callback object.
Definition: tsort.c:44
virtual bool registerSyncReceiver(ReceiverInterface *receiver, const std::string &groupName, const std::string &dataName, int callbackParam=0)=0
register a receiver to receive a synchronous callback for a certain stream
mars::data_broker::DataBrokerInterface * dataBroker
Definition: DataWidget.h:93
void closeEvent(QCloseEvent *event)
Definition: DataWidget.cpp:376
virtual bool registerTimedReceiver(ReceiverInterface *receiver, const std::string &groupName, const std::string &dataName, const std::string &timerName, int updatePeriod, int callbackParam=0)=0
registers a receiver for a group/data with a timer
DataWidget(MainDataGui *mainLib, lib_manager::LibManager *libManager, mars::data_broker::DataBrokerInterface *_dataBroker, mars::cfg_manager::CFGManagerInterface *cfg, QWidget *parent=0)
Definition: DataWidget.cpp:40
void removeGenericProperty(QtVariantProperty *property)
Removes the property.
virtual bool unregisterTimedReceiver(ReceiverInterface *receiver, const std::string &groupName, const std::string &dataName, const std::string &timerName)=0
unregister a receiver from receiving callbacks from a timer for certain group/data ...
bool get(const std::string &itemName, T *val) const
gets the value of the DataItem with the given name
Definition: DataPackage.h:98
map< QtVariantProperty *, paramWrapper * > guiToWrapper
Definition: DataWidget.h:104
unsigned long dataId
A unique numeric identifier assigned by the DataBroker.
Definition: DataInfo.h:56
virtual const std::vector< DataInfo > getDataList(PackageFlag flag=DATA_PACKAGE_NO_FLAG) const =0
get a list of all DataInfo items currently in the DataBroker
std::string groupName
A name describing the group/category this belongs to.
Definition: DataInfo.h:60
lib_manager::LibManager * libManager
Definition: DataWidget.h:92
void setButtonBoxVisibility(bool visible)
Sets the visibility of the button box.
bool isPropertyVisible(QtProperty *prop) const
LibInterface * getLibrary(const std::string &libName)
Definition: LibManager.hpp:89
Copyright 2012, DFKI GmbH Robotics Innovation Center.
virtual unsigned long pushData(const std::string &groupName, const std::string &dataName, const DataPackage &dataPackage, const ReceiverInterface *producer, PackageFlag flags)=0
pushes a DataPackage into the DataBroker
virtual bool unregisterSyncReceiver(ReceiverInterface *receiver, const std::string &groupName, const std::string &dataName)=0
unregister a receiver from receiving callbacks for certain group/data
virtual void valueChanged(QtProperty *property, const QVariant &value)
Called every time a property has changed its value.
Definition: DataWidget.cpp:262
DataType type
the type of the DataItem
Definition: DataItem.h:68
virtual const DataPackage getDataPackage(unsigned long dataId) const =0
get the DataPackage with a given dataId
data_broker::DataPackage dataPackage
Definition: DataWidget.h:61
Class containing information about a DataPackage.
Definition: DataInfo.h:47
map< unsigned long, paramWrapper > paramList
Definition: DataWidget.h:102
A collection of DataItems.
Definition: DataPackage.h:44
set< unsigned long > changeList
Definition: DataWidget.h:100
The interface every DataBroker should implement.
void addParam(const mars::data_broker::DataInfo _info)
Definition: DataWidget.cpp:90
QtVariantProperty * addGenericProperty(const std::string &path, int type, const QVariant &value, std::map< QString, QVariant > *attributes=NULL, QStringList *options=NULL)
Creates a property.
data_broker::DataInfo info
Definition: DataWidget.h:60
ErrorNumber releaseLibrary(const std::string &libName)
Releases a previously acquired library.
Definition: LibManager.cpp:311