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 {
12 }
13 
15 {
16  _snippet = snippet;
17  _linked_plot_name = snippet.linked_source.toStdString();
18  _plot_name = snippet.alias_name.toStdString();
19 
20  _used_channels.clear();
21  for (QString source : snippet.additional_sources)
22  {
23  _used_channels.push_back(source.toStdString());
24  }
25 }
26 
28 {
29  // This cause a crash during streaming for reasons that are not 100% clear.
30  // initEngine();
31 }
32 
34 {
35  bool newly_added = false;
36 
37  auto dst_data_it = src_data.numeric.find(_plot_name);
38  if (dst_data_it == src_data.numeric.end())
39  {
40  dst_data_it = src_data.addNumeric(_plot_name);
41  newly_added = true;
42  }
43 
44  PlotData& dst_data = dst_data_it->second;
45  std::vector<PlotData*> dst_vector = { &dst_data };
46  dst_data.clear();
47 
48  setData(&src_data, {}, dst_vector);
49 
50  try
51  {
52  calculate();
53  }
54  catch (...)
55  {
56  if (newly_added)
57  {
58  plotData()->numeric.erase(dst_data_it);
59  }
60  std::rethrow_exception(std::current_exception());
61  }
62 }
63 
65 {
66  return _snippet;
67 }
68 
70 {
71  auto dst_data = _dst_vector.front();
72 
73  auto data_it = plotData()->numeric.find(_linked_plot_name);
74  if (data_it == plotData()->numeric.end())
75  {
76  // failed! keep it empty
77  return;
78  }
79  _src_vector.clear();
80  _src_vector.push_back(&data_it->second);
81 
82  for (const auto& channel : _used_channels)
83  {
84  auto it = plotData()->numeric.find(channel);
85  if (it == plotData()->numeric.end())
86  {
87  throw std::runtime_error("Invalid channel name");
88  }
89  const PlotData* chan_data = &(it->second);
90  _src_vector.push_back(chan_data);
91  }
92 
93  const PlotData* main_data_source = _src_vector.front();
94 
95  // clean up old data
96  dst_data->setMaximumRangeX(main_data_source->maximumRangeX());
97 
98  double last_updated_stamp = std::numeric_limits<double>::lowest();
99  if (dst_data->size() != 0)
100  {
101  last_updated_stamp = dst_data->back().x;
102  }
103 
104  std::vector<PlotData::Point> points;
105  for (size_t i = 0; i < main_data_source->size(); ++i)
106  {
107  if (main_data_source->at(i).x > last_updated_stamp)
108  {
109  points.clear();
110  calculatePoints(_src_vector, i, points);
111 
112  for (PlotData::Point const& point : points)
113  {
114  dst_data->pushBack(point);
115  }
116  }
117  }
118 }
119 
120 bool CustomFunction::xmlSaveState(QDomDocument& doc, QDomElement& parent_element) const
121 {
122  parent_element.appendChild(ExportSnippetToXML(_snippet, doc));
123  return true;
124 }
125 
126 bool CustomFunction::xmlLoadState(const QDomElement& parent_element)
127 {
128  setSnippet(GetSnippetFromXML(parent_element));
129  return true;
130 }
131 
132 SnippetsMap GetSnippetsFromXML(const QString& xml_text)
133 {
134  if (xml_text.isEmpty())
135  {
136  return {};
137  }
138 
139  QDomDocument doc;
140  QString parseErrorMsg;
141  int parseErrorLine;
142  if (!doc.setContent(xml_text, &parseErrorMsg, &parseErrorLine))
143  {
144  QMessageBox::critical(nullptr, "Error",
145  QString("Failed to parse snippets (xml), error %1 at line %2")
146  .arg(parseErrorMsg)
147  .arg(parseErrorLine));
148  return {};
149  }
150  else
151  {
152  QDomElement snippets_element = doc.documentElement();
153  return GetSnippetsFromXML(snippets_element);
154  }
155 }
156 
157 SnippetsMap GetSnippetsFromXML(const QDomElement& snippets_element)
158 {
159  SnippetsMap snippets;
160 
161  for (auto elem = snippets_element.firstChildElement("snippet"); !elem.isNull();
162  elem = elem.nextSiblingElement("snipp"
163  "et"))
164  {
165  SnippetData snippet = GetSnippetFromXML(elem);
166  snippets.insert({ snippet.alias_name, snippet });
167  }
168  return snippets;
169 }
170 
171 QDomElement ExportSnippets(const SnippetsMap& snippets, QDomDocument& doc)
172 {
173  auto snippets_root = doc.createElement("snippets");
174 
175  for (const auto& it : snippets)
176  {
177  const auto& snippet = it.second;
178  auto element = ExportSnippetToXML(snippet, doc);
179  snippets_root.appendChild(element);
180  }
181  return snippets_root;
182 }
183 
184 SnippetData GetSnippetFromXML(const QDomElement& element)
185 {
186  SnippetData snippet;
187  snippet.linked_source = element.firstChildElement("linked_source").text().trimmed();
188  snippet.alias_name = element.attribute("name");
189  snippet.global_vars = element.firstChildElement("global").text().trimmed();
190  snippet.function = element.firstChildElement("function").text().trimmed();
191 
192  auto additional_el = element.firstChildElement("additional_sources");
193  if (!additional_el.isNull())
194  {
195  int count = 1;
196  auto tag_name = QString("v%1").arg(count);
197  auto source_el = additional_el.firstChildElement(tag_name);
198  while (!source_el.isNull())
199  {
200  snippet.additional_sources.push_back(source_el.text());
201  tag_name = QString("v%1").arg(++count);
202  source_el = additional_el.firstChildElement(tag_name);
203  }
204  }
205  return snippet;
206 }
207 
208 QDomElement ExportSnippetToXML(const SnippetData& snippet, QDomDocument& doc)
209 {
210  auto element = doc.createElement("snippet");
211 
212  element.setAttribute("name", snippet.alias_name);
213 
214  auto global_el = doc.createElement("global");
215  global_el.appendChild(doc.createTextNode(snippet.global_vars));
216  element.appendChild(global_el);
217 
218  auto equation_el = doc.createElement("function");
219  equation_el.appendChild(doc.createTextNode(snippet.function));
220  element.appendChild(equation_el);
221 
222  auto linked_el = doc.createElement("linked_source");
223  linked_el.appendChild(doc.createTextNode(snippet.linked_source));
224  element.appendChild(linked_el);
225 
226  if (snippet.additional_sources.size() > 0)
227  {
228  auto sources_el = doc.createElement("additional_sources");
229 
230  int count = 1;
231  for (QString curve_name : snippet.additional_sources)
232  {
233  auto tag_name = QString("v%1").arg(count++);
234  auto source_el = doc.createElement(tag_name);
235  source_el.appendChild(doc.createTextNode(curve_name));
236  sources_el.appendChild(source_el);
237  }
238 
239  element.appendChild(sources_el);
240  }
241 
242  return element;
243 }
PJ::TransformFunction::setData
virtual void setData(PlotDataMapRef *data, const std::vector< const PlotData * > &src_vect, std::vector< PlotData * > &dst_vect)
Definition: transform_function.cpp:22
PJ::TimeseriesBase
Definition: timeseries.h:16
lua_custom_function.h
ExportSnippetToXML
QDomElement ExportSnippetToXML(const SnippetData &snippet, QDomDocument &doc)
Definition: custom_function.cpp:208
ExportSnippets
QDomElement ExportSnippets(const SnippetsMap &snippets, QDomDocument &doc)
Definition: custom_function.cpp:171
CustomFunction::_snippet
SnippetData _snippet
Definition: custom_function.h:83
PJ::PlotDataMapRef::addNumeric
TimeseriesMap::iterator addNumeric(const std::string &name, PlotGroup::Ptr group={})
Definition: plotdata.cpp:51
GetSnippetsFromXML
SnippetsMap GetSnippetsFromXML(const QString &xml_text)
Definition: custom_function.cpp:132
SnippetData::linked_source
QString linked_source
Definition: custom_function.h:24
arg
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
Definition: core.h:1875
CustomFunction::reset
void reset() override
Definition: custom_function.cpp:27
CustomFunction::calculate
void calculate() override
Definition: custom_function.cpp:69
CustomFunction::xmlSaveState
bool xmlSaveState(QDomDocument &doc, QDomElement &parent_element) const override
Override this method to save the status of the plugin to XML.
Definition: custom_function.cpp:120
PJ::TransformFunction::_src_vector
std::vector< const PlotData * > _src_vector
Definition: transform_function.h:78
PJ::PlotDataBase::clear
virtual void clear()
Definition: plotdatabase.h:213
CustomFunction::setSnippet
void setSnippet(const SnippetData &snippet)
Definition: custom_function.cpp:14
PJ::PlotDataMapRef::numeric
TimeseriesMap numeric
Numerical timeseries.
Definition: plotdata.h:39
SnippetData::additional_sources
QStringList additional_sources
Definition: custom_function.h:25
CustomFunction::calculatePoints
virtual void calculatePoints(const std::vector< const PlotData * > &src_data, size_t point_index, std::vector< PlotData::Point > &new_points)=0
detail::count
constexpr auto count() -> size_t
Definition: core.h:1222
custom_function.h
SnippetData::alias_name
QString alias_name
Definition: custom_function.h:21
SnippetData::function
QString function
Definition: custom_function.h:23
CustomFunction::_linked_plot_name
std::string _linked_plot_name
Definition: custom_function.h:84
CustomFunction::snippet
const SnippetData & snippet() const
Definition: custom_function.cpp:64
CustomFunction::_plot_name
std::string _plot_name
Definition: custom_function.h:85
PJ::TimeseriesBase::Point
typename PlotDataBase< double, Value >::Point Point
Definition: timeseries.h:23
GetSnippetFromXML
SnippetData GetSnippetFromXML(const QDomElement &element)
Definition: custom_function.cpp:184
source
const char * source
Definition: lz4.h:767
CustomFunction::_used_channels
std::vector< std::string > _used_channels
Definition: custom_function.h:87
PJ::PlotDataBase::size
virtual size_t size() const
Definition: plotdatabase.h:183
SnippetData::global_vars
QString global_vars
Definition: custom_function.h:22
CustomFunction::xmlLoadState
bool xmlLoadState(const QDomElement &parent_element) override
Override this method to load the status of the plugin from XML.
Definition: custom_function.cpp:126
PJ::TimeseriesBase::maximumRangeX
double maximumRangeX() const
Definition: timeseries.h:48
SnippetData
Definition: custom_function.h:19
CustomFunction::CustomFunction
CustomFunction(SnippetData snippet={})
Definition: custom_function.cpp:9
SnippetsMap
std::map< QString, SnippetData > SnippetsMap
Definition: custom_function.h:28
PJ::TransformFunction::plotData
PlotDataMapRef * plotData()
Definition: transform_function.h:57
PJ::PlotDataBase::at
const Point & at(size_t index) const
Definition: plotdatabase.h:193
CustomFunction::calculateAndAdd
void calculateAndAdd(PlotDataMapRef &src_data)
Definition: custom_function.cpp:33
PJ::PlotDataMapRef
Definition: plotdata.h:34
PJ::TransformFunction::_dst_vector
std::vector< PlotData * > _dst_vector
Definition: transform_function.h:79


plotjuggler
Author(s): Davide Faconti
autogenerated on Mon Nov 11 2024 03:23:43