KaCanOpen
 All Classes Functions Variables Typedefs Enumerations Pages
entry.cpp
1 /*
2  * Copyright (c) 2015, Thomas Keh
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include "entry.h"
33 #include "canopen_error.h"
34 
35 #include <cassert>
36 #include <future>
37 #include <iomanip>
38 #include <memory>
39 #include <iostream>
40 
41 namespace kaco {
42 
44  : type(Type::invalid),
45  m_value_changed_callbacks_mutex(new std::mutex),
46  m_read_write_mutex(new std::recursive_mutex)
47  { }
48 
49 // standard constructor
50 Entry::Entry(const uint16_t _index, const uint8_t _subindex, const std::string& _name, const Type _type, const AccessType _access_type)
51  : index(_index),
52  subindex(_subindex),
53  name(_name),
54  type(_type),
55  access_type(_access_type),
56  disabled(false),
57  is_generic(false),
58  m_valid(false),
59  m_value_changed_callbacks_mutex(new std::mutex),
60  m_read_write_mutex(new std::recursive_mutex)
61  { }
62 
63 void Entry::set_value(const Value& value) {
64 
65  if (value.type != type) {
66  throw canopen_error("[Entry::set_value] You passed a value of wrong type: "+Utils::type_to_string(value.type)+" != "+Utils::type_to_string(type)+".");
67  }
68 
69  bool value_changed = false;
70 
71  {
72  std::lock_guard<std::recursive_mutex> lock(*m_read_write_mutex);
73 
74  if (m_value.type != type || m_value != value) {
75  value_changed = true;
76  }
77 
78  m_value = value;
79  m_valid = true;
80 
81  }
82 
83  if (value_changed) {
84  std::lock_guard<std::mutex> lock(*m_value_changed_callbacks_mutex);
85  for (auto& callback : m_value_changed_callbacks) {
86  // TODO: currently callbacks are only internal and it's ok to call them synchonously.
87  //std::async(std::launch::async, callback, value);
88  callback(value);
89  }
90  }
91 
92 }
93 
94 const Value& Entry::get_value() const {
95  std::lock_guard<std::recursive_mutex> lock(*m_read_write_mutex);
96  if (!valid()) {
97  throw canopen_error("[Entry::get_value] Value is not valid.");
98  }
99  return m_value;
100 }
101 
102 bool Entry::valid() const {
103  return m_valid;
104 }
105 
106 Type Entry::get_type() const {
107  return type;
108 }
109 
111  std::lock_guard<std::mutex> lock(*m_value_changed_callbacks_mutex);
112  m_value_changed_callbacks.push_back(std::move(callback));
113 }
114 
115 void Entry::print() const {
116 
117  std::cout << "0x"<<std::hex<<index;
118  std::cout << "/";
119  std::cout << std::dec<<(unsigned)subindex;
120  std::cout << "\t";
122  std::cout << "\t";
123  std::cout << std::setw(75) << std::left << name;
124  std::cout << " ";
125 
126  if (valid()) {
127  std::cout << std::setw(10) << get_value();
128  } else {
129  std::cout << std::setw(10) << "empty";
130  }
131 
132  std::cout << std::endl;
133 
134 }
135 
136 bool Entry::operator<(const Entry& other) const {
137  return (index<other.index) || (index==other.index && subindex<other.subindex);
138 }
139 
140 } // end namespace kaco
Type get_type() const
Returns the data type.
Definition: entry.cpp:106
static std::string access_type_to_string(AccessType type)
Converts access types to a string.
Definition: utils.cpp:213
void add_value_changed_callback(ValueChangedCallback callback)
Registers a given function to be called when the value is changed.
Definition: entry.cpp:110
Type type
Data type of the value.
Definition: entry.h:129
std::function< void(const Value &value) > ValueChangedCallback
type of a callback for a value changed event Important: Never call add_value_changed_callback() from ...
Definition: entry.h:60
const Value & get_value() const
Returns the value.
Definition: entry.cpp:94
void set_value(const Value &value)
Sets the value.
Definition: entry.cpp:63
AccessType access_type
Accessibility of the entry.
Definition: entry.h:132
uint16_t index
index in dictionary
Definition: entry.h:118
std::string name
Human-readable name Should be escaped for consitency using Utils::escape().
Definition: entry.h:126
uint8_t subindex
subindex in dictionary. if is_array==true, this variable is not used
Definition: entry.h:122
This is the base class of all types of exceptions thrown by the KaCanOpen library. It can be used directly like std::runtime_error if there isn't any more specific error class.
Definition: canopen_error.h:43
static std::string type_to_string(Type type)
Converts data types to a string.
Definition: utils.cpp:42
Type type
Tyoe of the value.
Definition: value.h:56
bool valid() const
Returns if the value is set/valid.
Definition: entry.cpp:102
bool operator<(const Entry &other) const
Compares entries by index and subindex. This can be used for sorting the dictionary.
Definition: entry.cpp:136
This class represents an entry in the object dictionary of a device.
Definition: entry.h:53
void print() const
Prints relevant information concerning this entry on standard output - name, index, possibly value, ... This is used by Device::print_dictionary()
Definition: entry.cpp:115
Entry()
Constructs an empty entry.
Definition: entry.cpp:43
This class contains a value to be stored in the object dictionary. The value can have one of the type...
Definition: value.h:53