Memory.cpp
Go to the documentation of this file.
1#include "Memory.h"
2
3#include <memory>
4
7
14
16{
17 void
18 Memory::_configure(const nlohmann::json& json)
19 {
21
24
25 std::string exportPath = p.export_path;
26
27 std::string persistenceStrategiesStr = p.persistenceStrategies;
28
29 ARMARX_INFO << "Persistence strategies=" << persistenceStrategiesStr;
30
31 std::vector<std::string> persistenceStrategies = split(persistenceStrategiesStr, ',');
32
33 ARMARX_INFO << "Found " << persistenceStrategies.size() << " persistence strategies";
34
35
36 std::string identifiersStr = p.persistenceStrategyIdentifier;
37 std::vector<std::string> identifiers = split(identifiersStr, ',');
38 std::string identifier = "defaultStrategy";
39 ARMARX_INFO << "Persistence identifiers=" << identifiersStr;
40 ARMARX_INFO << "Found " << identifiers.size() << " persistence strategies identifiers";
41
42
43 std::shared_ptr<armem::server::ltm::persistence::RedundantPersistenceStrategy>
44 redundantPersistence =
45 std::make_shared<armem::server::ltm::persistence::RedundantPersistenceStrategy>();
46 redundantPersistence->setExportName(getExportName());
47
48 for (size_t i = 0; i < persistenceStrategies.size(); i++)
49 {
50 std::string s = persistenceStrategies.at(i);
51
52 if (i < identifiers.size())
53 {
54 identifier = identifiers.at(i);
55 }
56
57 if (s == "disk")
58 {
59 ARMARX_IMPORTANT << "Using persistence strategy=" << s;
60 ARMARX_INFO << "MemoryID=" << getMemoryID().str();
61 ARMARX_INFO << "Identifier=" << identifier;
62 ARMARX_INFO << "Export name=" << getExportName();
63 ARMARX_INFO << "Export path=" << exportPath;
64 ARMARX_INFO << "Min available disk space=" << p.minDiskSpace;
65
66 std::shared_ptr<armem::server::ltm::persistence::DiskPersistence> diskPersistence =
67 std::make_shared<armem::server::ltm::persistence::DiskPersistence>(
68 std::filesystem::path(exportPath));
69 diskPersistence->setIdentifier(identifier);
70 diskPersistence->setExportName(getExportName());
71 diskPersistence->setMinAvailableDiskSpace(p.minDiskSpace);
72
73 // Configure compression if enabled
74 if (p.compressionEnabled)
75 {
76 diskPersistence->setCompressionLevel(p.compressionLevel);
77 diskPersistence->setCompressionMinBytes(
78 static_cast<std::size_t>(p.compressionMinBytes));
79 diskPersistence->setCompressionEnabled(true);
80 ARMARX_INFO << "LTM export compression enabled: gzip level "
81 << p.compressionLevel << " for payloads >= "
82 << p.compressionMinBytes << " bytes";
83 }
84
85 // Configure batch writing if enabled
86 if (p.batchWriteEnabled)
87 {
88 diskPersistence->setBatchSizeThreshold(static_cast<size_t>(p.batchSizeThreshold));
89 diskPersistence->setBatchTimeThresholdMs(static_cast<size_t>(p.batchTimeThresholdMs));
90 diskPersistence->setBatchWriteEnabled(true);
91 ARMARX_INFO << "Batch write mode enabled: threshold=" << p.batchSizeThreshold
92 << " items or " << p.batchTimeThresholdMs << "ms";
93 }
94
95 redundantPersistence->addStrategy(diskPersistence);
96 }
97 else if (s == "rest")
98 {
99 ARMARX_IMPORTANT << "Using persistence strategy=" << s;
100 ARMARX_WARNING << "Persistence strategy=" << s << " currently deactivated";
101 /**
102 ARMARX_INFO << "MemoryID=" << getMemoryID().str();
103 ARMARX_INFO << "Identifier=" << identifier;
104 ARMARX_INFO << "Export name=" << getExportName();
105 ARMARX_INFO << "Host=" << p.restHost;
106 ARMARX_INFO << "Port=" << p.restPort;
107 ARMARX_INFO << "DisableIfNotAvailable=" << p.restDisableIfNotAvailable;
108
109 std::shared_ptr<armem::server::ltm::persistence::RestPersistence> restPersistence =
110 std::make_shared<armem::server::ltm::persistence::RestPersistence>(
111 identifier,
112 getExportName(),
113 p.restHost,
114 p.restPort,
115 p.restDisableIfNotAvailable);
116
117
118 redundantPersistence->addStrategy(restPersistence);
119 */
120 }
121 else if (s == "mongodb")
122 {
123 ARMARX_IMPORTANT << "Using persistence strategy=" << s;
124 ARMARX_WARNING << "Persistence strategy=" << s << " not implemented";
125 }
126 else
127 {
128 ARMARX_WARNING << "Persistence strategy=" << s << " unknown";
129 }
130 }
131
132 setPersistenceStrategy(redundantPersistence);
133 }
134
135 Memory::Memory() : Memory("MemoryExport", "Test")
136 {
137 }
138
139 Memory::Memory(const std::string& exportName, const std::string& memoryName) :
140 MemoryBase(exportName, MemoryID(memoryName, "")),
141 BufferedBase(MemoryID(memoryName, "")),
142 CachedBase(MemoryID(memoryName, "")),
143 persistenceStrategy_(std::make_shared<persistence::RedundantPersistenceStrategy>())
144 {
145 }
146
148 const std::string& exportName,
149 const std::string& memoryName,
150 const std::shared_ptr<persistence::RedundantPersistenceStrategy>& persistenceStrategy) :
151 MemoryBase(exportName, MemoryID(memoryName, "")),
152 BufferedBase(MemoryID(memoryName, "")),
153 CachedBase(MemoryID(memoryName, "")),
154 persistenceStrategy_(persistenceStrategy)
155 {
156 }
157
158 void
159 Memory::_setExportName(const std::string& memoryName)
160 {
162
163 if (persistenceStrategy_)
164 {
165 persistenceStrategy_->setExportName(memoryName);
166 }
167 }
168
169 void
171 {
173
175 }
176
177 void
179 {
181
183 ARMARX_IMPORTANT << "Storing of data finished, starting to generate and save statistics...";
185 }
186
187 void
189 {
191
192 ARMARX_DEBUG << "Setting memory=" << memoryId.memoryName
193 << ", id=" << memoryId.cleanID().str();
194
197 }
198
199 bool
200 Memory::_implForEachCoreSegment(std::function<void(CoreSegment&)> func) const
201 {
203
204 ARMARX_DEBUG << "For each core segment (mem id=" << id().cleanID().str() << ")";
205
206
207 for (auto& core_segment : persistenceStrategy_->getContainerKeys(id()))
208 {
209 ARMARX_DEBUG << "Found core segment=" << core_segment;
210
211 std::shared_ptr<persistence::MemoryPersistenceStrategy> coreSegmentPersistenceStrategy(
212 persistenceStrategy_);
213
215 id().withCoreSegmentName(core_segment),
217 coreSegmentPersistenceStrategy);
218 func(c);
219 }
220
221
222 return true;
223 }
224
225 bool
226 Memory::_implHasCoreSegment(const std::string& coreSegmentName) const
227 {
229
230 bool foundCoreSegment = cacheHasCoreSegment(coreSegmentName) ||
231 persistenceStrategy_->containsContainer(id(), coreSegmentName);
232
233 return foundCoreSegment;
234 }
235
236 std::shared_ptr<CoreSegment>
237 Memory::_implFindCoreSegment(const std::string& coreSegmentName) const
238 {
240
241 if (!_implHasCoreSegment(coreSegmentName)) // Call _impl version
242 {
243 return nullptr;
244 }
245
246 std::shared_ptr<persistence::MemoryPersistenceStrategy> coreSegmentPersistenceStrategy(
247 persistenceStrategy_);
248
249 return std::make_shared<CoreSegment>(getExportName(),
250 id().withCoreSegmentName(coreSegmentName),
252 coreSegmentPersistenceStrategy);
253 }
254
255 void
257 {
259
262 }
263
264 void
266 {
268
269 wmMemory.id() = id().getMemoryID().cleanID();
270
271 ARMARX_DEBUG << "Memory: Load all references (id=" << wmMemory.id().cleanID().str() << ")";
272
274 [&wmMemory](auto& ltmCoreSegment)
275 {
276 armem::wm::CoreSegment wmCoreSegment;
277 ltmCoreSegment.loadAllReferences(wmCoreSegment);
278
279 // Because there might be multiple LTMs providers with the same provider segment
280 if (wmMemory.hasCoreSegment(wmCoreSegment.name()))
281 {
282 armem::wm::CoreSegment existingWmCoreSegment =
283 wmMemory.getCoreSegment(wmCoreSegment.name());
284 existingWmCoreSegment.append(wmCoreSegment);
285 }
286 else
287 {
288 wmMemory.addCoreSegment(wmCoreSegment);
289 }
290 });
291 }
292
293 void
294 Memory::_loadAllReferences(armem::wm::Memory& wmMemory, std::list<std::string> coreSegmentNames)
295 {
296 //TODO
298
299 wmMemory.id() = id().getMemoryID().cleanID();
300
301 ARMARX_DEBUG << "Memory: Load all references (id=" << wmMemory.id().cleanID().str() << ")";
302
304 [&wmMemory, &coreSegmentNames](auto& ltmCoreSegment)
305 {
306 bool loadCoreSeg =
307 (std::find(coreSegmentNames.begin(),
308 coreSegmentNames.end(),
309 ltmCoreSegment.id().coreSegmentName) != coreSegmentNames.end());
310 if (loadCoreSeg)
311 {
312 armem::wm::CoreSegment wmCoreSegment;
313 ltmCoreSegment.loadAllReferences(wmCoreSegment);
314
315 // Because there might be multiple LTMs providers with the same provider segment
316 if (wmMemory.hasCoreSegment(wmCoreSegment.name()))
317 {
318 armem::wm::CoreSegment existingWmCoreSegment =
319 wmMemory.getCoreSegment(wmCoreSegment.name());
320 existingWmCoreSegment.append(wmCoreSegment);
321 }
322 else
323 {
324 wmMemory.addCoreSegment(wmCoreSegment);
325 }
326 }
327 else
328 {
329 ARMARX_DEBUG << "Skipping loading CoreSegment with name "
330 << wmMemory.id().coreSegmentName
331 << " from LTM into WM as it is not in the defined list";
332 }
333 });
334 }
335
336 void
338 {
340 wmMemory.id() = id().getMemoryID().cleanID();
341
342 ARMARX_DEBUG << "Memory: Load latest N references for all core segments (id="
343 << wmMemory.id().cleanID().str() << ")";
344
346 [&wmMemory, &n](auto& ltmCoreSegment)
347 {
348 armem::wm::CoreSegment wmCoreSegment;
349 ltmCoreSegment.loadLatestNReferences(n, wmCoreSegment);
350
351 // Because there might be multiple LTMs providers with the same provider segment
352 if (wmMemory.hasCoreSegment(wmCoreSegment.name()))
353 {
354 armem::wm::CoreSegment existingWmCoreSegment =
355 wmMemory.getCoreSegment(wmCoreSegment.name());
356 existingWmCoreSegment.append(wmCoreSegment);
357 }
358 else
359 {
360 wmMemory.addCoreSegment(wmCoreSegment);
361 }
362 });
363 }
364
365 void
367 armem::wm::Memory& wmMemory,
368 std::list<std::string> coreSegNames)
369 {
371 wmMemory.id() = id().getMemoryID().cleanID();
372
373 ARMARX_DEBUG << "Memory: Load latest references for set of core segments (id="
374 << wmMemory.id().cleanID().str() << ")";
375
377 [&wmMemory, &n, &coreSegNames](auto& ltmCoreSegment)
378 {
379 bool loadCoreSeg =
380 (std::find(coreSegNames.begin(),
381 coreSegNames.end(),
382 ltmCoreSegment.id().coreSegmentName) != coreSegNames.end());
383 if (loadCoreSeg)
384 {
385 ARMARX_DEBUG << "Load core segment=" << ltmCoreSegment.id().coreSegmentName;
386 armem::wm::CoreSegment wmCoreSegment;
387 ltmCoreSegment.loadLatestNReferences(n, wmCoreSegment);
388
389 // Because there might be multiple LTMs providers with the same provider segment
390 if (wmMemory.hasCoreSegment(wmCoreSegment.name()))
391 {
392 armem::wm::CoreSegment existingWmCoreSegment =
393 wmMemory.getCoreSegment(wmCoreSegment.name());
394 existingWmCoreSegment.append(wmCoreSegment);
395 }
396 else
397 {
398 wmMemory.addCoreSegment(wmCoreSegment);
399 }
400 }
401 else
402 {
403 ARMARX_DEBUG << "Skipping loading CoreSegment with name "
404 << wmMemory.id().coreSegmentName
405 << " from LTM into WM as it is not in the defined list";
406 }
407 });
408 }
409
410 void
412 {
414
415 ARMARX_DEBUG << "Resolve memory id=" << id().cleanID().str();
416
417 wmMemory.forEachCoreSegment(
418 [&](auto& wmCoreSegment)
419 {
420 std::shared_ptr<persistence::MemoryPersistenceStrategy>
421 coreSegmentPersistenceStrategy(persistenceStrategy_);
422
423 CoreSegment ltmCoreSegment(
425 id().withCoreSegmentName(wmCoreSegment.id().coreSegmentName),
427 coreSegmentPersistenceStrategy);
428
429 ltmCoreSegment.resolve(wmCoreSegment);
430 });
431 }
432
433 void
435 {
438 }
439
440 void
441 Memory::_directlyStore(const armem::wm::Memory& wmMemory, bool simulatedVersion)
442 {
444
445 if (id().memoryName.empty())
446 {
448 << "During storage of memory '" << wmMemory.id().str()
449 << "' I noticed that the corresponding LTM has no id set. "
450 << "I set the id of the LTM to the same name, however this should not happen!";
451 setMemoryID(wmMemory.id());
452 }
453
454 ARMARX_DEBUG << "Directly store memory id=" << id().cleanID().str();
455 ARMARX_DEBUG << "CoreSegments: " << wmMemory.getCoreSegmentNames().size();
456
457 wmMemory.forEachCoreSegment(
458 [&](const auto& wmCoreSegment)
459 {
460 std::shared_ptr<persistence::MemoryPersistenceStrategy>
461 coreSegmentPersistenceStrategy(persistenceStrategy_);
462
463 CoreSegment ltmCoreSegment(
465 id().withCoreSegmentName(wmCoreSegment.id().coreSegmentName),
467 coreSegmentPersistenceStrategy);
468
469 // 2. store data
470 ltmCoreSegment.store(wmCoreSegment, simulatedVersion);
471
472
473 // 3. update statistics
474 statistics.recordedCoreSegments++;
475 });
476
477 // 4. update cache
478 //CachedBase::addToCache(memory);
479 }
480
481 std::shared_ptr<armem::wm::Memory>
483 uint64_t& filteredCount,
484 uint64_t& passedCount)
485 {
487
488 filteredCount = 0;
489 passedCount = 0;
490
491 // If no filters and no segment selection configured, return a copy of the original memory
492 if (!processors || (processors->snapFilters.empty() && !processors->hasSegmentSelection()))
493 {
494 // Count all snapshots as passed
495 memory.forEachCoreSegment([&](const auto& cs) {
496 cs.forEachProviderSegment([&](const auto& ps) {
497 ps.forEachEntity([&](const auto& entity) {
498 entity.forEachSnapshot([&](const auto&) {
499 passedCount++;
500 });
501 });
502 });
503 });
504
505 // Return a copy wrapped in shared_ptr
506 return std::make_shared<armem::wm::Memory>(memory);
507 }
508
509 // Create a new memory for filtered snapshots
510 auto filteredMemory = std::make_shared<armem::wm::Memory>(memory.id());
511
512 // Iterate through the memory hierarchy and apply filters
513 memory.forEachCoreSegment([&](const auto& wmCoreSegment) {
514 wmCoreSegment.forEachProviderSegment([&](const auto& wmProviderSegment) {
515 wmProviderSegment.forEachEntity([&](const auto& wmEntity) {
516 wmEntity.forEachSnapshot([&](const auto& wmSnapshot) {
517 // Apply the segment whitelist and per-segment / global snapshot filters
518 bool accepted = processors->acceptSnapshotForSegment(
519 wmCoreSegment.name(), wmProviderSegment.name(), wmSnapshot, false);
520
521 if (accepted)
522 {
523 // Add snapshot to filtered memory
524 // Need to ensure the hierarchy exists
525 auto& cs = filteredMemory->hasCoreSegment(wmCoreSegment.name())
526 ? filteredMemory->getCoreSegment(wmCoreSegment.name())
527 : filteredMemory->addCoreSegment(wmCoreSegment.name());
528
529 auto& ps = cs.hasProviderSegment(wmProviderSegment.name())
530 ? cs.getProviderSegment(wmProviderSegment.name())
531 : cs.addProviderSegment(wmProviderSegment.name());
532
533 auto& entity = ps.hasEntity(wmEntity.name())
534 ? ps.getEntity(wmEntity.name())
535 : ps.addEntity(wmEntity.name());
536
537 entity.addSnapshot(wmSnapshot);
538 passedCount++;
539 }
540 else
541 {
542 filteredCount++;
543 }
544 });
545 });
546 });
547 });
548
549 ARMARX_DEBUG << "Pre-filter: " << passedCount << " passed, "
550 << filteredCount << " filtered out";
551
552 return filteredMemory;
553 }
554
555 void
557 {
558 //not used any more
559 }
560
561 void
562 Memory::_enqueueForAsyncStorage(std::shared_ptr<const armem::wm::Memory> memory)
563 {
565 // Forward to the BufferedMemoryMixin's async storage queue
567 }
568
569 void
571 {
573 // Forward to the BufferedMemoryMixin's async storage queue
574 BufferedBase::enqueuePendingConversion(std::move(pending));
575 }
576
577 void
579 {
581 auto firstTimeStarted = this->statistics.firstStarted;
582 if (!firstTimeStarted.isValid())
583 {
584 //No statistics to be saved, as recording was never started
585 ARMARX_DEBUG << "No Statistics will be saved because firstStarted is invalid: "
586 << VAROUT(this->statistics.firstStarted);
587 return;
588 }
589
590 ARMARX_DEBUG << "Preparing to save statistics for " << this->name();
591 try
592 {
593 auto first_stats = this->getFilterStatistics();
594 if (first_stats.empty())
595 {
596 //empty statistics mean no data was recorded and no statistics should be saved
597 ARMARX_DEBUG << "No Statistics will be saved because no actual data was recorded.";
598 return;
599 }
600 std::map<std::string,
601 std::map<std::string, ltm::processor::SnapshotFilter::FilterStatistics>>
602 information;
603 std::map<std::string, armarx::core::time::DateTime> times;
604
605 try
606 {
607 times["Started LTM1"] = this->getStatistics().lastStarted;
608 times["Stopped LTM1"] = this->getStatistics().lastStopped;
609 information["LTM"] = first_stats;
610 }
611 catch (...)
612 {
613 ARMARX_DEBUG << "Something went wrong after getting the statistics";
614 }
615 // auto exportPath = this->getMemoryBasePath();
616 auto exportName = this->getExportName();
617 auto recording_started = this->getStatistics().lastStarted;
618 auto recording_stopped = this->getStatistics().lastStopped;
619 // test::save_statistics(information,
620 // times,
621 // recording_started,
622 // recording_stopped,
623 // exportPath,
624 // exportName,
625 // this->name());
626 }
627 catch (...)
628 {
629 ARMARX_DEBUG << "Something went wrong with the statistics saving process";
630 }
631 }
632
633 std::vector<std::string>
634 Memory::split(std::string str, char delimiter)
635 {
637 // Using str in a string stream
638 std::stringstream ss(str);
639 std::vector<std::string> res;
640 std::string token;
641 while (std::getline(ss, token, delimiter))
642 {
643 res.push_back(token);
644 }
645 return res;
646 }
647} // namespace armarx::armem::server::ltm
#define VAROUT(x)
constexpr T c
std::string str(const T &t)
std::string coreSegmentName
Definition MemoryID.h:51
MemoryID getMemoryID() const
Definition MemoryID.cpp:286
MemoryID cleanID() const
Definition MemoryID.cpp:133
std::string str(bool escapeDelimiters=true) const
Get a string representation of this memory ID.
Definition MemoryID.cpp:102
std::string memoryName
Definition MemoryID.h:50
void append(const OtherDerivedT &other)
bool forEachCoreSegment(CoreSegmentFunctionT &&func)
Definition MemoryBase.h:188
bool hasCoreSegment(const std::string &name) const
Definition MemoryBase.h:107
CoreSegmentT & addCoreSegment(const std::string &name, aron::type::ObjectPtr coreSegmentType=nullptr, const std::vector< PredictionEngine > &predictionEngines={})
Add an empty core segment with the given name, type and prediction engines.
Definition MemoryBase.h:261
std::vector< std::string > getCoreSegmentNames() const
Definition MemoryBase.h:240
CoreSegmentT & getCoreSegment(const std::string &name)
Definition MemoryBase.h:134
void getAndSaveStatistics()
getAndSaveStatistics generates and saves statistics for a LTM recording
Definition Memory.cpp:578
void _setMemoryID(const MemoryID &memoryId) final
Definition Memory.cpp:188
void _enqueueForAsyncStorage(std::shared_ptr< const armem::wm::Memory > memory) final
Definition Memory.cpp:562
void _resolve(armem::wm::Memory &wmMemory) final
Definition Memory.cpp:411
detail::mixin::BufferedMemoryMixin< CoreSegment > BufferedBase
Definition Memory.h:27
detail::mixin::CachedMemoryMixin< CoreSegment > CachedBase
Definition Memory.h:28
void _loadLatestNReferences(int n, armem::wm::Memory &wmMemory) final
Definition Memory.cpp:337
void _directlyStore(const armem::wm::Memory &wmMemory, bool simulatedVersion) final
Definition Memory.cpp:441
void _setExportName(const std::string &memoryName) final
Definition Memory.cpp:159
bool _implHasCoreSegment(const std::string &coreSegmentName) const final
Definition Memory.cpp:226
bool _implForEachCoreSegment(std::function< void(CoreSegment &)> func) const final
Definition Memory.cpp:200
std::shared_ptr< armem::wm::Memory > _preFilterMemory(const armem::wm::Memory &memory, uint64_t &filteredCount, uint64_t &passedCount) final
Pre-filter a memory object before enqueuing for async storage.
Definition Memory.cpp:482
void setPersistenceStrategy(std::shared_ptr< persistence::RedundantPersistenceStrategy > persistenceStrategy)
Definition Memory.h:89
std::shared_ptr< CoreSegment > _implFindCoreSegment(const std::string &coreSegmentName) const final
Definition Memory.cpp:237
void _loadAllReferences(armem::wm::Memory &wmMemory) final
Definition Memory.cpp:265
void _store(const armem::wm::Memory &wmMemory) final
Definition Memory.cpp:434
void createPropertyDefinitions(PropertyDefinitionsPtr &defs, const std::string &prefix) override
default parameters. Implementation should use the configuration to configure
Definition Memory.cpp:256
void _configure(const nlohmann::json &config) final
configuration
Definition Memory.cpp:18
void _enqueuePendingConversion(detail::mixin::PendingConversion pending) final
Definition Memory.cpp:570
detail::MemoryBase< CoreSegment > MemoryBase
Definition Memory.h:26
void store(const armem::wm::CoreSegment &coreSeg, bool simulatedVersion)
encode the content of a wm::Memory and store
void resolve(armem::wm::CoreSegment &coreSeg)
convert the references of the input into a wm::Memory
virtual void createPropertyDefinitions(PropertyDefinitionsPtr &defs, const std::string &prefix)
Definition MemoryBase.h:391
bool forEachCoreSegment(std::function< void(CoreSegmentT &)> func) const
Definition MemoryBase.h:370
struct armarx::armem::server::ltm::detail::MemoryBase::Properties p
std::map< std::string, processor::SnapshotFilter::FilterStatistics > getFilterStatistics()
Definition MemoryBase.h:479
virtual std::string getExportName() const
Definition MemoryItem.h:27
std::shared_ptr< Processors > processors
Definition MemoryItem.h:54
void createPropertyDefinitions(PropertyDefinitionsPtr &defs, const std::string &prefix)
void enqueueForAsyncStoragePublic(std::shared_ptr< const armem::wm::Memory > memory)
Client-side working memory core segment.
Client-side working memory.
Brief description of class memory.
Definition memory.h:39
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:179
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:188
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:182
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:191
const std::list< std::string > identifiers
auto make_shared(Args &&... args)
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
Holds snapshots and metadata for deferred conversion in async thread This allows us to defer the expe...
#define ARMARX_TRACE
Definition trace.h:75