source: finroc_plugins_parameters/internal/tParameterInfo.cpp @ 66:3700e332142e

17.03
Last change on this file since 66:3700e332142e was 66:3700e332142e, checked in by Max Reichardt <mreichardt@…>, 4 years ago

Removes 'unused variable' compiler warnings at static data type registration

File size: 11.5 KB
Line 
1//
2// You received this file as part of Finroc
3// A framework for intelligent robot control
4//
5// Copyright (C) Finroc GbR (finroc.org)
6//
7// This program is free software; you can redistribute it and/or modify
8// it under the terms of the GNU General Public License as published by
9// the Free Software Foundation; either version 2 of the License, or
10// (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License along
18// with this program; if not, write to the Free Software Foundation, Inc.,
19// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20//
21//----------------------------------------------------------------------
22/*!\file    plugins/parameters/internal/tParameterInfo.cpp
23 *
24 * \author  Max Reichardt
25 *
26 * \date    2012-11-28
27 *
28 */
29//----------------------------------------------------------------------
30#include "plugins/parameters/internal/tParameterInfo.h"
31
32//----------------------------------------------------------------------
33// External includes (system with <>, local with "")
34//----------------------------------------------------------------------
35#include "rrlib/rtti/rtti.h"
36#include "core/port/tAbstractPort.h"
37#include "core/tRuntimeEnvironment.h"
38#include "plugins/data_ports/tGenericPort.h"
39
40//----------------------------------------------------------------------
41// Internal includes with ""
42//----------------------------------------------------------------------
43#include "plugins/parameters/tConfigFile.h"
44#include "plugins/parameters/tConfigNode.h"
45
46//----------------------------------------------------------------------
47// Debugging
48//----------------------------------------------------------------------
49#include <cassert>
50
51//----------------------------------------------------------------------
52// Namespace usage
53//----------------------------------------------------------------------
54
55//----------------------------------------------------------------------
56// Namespace declaration
57//----------------------------------------------------------------------
58namespace finroc
59{
60namespace parameters
61{
62namespace internal
63{
64
65//----------------------------------------------------------------------
66// Forward declarations / typedefs / enums
67//----------------------------------------------------------------------
68
69//----------------------------------------------------------------------
70// Const values
71//----------------------------------------------------------------------
72
73/* Initializes parameter info annotation type */
74__attribute__((unused))
75static rrlib::rtti::tDataType<tParameterInfo> cTYPE;
76
77//----------------------------------------------------------------------
78// Implementation
79//----------------------------------------------------------------------
80
81tParameterInfo::tParameterInfo() :
82  config_entry(),
83  entry_set_from_finstruct(false),
84  command_line_option(),
85  finstruct_default()
86{}
87
88#ifdef _LIB_RRLIB_XML_PRESENT_
89void tParameterInfo::Deserialize(const rrlib::xml::tNode& node, bool finstruct_context, bool include_commmand_line)
90{
91  if (node.HasAttribute("config"))
92  {
93    config_entry = node.GetStringAttribute("config");
94    entry_set_from_finstruct = finstruct_context;
95  }
96  else
97  {
98    config_entry = "";
99  }
100  if (include_commmand_line)
101  {
102    if (node.HasAttribute("cmdline"))
103    {
104      command_line_option = node.GetStringAttribute("cmdline");
105    }
106    else
107    {
108      command_line_option = "";
109    }
110  }
111  if (node.HasAttribute("default"))
112  {
113    finstruct_default = node.GetStringAttribute("default");
114  }
115  else
116  {
117    finstruct_default = "";
118  }
119}
120#endif
121
122bool tParameterInfo::IsFinstructableGroupResponsibleForConfigFileConnections(const core::tFrameworkElement& finstructable_group, const core::tFrameworkElement& ap)
123{
124  core::tFrameworkElement* responsible = ap.GetParentWithFlags(core::tFrameworkElement::tFlag::FINSTRUCTABLE_GROUP | core::tFrameworkElement::tFlag::MANAGES_PARAMETER_CONFIGURATION);
125  return responsible == &finstructable_group;
126}
127
128void tParameterInfo::LoadValue(bool ignore_ready)
129{
130  core::tAbstractPort* ann = this->GetAnnotated<core::tAbstractPort>();
131  {
132    rrlib::thread::tLock lock(ann->GetStructureMutex());
133    if (ann && (ignore_ready || ann->IsReady()))
134    {
135      // command line option
136      if (command_line_option.length() > 0)
137      {
138        std::string arg = core::tRuntimeEnvironment::GetInstance().GetCommandLineArgument(command_line_option);
139        if (arg.length() > 0)
140        {
141          if (data_ports::IsDataFlowType(ann->GetDataType()))
142          {
143            rrlib::serialization::tStringInputStream sis(arg);
144            data_ports::tGenericPort port = data_ports::tGenericPort::Wrap(*ann);
145            data_ports::tPortDataPointer<rrlib::rtti::tGenericObject> buffer = port.GetUnusedBuffer();
146            try
147            {
148              buffer->Deserialize(sis);
149              std::string error = port.BrowserPublish(buffer);
150              if (error.size() > 0)
151              {
152                FINROC_LOG_PRINT(WARNING, "Failed to load parameter '", ann, "' from command line argument '", arg, "': ", error);
153              }
154              return;
155            }
156            catch (const std::exception& e)
157            {
158              FINROC_LOG_PRINT(ERROR, "Failed to load parameter '", ann, "' from command line argument '", arg, "': ", e);
159            }
160          }
161          else
162          {
163            throw std::runtime_error("Port Type not supported as a parameter");
164          }
165        }
166      }
167
168      // config file entry
169      tConfigFile* cf = tConfigFile::Find(*ann);
170      if (cf != NULL && config_entry.length() > 0)
171      {
172        std::string full_config_entry = tConfigNode::GetFullConfigEntry(*ann, config_entry);
173        if (cf->HasEntry(full_config_entry))
174        {
175#ifdef _LIB_RRLIB_XML_PRESENT_
176          rrlib::xml::tNode& node = cf->GetEntry(full_config_entry, false);
177          if (data_ports::IsDataFlowType(ann->GetDataType()))
178          {
179            data_ports::tGenericPort port = data_ports::tGenericPort::Wrap(*ann);
180            data_ports::tPortDataPointer<rrlib::rtti::tGenericObject> buffer = port.GetUnusedBuffer();
181
182            try
183            {
184              buffer->Deserialize(node);
185              std::string error = port.BrowserPublish(buffer);
186              if (error.size() > 0)
187              {
188                FINROC_LOG_PRINT(WARNING, "Failed to load parameter '", ann, "' from config entry '", full_config_entry, "': ", error);
189              }
190              return;
191            }
192            catch (const std::exception& e)
193            {
194              FINROC_LOG_PRINT(ERROR, "Failed to load parameter '", ann, "' from config entry '", full_config_entry, "': ", e);
195            }
196          }
197          else
198          {
199            throw std::runtime_error("Port Type not supported as a parameter");
200          }
201#endif
202        }
203      }
204
205      // finstruct default
206      if (finstruct_default.length() > 0)
207      {
208        if (data_ports::IsDataFlowType(ann->GetDataType()))
209        {
210          rrlib::serialization::tStringInputStream sis(finstruct_default);
211          data_ports::tGenericPort port = data_ports::tGenericPort::Wrap(*ann);
212          data_ports::tPortDataPointer<rrlib::rtti::tGenericObject> buffer = port.GetUnusedBuffer();
213
214          try
215          {
216            buffer->Deserialize(sis);
217            std::string error = port.BrowserPublish(buffer);
218            if (error.size() > 0)
219            {
220              FINROC_LOG_PRINT(WARNING, "Failed to load parameter '", ann, "' from finstruct default '", finstruct_default, "': ", error);
221            }
222            return;
223          }
224          catch (const std::exception& e)
225          {
226            FINROC_LOG_PRINT(ERROR, "Failed to load parameter '", ann, "' from finstruct default '", finstruct_default, "': ", e);
227          }
228        }
229        else
230        {
231          throw std::runtime_error("Port Type not supported as a parameter");
232        }
233      }
234    }
235  }
236}
237
238void tParameterInfo::OnInitialization()
239{
240  try
241  {
242    LoadValue(true);
243  }
244  catch (const std::exception& e)
245  {
246    FINROC_LOG_PRINT(ERROR, e);
247  }
248}
249
250void tParameterInfo::SaveValue()
251{
252  core::tAbstractPort* ann = GetAnnotated<core::tAbstractPort>();
253  if (ann == NULL || (!ann->IsReady()))
254  {
255    return;
256  }
257  tConfigFile* cf = tConfigFile::Find(*ann);
258  bool has_entry = cf->HasEntry(config_entry);
259  if (data_ports::IsDataFlowType(ann->GetDataType()))
260  {
261    data_ports::tGenericPort port = data_ports::tGenericPort::Wrap(*ann);
262    if (has_entry)
263    {
264#ifdef _LIB_RRLIB_XML_PRESENT_
265      rrlib::xml::tNode& node = cf->GetEntry(config_entry, true);
266      std::unique_ptr<rrlib::rtti::tGenericObject> current_value(port.GetDataType().CreateGenericObject());
267      port.Get(*current_value);
268      current_value->Serialize(node);
269#endif
270    }
271  }
272  else
273  {
274    throw std::runtime_error("Port Type not supported as a parameter");
275  }
276}
277
278#ifdef _LIB_RRLIB_XML_PRESENT_
279void tParameterInfo::Serialize(rrlib::xml::tNode & node, bool finstruct_context, bool include_command_line) const
280{
281  assert(!(node.HasAttribute("default") || node.HasAttribute("cmdline") || node.HasAttribute("config")));
282  if (config_entry.length() > 0 && (entry_set_from_finstruct || (!finstruct_context)))
283  {
284    node.SetAttribute("config", config_entry);
285  }
286  if (include_command_line)
287  {
288    if (command_line_option.length() > 0)
289    {
290      node.SetAttribute("cmdline", command_line_option);
291    }
292  }
293  if (finstruct_default.length() > 0)
294  {
295    node.SetAttribute("default", finstruct_default);
296  }
297}
298#endif
299
300void tParameterInfo::SetConfigEntry(const std::string & config_entry, bool finstruct_set)
301{
302  if (this->config_entry.compare(config_entry) != 0)
303  {
304    this->config_entry = config_entry;
305    this->entry_set_from_finstruct = finstruct_set;
306    try
307    {
308      LoadValue();
309    }
310    catch (const std::exception& e)
311    {
312      FINROC_LOG_PRINT(ERROR, e);
313    }
314  }
315}
316
317
318rrlib::serialization::tOutputStream& operator << (rrlib::serialization::tOutputStream & stream, const tParameterInfo & parameter_info)
319{
320  stream.WriteBoolean(parameter_info.IsConfigEntrySetFromFinstruct());
321  stream.WriteString(parameter_info.GetConfigEntry());
322  stream.WriteString(parameter_info.GetCommandLineOption());
323  stream.WriteString(parameter_info.GetFinstructDefault());
324  return stream;
325}
326
327rrlib::serialization::tInputStream& operator >> (rrlib::serialization::tInputStream & stream, tParameterInfo & parameter_info)
328{
329  parameter_info.entry_set_from_finstruct = stream.ReadBoolean();
330  std::string config_entry_tmp = stream.ReadString();
331  std::string command_line_option_tmp = stream.ReadString();
332  std::string finstruct_default_tmp = stream.ReadString();
333  bool same = config_entry_tmp.compare(parameter_info.GetConfigEntry()) == 0 &&
334              command_line_option_tmp.compare(parameter_info.GetCommandLineOption()) == 0 &&
335              finstruct_default_tmp.compare(parameter_info.GetFinstructDefault()) == 0;
336  parameter_info.config_entry = config_entry_tmp;
337  parameter_info.command_line_option = command_line_option_tmp;
338  parameter_info.finstruct_default = finstruct_default_tmp;
339
340  if (!same)
341  {
342    try
343    {
344      parameter_info.LoadValue();
345    }
346    catch (std::exception& e)
347    {
348      FINROC_LOG_PRINT_STATIC(ERROR, e);
349    }
350  }
351  return stream;
352}
353
354//----------------------------------------------------------------------
355// End of namespace declaration
356//----------------------------------------------------------------------
357}
358}
359}
Note: See TracBrowser for help on using the repository browser.