custom_function.cpp
Go to the documentation of this file.
1 #include "custom_function.h"
2 
3 #include <limits>
4 #include <QFile>
5 #include <QMessageBox>
6 #include <QElapsedTimer>
7 #include "lua_custom_function.h"
8 
10  _snippet(snippet)
11 , _linked_plot_name(snippet.linkedSource.toStdString())
12 , _plot_name(snippet.name.toStdString())
13 {
14  for( QString source: snippet.additionalSources){
15  _used_channels.push_back( source.toStdString() );
16  }
17 }
18 
20 {
21  initEngine();
22 }
23 
25 {
26  bool newly_added = false;
27 
28  auto dst_data_it = plotData.numeric.find(_plot_name);
29  if (dst_data_it == plotData.numeric.end())
30  {
31  dst_data_it = plotData.addNumeric(_plot_name);
32  newly_added = true;
33  }
34 
35  PlotData& dst_data = dst_data_it->second;
36  dst_data.clear();
37 
38  try
39  {
40  calculate(plotData, &dst_data);
41  }
42  catch (...)
43  {
44  if (newly_added)
45  {
46  plotData.numeric.erase(dst_data_it);
47  }
48  std::rethrow_exception(std::current_exception());
49  }
50 }
51 
53 {
54  return _snippet;
55 }
56 
57 void CustomFunction::calculate(const PlotDataMapRef& plotData, PlotData* dst_data)
58 {
59  auto src_data_it = plotData.numeric.find(_linked_plot_name);
60  if (src_data_it == plotData.numeric.end())
61  {
62  // failed! keep it empty
63  return;
64  }
65 
66  const PlotData& src_data = src_data_it->second;
67  if (src_data.size() == 0)
68  {
69  return;
70  }
71 
72  // clean up old data
73  dst_data->setMaximumRangeX(src_data.maximumRangeX());
74 
75  std::vector<const PlotData*> channel_data;
76  channel_data.reserve(_used_channels.size());
77 
78  for (const auto& channel : _used_channels)
79  {
80  auto it = plotData.numeric.find(channel);
81  if (it == plotData.numeric.end())
82  {
83  throw std::runtime_error("Invalid channel name");
84  }
85  const PlotData* chan_data = &(it->second);
86  channel_data.push_back(chan_data);
87  }
88 
89  double last_updated_stamp = -std::numeric_limits<double>::max();
90  if (dst_data->size() != 0)
91  {
92  last_updated_stamp = dst_data->back().x;
93  }
94 
95  for (size_t i = 0; i < src_data.size(); ++i)
96  {
97  if (src_data.at(i).x > last_updated_stamp)
98  {
99  dst_data->pushBack(calculatePoint(src_data, channel_data, i));
100  }
101  }
102 }
103 
104 const std::string& CustomFunction::name() const
105 {
106  return _plot_name;
107 }
108 
109 const std::string& CustomFunction::linkedPlotName() const
110 {
111  return _linked_plot_name;
112 }
113 
114 
115 QDomElement CustomFunction::xmlSaveState(QDomDocument& doc) const
116 {
117  return ExportSnippetToXML(_snippet, doc);
118 }
119 
121 {
123  return std::make_unique<LuaCustomFunction>(snippet);
124 }
125 
126 SnippetsMap GetSnippetsFromXML(const QString& xml_text)
127 {
128  if (xml_text.isEmpty()){
129  return {};
130  }
131 
132  QDomDocument doc;
133  QString parseErrorMsg;
134  int parseErrorLine;
135  if (!doc.setContent(xml_text, &parseErrorMsg, &parseErrorLine))
136  {
137  QMessageBox::critical(
138  nullptr, "Error",
139  QString("Failed to parse snippets (xml), error %1 at line %2").arg(parseErrorMsg).arg(parseErrorLine));
140  return {};
141  }
142  else
143  {
144  QDomElement snippets_element = doc.documentElement();
145  return GetSnippetsFromXML(snippets_element);
146  }
147 }
148 
149 SnippetsMap GetSnippetsFromXML(const QDomElement& snippets_element)
150 {
151  SnippetsMap snippets;
152 
153  for (auto elem = snippets_element.firstChildElement("snippet");
154  !elem.isNull();
155  elem = elem.nextSiblingElement("snippet") )
156  {
158  snippets.insert({ snippet.name, snippet });
159  }
160  return snippets;
161 }
162 
163 
164 QDomElement ExportSnippets(const SnippetsMap& snippets, QDomDocument& doc)
165 {
166  auto snippets_root = doc.createElement("snippets");
167 
168  for (const auto& it : snippets)
169  {
170  const auto& snippet = it.second;
171  auto element = ExportSnippetToXML(snippet, doc);
172  snippets_root.appendChild(element);
173  }
174  return snippets_root;
175 }
176 
177 SnippetData GetSnippetFromXML(const QDomElement &element)
178 {
180  snippet.linkedSource = element.firstChildElement("linkedSource").text().trimmed();
181  snippet.name = element.attribute("name");
182  snippet.globalVars = element.firstChildElement("global").text().trimmed();
183  snippet.function = element.firstChildElement("function").text().trimmed();
184 
185  auto additional_el = element.firstChildElement("additionalSources");
186  if( !additional_el.isNull() )
187  {
188  int count = 1;
189  auto tag_name = QString("v%1").arg(count);
190  auto source_el = additional_el.firstChildElement( tag_name );
191  while( !source_el.isNull() )
192  {
193  snippet.additionalSources.push_back( source_el.text() );
194  tag_name = QString("v%1").arg(++count);
195  source_el = additional_el.firstChildElement( tag_name );
196  }
197  }
198  return snippet;
199 }
200 
201 
202 QDomElement ExportSnippetToXML(const SnippetData &snippet, QDomDocument &doc)
203 {
204  auto element = doc.createElement("snippet");
205 
206  element.setAttribute("name", snippet.name);
207 
208  auto global_el = doc.createElement("global");
209  global_el.appendChild(doc.createTextNode(snippet.globalVars));
210  element.appendChild(global_el);
211 
212  auto equation_el = doc.createElement("function");
213  equation_el.appendChild(doc.createTextNode(snippet.function));
214  element.appendChild(equation_el);
215 
216  auto linked_el = doc.createElement("linkedSource");
217  linked_el.appendChild(doc.createTextNode(snippet.linkedSource));
218  element.appendChild(linked_el);
219 
220  if( snippet.additionalSources.size() > 0)
221  {
222  auto sources_el = doc.createElement("additionalSources");
223 
224  int count = 1;
225  for(QString curve_name: snippet.additionalSources)
226  {
227  auto tag_name = QString("v%1").arg(count++);
228  auto source_el = doc.createElement(tag_name);
229  source_el.appendChild(doc.createTextNode(curve_name));
230  sources_el.appendChild(source_el);
231  }
232 
233  element.appendChild(sources_el);
234  }
235 
236 
237  return element;
238 }
const Point & back() const
Definition: plotdata.h:139
const Point & at(size_t index) const
Definition: plotdata.h:97
std::vector< std::string > _used_channels
QString globalVars
std::map< QString, SnippetData > SnippetsMap
std::unordered_map< std::string, PlotData > numeric
Definition: plotdata.h:495
SnippetData GetSnippetFromXML(const QDomElement &element)
const std::string & name() const
QString linkedSource
QDomElement ExportSnippets(const SnippetsMap &snippets, QDomDocument &doc)
double maximumRangeX() const
Definition: plotdata.h:305
QString function
const std::string & linkedPlotName() const
constexpr size_t count()
Definition: core.h:960
const std::string _plot_name
#define max(A, B)
Definition: Socket.h:88
void calculate(const PlotDataMapRef &plotData, PlotData *dst_data)
std::shared_ptr< CustomFunction > CustomPlotPtr
void setMaximumRangeX(double max_range)
Definition: plotdata.h:299
SnippetsMap GetSnippetsFromXML(const QString &xml_text)
const SnippetData _snippet
const char * name
virtual size_t size() const
Definition: plotdata.h:92
detail::named_arg< Char, T > arg(const Char *name, const T &arg)
Definition: core.h:1656
static CustomPlotPtr createFromXML(QDomElement &element)
const SnippetData & snippet() const
const std::string _linked_plot_name
QDomElement ExportSnippetToXML(const SnippetData &snippet, QDomDocument &doc)
void pushBack(const Point &p)
Definition: plotdata.h:330
virtual PlotData::Point calculatePoint(const PlotData &src_data, const std::vector< const PlotData * > &channels_data, size_t point_index)=0
std::unordered_map< std::string, PlotData >::iterator addNumeric(const std::string &name)
Definition: plotdata.h:498
CustomFunction(const SnippetData &snippet)
QStringList additionalSources
QDomElement xmlSaveState(QDomDocument &doc) const
void calculateAndAdd(PlotDataMapRef &plotData)
virtual void initEngine()=0


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Dec 6 2020 03:47:33