source: finroc_plugins_data_ports/optimized/tSingleThreadedCheapCopyPortGeneric.cpp @ 115:fd7b0e5ec9ea

17.03
Last change on this file since 115:fd7b0e5ec9ea was 115:fd7b0e5ec9ea, checked in by Max Reichardt <mreichardt@…>, 6 years ago

Makes initial pushing mechanism use/respect type conversion

File size: 7.9 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/data_ports/optimized/tSingleThreadedCheapCopyPortGeneric.cpp
23 *
24 * \author  Max Reichardt
25 *
26 * \date    2014-06-22
27 *
28 */
29//----------------------------------------------------------------------
30#include "plugins/data_ports/optimized/tSingleThreadedCheapCopyPortGeneric.h"
31
32//----------------------------------------------------------------------
33// External includes (system with <>, local with "")
34//----------------------------------------------------------------------
35
36//----------------------------------------------------------------------
37// Internal includes with ""
38//----------------------------------------------------------------------
39#include "plugins/data_ports/optimized/cheaply_copied_types.h"
40
41//----------------------------------------------------------------------
42// Debugging
43//----------------------------------------------------------------------
44#include <cassert>
45
46//----------------------------------------------------------------------
47// Namespace usage
48//----------------------------------------------------------------------
49
50//----------------------------------------------------------------------
51// Namespace declaration
52//----------------------------------------------------------------------
53namespace finroc
54{
55namespace data_ports
56{
57namespace optimized
58{
59
60//----------------------------------------------------------------------
61// Forward declarations / typedefs / enums
62//----------------------------------------------------------------------
63
64//----------------------------------------------------------------------
65// Const values
66//----------------------------------------------------------------------
67
68//----------------------------------------------------------------------
69// Implementation
70//----------------------------------------------------------------------
71
72tSingleThreadedCheapCopyPortGeneric::tSingleThreadedCheapCopyPortGeneric(common::tAbstractDataPortCreationInfo creation_info) :
73  common::tAbstractDataPort(creation_info),
74  current_value(),
75  default_value(),
76  max_queue_length(-1),
77  standard_assign(!GetFlag(tFlag::NON_STANDARD_ASSIGN) && (!GetFlag(tFlag::HAS_QUEUE)))
78{
79  current_value.data.reset(creation_info.data_type.CreateGenericObject());
80  current_value.data_pointer = current_value.data->GetRawDataPointer();
81  current_value.cheaply_copyable_type_index = RegisterPort(creation_info.data_type);
82  current_value.timestamp = rrlib::time::cNO_TIME;
83
84  if ((!IsDataFlowType(GetDataType())) || (!IsCheaplyCopiedType(GetDataType())))
85  {
86    FINROC_LOG_PRINT(ERROR, "Data type ", GetDataType().GetName(), " is not suitable for cheap copy port implementation.");
87    abort();
88  }
89
90  // set initial value to default?
91  if (creation_info.DefaultValueSet() || creation_info.flags.Get(core::tFrameworkElement::tFlag::DEFAULT_ON_DISCONNECT))
92  {
93    default_value.reset(creation_info.data_type.CreateGenericObject());
94    if (creation_info.DefaultValueSet())
95    {
96      rrlib::serialization::tInputStream stream(creation_info.GetDefaultGeneric());
97      default_value->Deserialize(stream);
98    }
99    current_value.data->DeepCopyFrom(*default_value);
100  }
101
102  // Queues are only supported in subclass
103}
104
105tSingleThreadedCheapCopyPortGeneric::~tSingleThreadedCheapCopyPortGeneric()
106{}
107
108void tSingleThreadedCheapCopyPortGeneric::ApplyDefaultValue()
109{
110  if (!default_value)
111  {
112    FINROC_LOG_PRINT(ERROR, "No default value has been set. Doing nothing.");
113    return;
114  }
115  BrowserPublishRaw(*default_value, rrlib::time::cNO_TIME, true);
116}
117
118std::string tSingleThreadedCheapCopyPortGeneric::BrowserPublishRaw(const rrlib::rtti::tGenericObject& buffer, rrlib::time::tTimestamp timestamp,
119    bool notify_listener_on_this_port, tChangeStatus change_constant)
120{
121  current_value.data->DeepCopyFrom(buffer);
122  current_value.timestamp = timestamp;
123  common::tPublishOperation<tSingleThreadedCheapCopyPortGeneric, tPublishingData> publish_operation(current_value);
124  if (notify_listener_on_this_port)
125  {
126    if (change_constant == tChangeStatus::CHANGED_INITIAL)
127    {
128      publish_operation.Execute<tChangeStatus::CHANGED_INITIAL, true, true>(*this);
129    }
130    else
131    {
132      publish_operation.Execute<tChangeStatus::CHANGED, true, true>(*this);
133    }
134  }
135  else
136  {
137    if (change_constant == tChangeStatus::CHANGED_INITIAL)
138    {
139      publish_operation.Execute<tChangeStatus::CHANGED_INITIAL, true, false>(*this);
140    }
141    else
142    {
143      publish_operation.Execute<tChangeStatus::CHANGED, true, false>(*this);
144    }
145  }
146  return "";
147}
148
149void tSingleThreadedCheapCopyPortGeneric::ForwardData(tAbstractDataPort& other)
150{
151  assert(IsDataFlowType(other.GetDataType()) && (IsCheaplyCopiedType(other.GetDataType())));
152
153  common::tPublishOperation<tSingleThreadedCheapCopyPortGeneric, tPublishingData> publish_operation(current_value);
154  publish_operation.Execute<tChangeStatus::CHANGED, false, false>(static_cast<tSingleThreadedCheapCopyPortGeneric&>(other));
155}
156
157int tSingleThreadedCheapCopyPortGeneric::GetMaxQueueLengthImplementation() const
158{
159  return max_queue_length;
160}
161
162void tSingleThreadedCheapCopyPortGeneric::InitialPushTo(core::tConnector& connector)
163{
164  if (typeid(connector) == typeid(common::tConversionConnector))
165  {
166    static_cast<common::tConversionConnector&>(connector).Publish(*current_value.data, tChangeStatus::CHANGED_INITIAL);
167  }
168  else
169  {
170    common::tPublishOperation<tSingleThreadedCheapCopyPortGeneric, tPublishingData> data(current_value);
171    tSingleThreadedCheapCopyPortGeneric& target_port = static_cast<tSingleThreadedCheapCopyPortGeneric&>(connector.Destination());
172    common::tPublishOperation<tSingleThreadedCheapCopyPortGeneric, tPublishingData>::Receive<tChangeStatus::CHANGED_INITIAL>(data, target_port, *this);
173  }
174}
175
176bool tSingleThreadedCheapCopyPortGeneric::NonStandardAssign(tPublishingData& publishing_data, tChangeStatus change_constant)
177{
178  throw std::logic_error("Only implemented for/in subclasses");
179}
180
181void tSingleThreadedCheapCopyPortGeneric::Publish(const rrlib::rtti::tGenericObject& data, rrlib::time::tTimestamp timestamp)
182{
183  if (!GetFlag(tFlag::HIJACKED_PORT))
184  {
185    current_value.data->DeepCopyFrom(data);
186    current_value.timestamp = timestamp;
187    common::tPublishOperation<tSingleThreadedCheapCopyPortGeneric, tPublishingData> publish_operation(current_value);
188    publish_operation.Execute<tChangeStatus::CHANGED, false, false>(*this);
189  }
190}
191
192void tSingleThreadedCheapCopyPortGeneric::SetCurrentValueBuffer(void* address)
193{
194  std::unique_ptr<rrlib::rtti::tGenericObject> new_buffer(GetDataType().CreateGenericObject(address));
195  new_buffer->DeepCopyFrom(*current_value.data);
196  std::swap(new_buffer, current_value.data);
197  current_value.data_pointer = current_value.data->GetRawDataPointer();
198}
199
200void tSingleThreadedCheapCopyPortGeneric::SetDefault(rrlib::rtti::tGenericObject& new_default)
201{
202  default_value.reset(new_default.GetType().CreateGenericObject());
203  default_value->DeepCopyFrom(new_default);
204  current_value.data->DeepCopyFrom(new_default);
205}
206
207
208//----------------------------------------------------------------------
209// End of namespace declaration
210//----------------------------------------------------------------------
211}
212}
213}
Note: See TracBrowser for help on using the repository browser.