File: test.cpp

package info (click to toggle)
mrpt 1%3A2.5.8%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 87,448 kB
  • sloc: cpp: 551,662; ansic: 38,702; xml: 3,914; python: 2,547; sh: 404; makefile: 237
file content (140 lines) | stat: -rw-r--r-- 4,009 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/* +------------------------------------------------------------------------+
   |                     Mobile Robot Programming Toolkit (MRPT)            |
   |                          https://www.mrpt.org/                         |
   |                                                                        |
   | Copyright (c) 2005-2023, Individual contributors, see AUTHORS file     |
   | See: https://www.mrpt.org/Authors - All rights reserved.               |
   | Released under BSD License. See: https://www.mrpt.org/License          |
   +------------------------------------------------------------------------+ */

#include <mrpt/io/CPipe.h>
#include <mrpt/poses/CPose2D.h>
#include <mrpt/poses/CPose3D.h>
#include <mrpt/serialization/CArchive.h>

#include <chrono>
#include <iostream>
#include <thread>

using namespace mrpt;
using namespace mrpt::poses;
using namespace mrpt::system;
using namespace mrpt::io;
using namespace mrpt::serialization;
using namespace std;

void thread_reader(CPipeReadEndPoint& read_pipe)
{
	try
	{
		std::cout << "[thread_reader ID:" << std::this_thread::get_id()
				  << "] Started." << std::endl;

		// Simple read commands:
		size_t len = 0;
		char buf[100];
		read_pipe.Read(&len, sizeof(len));
		read_pipe.Read(buf, len);
		buf[len] = 0;
		cout << "RX: " << buf << endl;

		// Read MRPT object from a pipe:
		// *Note*: If the object class is known in advance, one can avoid smart
		// pointers with ReadObject(&existingObj)
		auto arch = archiveFrom(read_pipe);
#if !defined(HAS_BROKEN_CLANG_STD_VISIT)
		auto doprint = [](auto& pose) { cout << "RX pose: " << pose << endl; };
		auto var =
			arch.ReadVariant<mrpt::poses::CPose2D, mrpt::poses::CPose3D>();
		std::visit(doprint, var);
		var = arch.ReadVariant<mrpt::poses::CPose2D, mrpt::poses::CPose3D>();
		std::visit(doprint, var);
#else
		std::cout << "Code disabled for clang due to variant bug. See: "
					 "https://stackoverflow.com/a/46507150/1631514\n";
#endif

		printf("[thread_reader] Finished.\n");
	}
	catch (const std::exception& e)
	{
		cerr << e.what() << endl;
	}
}

void thread_writer(CPipeWriteEndPoint& write_pipe)
{
	try
	{
		std::cout << "[thread_writer ID:" << std::this_thread::get_id()
				  << "] Started." << std::endl;

		// Simple write commands:
		const char* str = "Hello world!";
		size_t len = strlen(str);
		write_pipe.Write(&len, sizeof(len));
		write_pipe.Write(str, len);

		// Send MRPT objects:
		mrpt::poses::CPose3D pose1(1, 2, 3, 1.57, 3.14, 0);
		mrpt::poses::CPose2D pose2(1.0, 2.0, 3.1415);

#if !defined(HAS_BROKEN_CLANG_STD_VISIT)
		std::variant<mrpt::poses::CPose3D, mrpt::poses::CPose2D> var1(
			std::move(pose1));
		std::variant<mrpt::poses::CPose3D, mrpt::poses::CPose2D> var2(
			std::move(pose2));
		auto arch = archiveFrom(write_pipe);
		arch.WriteVariant(var1);
		arch.WriteVariant(var2);
#endif
		printf("[thread_writer] Finished.\n");
	}
	catch (const std::exception& e)
	{
		cerr << e.what() << endl;
	}
}

// ------------------------------------------------------
//				ThreadsTest
// ------------------------------------------------------
void ThreadsTest()
{
	// Create a pipe:
	std::unique_ptr<CPipeReadEndPoint> read_pipe;
	std::unique_ptr<CPipeWriteEndPoint> write_pipe;

	CPipe::createPipe(read_pipe, write_pipe);

	// And send the two end-points to two threads:
	std::thread hT1(thread_reader, std::ref(*read_pipe));
	std::thread hT2(thread_writer, std::ref(*write_pipe));

	using namespace std::chrono_literals;
	std::this_thread::sleep_for(10ms);
	// Wait for the threads to end.
	hT2.join();
	// We need to close this to ensure the pipe gets flushed
	// Remember Unix uses buffered io
	// write_pipe.reset();
	hT1.join();
}

// ------------------------------------------------------
//						MAIN
// ------------------------------------------------------
int main()
{
	try
	{
		ThreadsTest();

		return 0;
	}
	catch (const std::exception& e)
	{
		std::cerr << "MRPT error: " << mrpt::exception_to_str(e) << std::endl;
		return -1;
	}
}