MADARA  3.4.1
DoubleVector3D.cpp
Go to the documentation of this file.
1 #include "DoubleVector3D.h"
3 
5  const KnowledgeUpdateSettings& settings, const std::string& delimiter)
6  : BaseContainer("", settings), context_(0), delimiter_(delimiter)
7 {
8 }
9 
11  const std::string& name, KnowledgeBase& knowledge,
12  const Dimensions& dimensions, bool delete_vars,
13  const KnowledgeUpdateSettings& settings, const std::string& delimiter)
14  : BaseContainer(name, settings),
15  context_(&(knowledge.get_context())),
16  delimiter_(delimiter)
17 {
18  size_ = get_size_ref();
19  resize(dimensions, delete_vars);
20 }
21 
23  const std::string& name, Variables& knowledge, const Dimensions& dimensions,
24  bool delete_vars, const KnowledgeUpdateSettings& settings,
25  const std::string& delimiter)
26  : BaseContainer(name, settings),
27  context_(knowledge.get_context()),
28  delimiter_(delimiter)
29 {
30  size_ = get_size_ref();
31  resize(dimensions, delete_vars);
32 }
33 
35  const DoubleVector3D& rhs)
36  : BaseContainer(rhs),
37  context_(rhs.context_),
38  vector_(rhs.vector_),
39  size_(rhs.size_),
40  delimiter_(rhs.delimiter_)
41 {
42 }
43 
45 
47 {
48  if (context_ && name_ != "")
49  {
50  ContextGuard context_guard(*context_);
51 
52  Indices dimensions = size();
53 
54  if (dimensions.x > 0 && dimensions.y > 0 && dimensions.z > 0)
55  {
56  for (size_t i = 0; i < dimensions.x; ++i)
57  {
58  for (size_t j = 0; j < dimensions.y; ++j)
59  {
60  for (size_t k = 0; k < dimensions.z; ++k)
61  {
62  context_->mark_modified(vector_[i][j][k]);
63  }
64  }
65  }
66  }
67 
68  context_->mark_modified(size_);
69  }
70 }
71 
73 {
74  std::stringstream result;
75 
76  result << "DoubleVector3D: ";
77 
78  if (context_)
79  {
80  ContextGuard context_guard(*context_);
81 
82  Indices dimensions = size();
83 
84  result << this->name_;
85  result << " [" << dimensions.x << "," << dimensions.y << "," << dimensions.z
86  << "]";
87  result << " = [";
88 
89  if (dimensions.x > 0 && dimensions.y > 0)
90  {
91  for (size_t i = 0; i < dimensions.x; ++i)
92  {
93  for (size_t j = 0; j < dimensions.y; ++j)
94  {
95  result << context_->get(vector_[i][j][0]).to_string();
96 
97  for (size_t k = 1; k < dimensions.z; ++k)
98  {
99  result << ", " << context_->get(vector_[i][j][k]).to_string();
100  }
101  }
102  result << "\n";
103  }
104  }
105 
106  result << "]";
107  }
108 
109  return result.str();
110 }
111 
113 {
114  modify();
115 }
116 
118 {
119  return get_debug_info();
120 }
121 
124 {
125  return new DoubleVector3D(*this);
126 }
127 
129 {
130  if (context_)
131  {
132  ContextGuard context_guard(*context_);
133  if (index.x < vector_.size() && index.y < vector_[index.x].size() &&
134  index.z < vector_[index.x][index.y].size())
135  context_->mark_modified(vector_[index.x][index.y][index.z]);
136  }
137 }
138 
140  const DoubleVector3D& rhs)
141 {
142  if (this != &rhs)
143  {
144  MADARA_GUARD_TYPE guard(mutex_), guard2(rhs.mutex_);
145 
146  this->context_ = rhs.context_;
147  this->name_ = rhs.name_;
148  this->settings_ = rhs.settings_;
149  this->size_ = rhs.size_;
150  this->vector_ = rhs.vector_;
151  this->delimiter_ = rhs.delimiter_;
152  }
153 }
154 
157 {
158  VariableReference ref;
159 
160  if (context_ && name_ != "")
161  {
162  KnowledgeUpdateSettings keep_local(true);
163  std::stringstream buffer;
164 
165  ContextGuard context_guard(*context_);
166 
167  buffer << name_;
168  buffer << delimiter_;
169  buffer << "size";
170 
171  ref = context_->get_ref(buffer.str(), keep_local);
172  }
173 
174  return ref;
175 }
176 
178  const Dimensions& dimensions, bool delete_vars)
179 {
180  if (context_ && name_ != "")
181  {
182  ContextGuard context_guard(*context_);
183 
185  "DoubleVector3D::resize: resizing to [%d,%d]\n", (int)dimensions.x,
186  (int)dimensions.y);
187 
188  bool is_reset = dimensions.x == 0 && dimensions.y == 0;
189 
190  if (!size_.is_valid())
191  {
192  size_ = get_size_ref();
193  }
194 
195  // save the old size
196  Dimensions old_size = size();
197  Dimensions new_size(dimensions);
198 
200  "DoubleVector3D::resize: old size is [%d,%d]\n", (int)old_size.x,
201  (int)old_size.y);
202 
203  if (is_reset)
204  {
206  "DoubleVector3D::resize: new size is being reset to size in KB\n");
207 
208  new_size.x = old_size.x;
209  new_size.y = old_size.y;
210  new_size.z = old_size.z;
211  }
212  else
213  {
215  "DoubleVector3D::resize: using dimensions passed in.\n");
216 
217  // set the new size
218  std::vector<KnowledgeRecord::Integer> update(3);
219  update[0] = dimensions.x;
220  update[1] = dimensions.y;
221  update[2] = dimensions.z;
222 
223  context_->set(size_, update, settings_);
224  }
225 
226  // correct the vector for the new size
227  vector_.resize(new_size.x);
228 
229  for (size_t i = 0; i < new_size.x; ++i)
230  {
232  "DoubleVector3D::resize: resizing vector_[%d] to %d.\n", (int)i,
233  (int)new_size.y);
234 
235  vector_[i].resize(new_size.y);
236 
237  // create any new VariableReference needed, default is end of old cols
238 
239  size_t start = old_size.y;
240 
241  // if you've gained rows and this is a new row, reset start to 0
242  if (is_reset || (old_size.x < new_size.x && i >= old_size.x))
243  {
244  start = 0;
245  }
246 
248  "DoubleVector3D::resize: creating var_refs from %d->%d.\n",
249  (int)start, (int)new_size.y);
250 
251  // create new VariableReferences
252  for (size_t j = start; j < new_size.y; ++j)
253  {
254  vector_[i][j].resize(new_size.z);
255 
256  // create any new VariableReference needed, default is end of old cols
257 
258  size_t start_z = old_size.z;
259 
260  // if you've gained cols and this is a new col, reset start to 0
261  if (is_reset || ((old_size.y < new_size.y && j >= old_size.y) ||
262  (old_size.x < new_size.x && i >= old_size.x)))
263  {
264  start_z = 0;
265  }
266 
267  // create new VariableReferences
268  for (size_t k = start_z; k < new_size.z; ++k)
269  {
270  std::stringstream var_name;
271  var_name << this->name_;
272  var_name << delimiter_;
273  var_name << i;
274  var_name << delimiter_;
275  var_name << j;
276  var_name << delimiter_;
277  var_name << k;
278 
279  vector_[i][j][k] = context_->get_ref(var_name.str(), settings_);
280  }
281  }
282  }
283 
284  // delete if we need to delete
285  if ((new_size.x < old_size.x || new_size.y < old_size.y ||
286  new_size.z < old_size.z) &&
287  delete_vars)
288  {
290  "DoubleVector3D::resize: deleting refs: rows: 0->%d.\n",
291  (int)old_size.x);
292 
293  // delete within the old rows
294  for (size_t i = 0; i < old_size.x; ++i)
295  {
296  // by default, delete from new col size to old col size
297  size_t start = new_size.y;
298 
299  // the exception is when we are deleting the entire col
300  if (old_size.x > new_size.x && i >= new_size.x)
301  {
302  start = 0;
303  }
304 
306  "DoubleVector3D::resize: deleting refs: %d:%d->%d.\n", (int)i,
307  (int)start, (int)old_size.x);
308 
309  // delete old columns
310  for (size_t j = start; j < old_size.y; ++j)
311  {
312  // by default, delete from new col size to old col size
313  size_t start_k = new_size.z;
314 
315  // the exception is when we are deleting the entire row
316  if (old_size.y > new_size.y && j >= new_size.y)
317  {
318  start = 0;
319  }
320 
321  // delete old columns
322  for (size_t k = start_k; k < old_size.z; ++k)
323  {
324  std::stringstream var_name;
325  var_name << this->name_;
326  var_name << delimiter_;
327  var_name << i;
328  var_name << delimiter_;
329  var_name << j;
330  var_name << delimiter_;
331  var_name << k;
332 
334  "DoubleVector3D::resize: deleting ref: %s.\n",
335  var_name.str().c_str());
336 
337  context_->delete_variable(var_name.str(), settings_);
338  }
339  }
340  }
341  }
342  }
343 }
344 
347 {
348  Indices cur_size;
349 
350  if (context_)
351  {
352  KnowledgeRecord record;
353  // lock the KnowledgeBase during access
354  {
355  ContextGuard context_guard(*context_);
356 
357  record = context_->get(size_);
358  }
359 
360  std::vector<KnowledgeRecord::Integer> sizes(record.to_integers());
361  cur_size.x = (size_t)(sizes.size() >= 3 ? sizes[0] : 0);
362  cur_size.y = (size_t)(sizes.size() >= 3 ? sizes[1] : 0);
363  cur_size.z = (size_t)(sizes.size() >= 3 ? sizes[2] : 0);
364  }
365 
366  return cur_size;
367 }
368 
370  const std::string& var_name, KnowledgeBase& knowledge,
371  const Indices& dimensions)
372 {
373  if (context_ != &(knowledge.get_context()) || name_ != var_name)
374  {
375  context_ = &(knowledge.get_context());
376 
377  ContextGuard context_guard(*context_);
378 
379  name_ = var_name;
380 
381  vector_.clear();
382 
383  size_ = get_size_ref();
384 
385  resize(dimensions);
386  }
387 }
388 
390  const std::string& var_name, Variables& knowledge,
391  const Indices& dimensions)
392 {
393  if (context_ != knowledge.get_context() || name_ != var_name)
394  {
395  context_ = knowledge.get_context();
396 
397  ContextGuard context_guard(*context_);
398 
399  name_ = var_name;
400 
401  vector_.clear();
402  resize(dimensions);
403  }
404 }
405 
407  const std::string& var_name, ThreadSafeContext& knowledge,
408  const Indices& dimensions)
409 {
410  if (context_ != &knowledge || name_ != var_name)
411  {
412  context_ = &knowledge;
413 
414  ContextGuard context_guard(*context_);
415 
416  name_ = var_name;
417 
418  vector_.clear();
419  resize(dimensions);
420  }
421 }
422 
424  const std::string& delimiter)
425 {
426  delimiter_ = delimiter;
427  if (context_)
428  {
429  ContextGuard context_guard(*context_);
430 
431  vector_.clear();
432  resize({0, 0, 0});
433  }
434 }
435 
437 {
438  return delimiter_;
439 }
440 
442  std::vector<std::vector<std::vector<type> > >& target) const
443 {
444  KnowledgeUpdateSettings keep_local(true);
445 
446  if (context_)
447  {
448  ContextGuard context_guard(*context_);
449 
450  Indices dimensions = size();
451 
452  target.resize(dimensions.x);
453 
454  for (size_t i = 0; i < dimensions.x; ++i)
455  {
456  target[i].resize(dimensions.y);
457  for (size_t j = 0; j < dimensions.y; ++j)
458  {
459  target[i][j].resize(dimensions.z);
460  for (size_t k = 0; k < dimensions.z; ++k)
461  {
462  target[i][j][k] =
463  context_->get(vector_[i][j][k], keep_local).to_double();
464  }
465  }
466  }
467  }
468 }
469 
472  const Indices& index) const
473 {
474  type result(0);
475 
476  KnowledgeUpdateSettings keep_local(true);
477 
479  "DoubleVector3D::[]: retrieving [%d,%d,%d].\n", (int)index.x,
480  (int)index.y, (int)index.z);
481 
482  if (context_)
483  {
484  ContextGuard context_guard(*context_);
485 
486  if (index.x < vector_.size() && index.y < vector_[index.x].size() &&
487  index.z < vector_[index.x][index.y].size())
488  {
490  "DoubleVector3D::[]: [%d][%d][%d] is within [%d,%d,%d].\n",
491  (int)index.x, (int)index.y, (int)index.z, (int)vector_.size(),
492  (int)vector_[index.x].size(), (int)vector_[index.x][index.y].size());
493 
494  result = context_->get(vector_[index.x][index.y][index.z], keep_local)
495  .to_double();
496 
498  "DoubleVector3D::[]: value is %.3f.\n", result);
499  }
500  else
501  {
503  "DoubleVector3D::[]: [%d][%d][%d] is not within [%d,%d,%d].\n",
504  (int)index.x, (int)index.y, (int)index.z, (int)vector_.size(),
505  (int)vector_[index.x].size(), (int)vector_[index.x][index.y].size());
506  }
507  }
508 
509  return result;
510 }
511 
513  const Indices& index) const
514 {
515  bool result(false);
516 
517  if (context_)
518  {
519  ContextGuard context_guard(*context_);
520 
521  if (index.x < vector_.size() && index.y < vector_[index.x].size() &&
522  index.z < vector_[index.x][index.y].size())
523  {
524  result = context_->exists(vector_[index.x][index.y][index.z]);
525  }
526  }
527 
528  return result;
529 }
530 
532  const Indices& index, type value)
533 {
534  int result = -1;
535 
536  if (context_)
537  {
538  ContextGuard context_guard(*context_);
539 
540  if (index.x < vector_.size() && index.y < vector_[index.x].size() &&
541  index.z < vector_[index.x][index.y].size())
542  {
543  result =
544  context_->set(vector_[index.x][index.y][index.z], value, settings_);
545  }
546  }
547 
548  return result;
549 }
550 
552  const std::vector<std::vector<std::vector<type> > >& value)
553 {
554  int result = 0;
555 
556  if (context_)
557  {
558  ContextGuard context_guard(*context_);
559 
560  for (size_t i = 0; i < value.size() && i < vector_.size(); ++i)
561  {
562  for (size_t j = 0; j < value[i].size() && j < vector_[i].size(); ++j)
563  {
564  for (size_t k = 0; k < value[i][j].size() && k < vector_[i][j].size();
565  ++k)
566  {
567  context_->set(vector_[i][j][k], value[i][j][k], settings_);
568  }
569  }
570  }
571  }
572 
573  return result;
574 }
575 
577  const Indices& index, type value, const KnowledgeUpdateSettings& settings)
578 {
579  int result = -1;
580 
581  if (context_)
582  {
583  ContextGuard context_guard(*context_);
584 
585  if (index.x < vector_.size() && index.y < vector_[index.x].size() &&
586  index.z < vector_[index.x][index.y].size())
587  {
588  result =
589  context_->set(vector_[index.x][index.y][index.z], value, settings);
590  }
591  }
592 
593  return result;
594 }
595 
597  const std::vector<std::vector<std::vector<type> > >& value,
598  const KnowledgeUpdateSettings& settings)
599 {
600  int result = 0;
601 
602  if (context_)
603  {
604  ContextGuard context_guard(*context_);
605 
606  for (size_t i = 0; i < value.size() && i < vector_.size(); ++i)
607  {
608  for (size_t j = 0; j < value[i].size() && j < vector_[i].size(); ++j)
609  {
610  for (size_t k = 0; k < value[i][j].size() && k < vector_[i][j].size();
611  ++k)
612  {
613  context_->set(vector_[i][j][k], value[i][j][k], settings);
614  }
615  }
616  }
617  }
618 
619  return result;
620 }
621 
623  const Indices& index, uint32_t quality,
624  const KnowledgeReferenceSettings& settings)
625 {
626  if (context_)
627  {
628  ContextGuard context_guard(*context_);
629 
630  if (index.x < vector_.size() && index.y < vector_[index.x].size() &&
631  index.z < vector_[index.x][index.y].size())
632  context_->set_quality(vector_[index.x][index.y][index.z].get_name(),
633  quality, true, settings);
634  }
635 }
636 
638 {
639  bool result(false);
640 
642  "DoubleVector3D::is_true: Checking for truth\n");
643 
644  if (context_)
645  {
646  ContextGuard context_guard(*context_);
647 
648  result = true;
649 
651  "DoubleVector3D::is_true: context was not null. Result changed to %d\n",
652  (int)result);
653 
654  for (size_t i = 0; i < vector_.size(); ++i)
655  {
656  for (size_t j = 0; j < vector_[i].size(); ++i)
657  {
658  for (size_t k = 0; k < vector_[i][j].size(); ++k)
659  {
661  "DoubleVector3D::is_true: checking [%d,%d,%d], is_false of %d. "
662  "\n",
663  (int)i, (int)j, (int)k,
664  (int)context_->get(vector_[i][j][k]).is_false());
665 
666  if (context_->get(vector_[i][j][k]).is_false())
667  {
669  "DoubleVector3D::is_true: result is false, breaking\n");
670 
671  result = false;
672  break;
673  }
674  }
675  }
676  }
677 
678  if (vector_.size() == 0)
679  result = false;
680  }
681 
683  "DoubleVector3D::is_true: final result is %d\n", (int)result);
684 
685  return result;
686 }
687 
689 {
690  return !is_true();
691 }
692 
694 {
695  return is_true();
696 }
697 
699 {
700  return is_false();
701 }
#define madara_logger_log(loggering, level,...)
Fast version of the madara::logger::log method.
Definition: Logger.h:20
const ThreadSafeContext * context_
A thread-safe guard for a context or knowledge base.
Definition: ContextGuard.h:24
This class provides a distributed knowledge base to users.
Definition: KnowledgeBase.h:45
This class encapsulates an entry in a KnowledgeBase.
std::vector< Integer > to_integers(void) const
converts the value to a vector of integers
Settings for applying knowledge updates.
Settings for applying knowledge updates.
This class stores variables and their values for use by any entity needing state information in a thr...
Optimized reference to a variable within the knowledge base.
Provides an interface for external functions into the MADARA KaRL variable settings.
Definition: Variables.h:53
This class is an abstract base class for all containers.
Definition: BaseContainer.h:34
KnowledgeUpdateSettings settings_
Settings for modifications.
std::string name_
Prefix of variable.
MADARA_LOCK_TYPE mutex_
guard for access and changes
Manages a 3D array of doubles as a virtual overlay in the KnowledgeBase.
virtual std::string get_debug_info_(void)
Returns the type of the container along with name and any other useful information.
DoubleVector3D(const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings(), const std::string &delimiter=".")
Default constructor.
VariableReference get_size_ref(void)
Returns a reference to the size of vector.
std::string delimiter_
Delimiter for the prefix to subvars.
void modify(void)
Mark the vector as modified.
virtual bool is_true_(void) const
Polymorphic is true method which can be used to determine if all values in the container are true.
double type
convenience typedef for element type
bool exists(const Indices &index) const
Checks to see if the index has ever been assigned a value.
std::string get_delimiter(void)
Gets the delimiter for adding and detecting subvariables.
void set_delimiter(const std::string &delimiter)
Sets the delimiter for adding and detecting subvariables.
void resize(const Dimensions &dimensions, bool delete_vars=true)
Resizes the vector.
virtual void modify_(void)
Polymorphic modify method used by collection containers.
void operator=(const DoubleVector3D &rhs)
Assignment operator.
std::vector< std::vector< std::vector< VariableReference > > > vector_
Values of the array.
void set_name(const std::string &var_name, KnowledgeBase &knowledge, const Dimensions &dimensions={0, 0, 0})
Sets the variable name that this refers to.
type operator[](const Indices &index) const
Retrieves an index from the multi-dimensional array.
Dimensions size(void) const
Returns the size of the local vector.
VariableReference size_
Reference to the size of 2D array.
bool is_true(void) const
Determines if all values in the vector are true.
void set_quality(const Indices &index, uint32_t quality, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings(false))
Sets the quality of writing to a certain variable from this entity.
bool is_false(void) const
Determines if the value of the vector is false.
virtual BaseContainer * clone(void) const
Clones this container.
std::string get_debug_info(void)
Returns the type of the container along with name and any other useful information.
virtual bool is_false_(void) const
Polymorphic is false method which can be used to determine if at least one value in the container is ...
ThreadSafeContext * context_
Variable context that we are modifying.
int set(const Indices &index, type value)
Sets a knowledge variable to a specified value.
void copy_to(std::vector< std::vector< std::vector< type > > > &target) const
Copies the vector elements to an STL vector.
constexpr string_t string
Provides functions and classes for the distributed knowledge base.