lua_custom_function.cpp
Go to the documentation of this file.
1 #include "lua_custom_function.h"
2 #include <QTextStream>
3 
5 {
6  initEngine();
7  {
8  QTextStream in(&snippet.global_vars);
9  while (!in.atEnd())
10  {
11  in.readLine();
12  global_lines_++;
13  }
14  }
15  {
16  QTextStream in(&snippet.function);
17  while (!in.atEnd())
18  {
19  in.readLine();
21  }
22  }
23 }
24 
26 {
27  std::unique_lock<std::mutex> lk(mutex_);
28 
29  _lua_function = {};
30  _lua_engine = {};
32  auto result = _lua_engine.safe_script(_snippet.global_vars.toStdString());
33  if (!result.valid())
34  {
35  sol::error err = result;
36  throw std::runtime_error(getError(err));
37  }
38 
39  auto calcMethodStr = QString("function calc(time, value");
40  for (int index = 1; index <= _snippet.additional_sources.size(); index++)
41  {
42  calcMethodStr += QString(", v%1").arg(index);
43  }
44  calcMethodStr += QString(")\n%1\nend").arg(snippet().function);
45 
46  result = _lua_engine.safe_script(calcMethodStr.toStdString());
47  if (!result.valid())
48  {
49  sol::error err = result;
50  throw std::runtime_error(getError(err));
51  }
52  _lua_function = _lua_engine["calc"];
53 }
54 
55 void LuaCustomFunction::calculatePoints(const std::vector<const PlotData*>& src_data,
56  size_t point_index,
57  std::vector<PlotData::Point>& points)
58 {
59  std::unique_lock<std::mutex> lk(mutex_);
60 
61  _chan_values.resize(src_data.size());
62 
63  const PlotData::Point& old_point = src_data.front()->at(point_index);
64 
65  for (size_t chan_index = 0; chan_index < src_data.size(); chan_index++)
66  {
67  double value;
68  const PlotData* chan_data = src_data[chan_index];
69  int index = chan_data->getIndexFromX(old_point.x);
70  if (index != -1)
71  {
72  value = chan_data->at(index).y;
73  }
74  else
75  {
76  value = std::numeric_limits<double>::quiet_NaN();
77  }
78  _chan_values[chan_index] = value;
79  }
80 
82  const auto& v = _chan_values;
83  // ugly code, sorry
84  switch (_snippet.additional_sources.size())
85  {
86  case 0:
87  result = _lua_function(old_point.x, v[0]);
88  break;
89  case 1:
90  result = _lua_function(old_point.x, v[0], v[1]);
91  break;
92  case 2:
93  result = _lua_function(old_point.x, v[0], v[1], v[2]);
94  break;
95  case 3:
96  result = _lua_function(old_point.x, v[0], v[1], v[2], v[3]);
97  break;
98  case 4:
99  result = _lua_function(old_point.x, v[0], v[1], v[2], v[3], v[4]);
100  break;
101  case 5:
102  result = _lua_function(old_point.x, v[0], v[1], v[2], v[3], v[4], v[5]);
103  break;
104  case 6:
105  result = _lua_function(old_point.x, v[0], v[1], v[2], v[3], v[4], v[5], v[6]);
106  break;
107  case 7:
108  result = _lua_function(old_point.x, v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]);
109  break;
110  case 8:
111  result = _lua_function(old_point.x, v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7],
112  v[8]);
113  break;
114  default:
115  throw std::runtime_error("Lua Engine: maximum number of additional data sources is "
116  "8");
117  }
118 
119  if (!result.valid())
120  {
121  sol::error err = result;
122  throw std::runtime_error(getError(err));
123  }
124 
125  if (result.return_count() == 2)
126  {
127  PlotData::Point new_point;
128  new_point.x = result.get<double>(0);
129  new_point.y = result.get<double>(1);
130  points.push_back(new_point);
131  }
132  else if (result.return_count() == 1 && result.get_type(0) == sol::type::number)
133  {
134  PlotData::Point new_point;
135  new_point.x = old_point.x;
136  new_point.y = result.get<double>(0);
137  points.push_back(new_point);
138  }
139  else if (result.return_count() == 1 && result.get_type(0) == sol::type::table)
140  {
141  static std::vector<std::array<double, 2>> multi_samples;
142  multi_samples.clear();
143 
144  multi_samples = result.get<std::vector<std::array<double, 2>>>(0);
145 
146  for (std::array<double, 2> sample : multi_samples)
147  {
148  PlotData::Point point;
149  point.x = sample[0];
150  point.y = sample[1];
151  points.push_back(point);
152  }
153  }
154  else
155  {
156  throw std::runtime_error("Wrong return object: expecting either a single value, "
157  "two values (time, value) "
158  "or an array of two-sized arrays (time, value)");
159  }
160 }
161 
162 bool LuaCustomFunction::xmlLoadState(const QDomElement& parent_element)
163 {
164  bool ret = CustomFunction::xmlLoadState(parent_element);
165  initEngine();
166  return ret;
167 }
168 
170 {
171  std::string out;
172  auto parts = QString(err.what()).split(":");
173 
174  if (parts.size() < 3)
175  {
176  return err.what();
177  }
178 
179  bool is_function = parts[0].contains("[string \"function calc(time,");
180  out = is_function ? "[Function]: line " : "[Global]: line ";
181 
182  int line_num = parts[1].toInt();
183  if (is_function)
184  {
185  line_num -= 1;
186  }
187  out += std::to_string(line_num) + ": ";
188  out += parts[2].toStdString();
189  return out;
190 }
sol::error::what
virtual const char * what() const noexcept override
Definition: sol.hpp:4593
sol::type::number
@ number
PJ::TimeseriesBase
Definition: timeseries.h:16
sol::protected_function_result
Definition: sol.hpp:17228
lua_custom_function.h
CustomFunction::_snippet
SnippetData _snippet
Definition: custom_function.h:83
LuaCustomFunction::initEngine
void initEngine() override
Definition: lua_custom_function.cpp:25
LuaCustomFunction::_lua_engine
sol::state _lua_engine
Definition: lua_custom_function.h:34
detail::in
constexpr auto in(type t, int set) -> bool
Definition: core.h:628
LuaCustomFunction::function_lines_
int function_lines_
Definition: lua_custom_function.h:39
sol::state_view::safe_script
protected_function_result safe_script(lua_Reader reader, void *data, Fx &&on_error, const std::string &chunkname=detail::default_chunk_name(), load_mode mode=load_mode::any)
Definition: sol.hpp:27564
sol::type::table
@ table
sol::protected_function_result::valid
bool valid() const noexcept
Definition: sol.hpp:17288
LuaCustomFunction::getError
std::string getError(sol::error err)
Definition: lua_custom_function.cpp:169
LuaCustomFunction::LuaCustomFunction
LuaCustomFunction(SnippetData snippet={})
Definition: lua_custom_function.cpp:4
SnippetData::additional_sources
QStringList additional_sources
Definition: custom_function.h:25
sol::protected_function_result::get_type
type get_type(int index_offset=0) const noexcept
Definition: sol.hpp:17342
LuaCustomFunction::xmlLoadState
bool xmlLoadState(const QDomElement &parent_element) override
Override this method to load the status of the plugin from XML.
Definition: lua_custom_function.cpp:162
SnippetData::function
QString function
Definition: custom_function.h:23
sol::protected_function_result::return_count
int return_count() const noexcept
Definition: sol.hpp:17394
LuaCustomFunction::global_lines_
int global_lines_
Definition: lua_custom_function.h:38
CustomFunction::snippet
const SnippetData & snippet() const
Definition: custom_function.cpp:64
LuaCustomFunction::_lua_function
sol::protected_function _lua_function
Definition: lua_custom_function.h:35
LuaCustomFunction::calculatePoints
void calculatePoints(const std::vector< const PlotData * > &channels_data, size_t point_index, std::vector< PlotData::Point > &points) override
Definition: lua_custom_function.cpp:55
PJ::TimeseriesBase::Point
typename PlotDataBase< double, Value >::Point Point
Definition: timeseries.h:23
sol::error
Definition: sol.hpp:4573
PJ::TimeseriesBase::getIndexFromX
int getIndexFromX(double x) const
Definition: timeseries.h:106
sol::state_view::open_libraries
void open_libraries(Args &&... args)
Definition: sol.hpp:27320
CustomFunction
Definition: custom_function.h:40
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
SnippetData
Definition: custom_function.h:19
PJ::PlotDataBase::at
const Point & at(size_t index) const
Definition: plotdatabase.h:193
sol::protected_function_result::get
decltype(auto) get(int index_offset=0) const
Definition: sol.hpp:17298
LuaCustomFunction::_chan_values
std::vector< double > _chan_values
Definition: lua_custom_function.h:36
LuaCustomFunction::mutex_
std::mutex mutex_
Definition: lua_custom_function.h:37
mqtt_test.ret
ret
Definition: mqtt_test.py:30


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