liblo  0.32
cpp_example.cpp
1 
2 #include <iostream>
3 #include <atomic>
4 
5 #ifndef WIN32
6 #include <unistd.h>
7 #endif
8 
9 #include <lo/lo.h>
10 #include <lo/lo_cpp.h>
11 
12 int main()
13 {
14  /*
15  * Create a server on a background thread. Note, all message
16  * handlers will run on the background thread!
17  */
18  lo::ServerThread st(9000);
19  if (!st.is_valid()) {
20  std::cout << "Nope." << std::endl;
21  return 1;
22  }
23 
24  /* Set some lambdas to be called when the thread starts and
25  * ends. Here we demonstrate capturing a reference to the server
26  * thread. */
27  st.set_callbacks([&st](){printf("Thread init: %p.\n",&st);},
28  [](){printf("Thread cleanup.\n");});
29 
30  std::cout << "URL: " << st.url() << std::endl;
31 
32  /*
33  * Counter for number of messages received -- we use an atomic
34  * because it will be updated in a background thread.
35  */
36  std::atomic<int> received(0);
37 
38  /*
39  * Add a method handler for "/example,i" using a C++11 lambda to
40  * keep it succinct. We capture a reference to the `received'
41  * count and modify it atomatically.
42  *
43  * You can also pass in a normal function, or a callable function
44  * object.
45  *
46  * Note: If the lambda doesn't specify a return value, the default
47  * is `return 0', meaning "this message has been handled,
48  * don't continue calling the method chain." If this is not
49  * the desired behaviour, add `return 1' to your method
50  * handlers.
51  */
52  st.add_method("example", "i",
53  [&received](lo_arg **argv, int)
54  {std::cout << "example (" << (++received) << "): "
55  << argv[0]->i << std::endl;});
56 
57  /*
58  * Start the server.
59  */
60  st.start();
61 
62  /*
63  * Send some messages to the server we just created on localhost.
64  */
65  lo::Address a("localhost", "9000");
66 
67  /*
68  * An individual message
69  */
70  a.send("example", "i", 7890987);
71 
72  /*
73  * Initalizer lists and message constructors are supported, so
74  * that bundles can be created easily:
75  */
76  a.send(lo::Bundle({{"example", lo::Message("i", 1234321)},
77  {"example", lo::Message("i", 4321234)}}));
78 
79  /*
80  * Polymorphic overloads on lo::Message::add() mean you don't need
81  * to specify the type explicitly. This is intended to be useful
82  * for templates.
83  */
84  lo::Message m;
85  m.add(7654321);
86  a.send("example", m);
87 
88  /*
89  * Wait for messages to be received and processed.
90  */
91  int tries = 200;
92  while (received < 4 && --tries > 0) {
93 #ifdef WIN32
94  Sleep(10);
95 #else
96  usleep(10*1000);
97 #endif
98  }
99 
100  if (tries <= 0) {
101  std::cout << "Error, waited too long for messages." << std::endl;
102  return 1;
103  }
104 
105  /*
106  * Resources are freed automatically, RAII-style, including
107  * closing the background server.
108  */
109  std::cout << "Success!" << std::endl;
110 }
Class representing an OSC destination address, proxy for lo_address.
Definition: lo_cpp.h:163
Class representing an OSC bundle, proxy for lo_bundle.
Definition: lo_cpp.h:970
Class representing an OSC message, proxy for lo_message.
Definition: lo_cpp.h:323
Class representing a server thread, proxy for lo_server_thread.
Definition: lo_cpp.h:755
Union used to read values from incoming messages.
Definition: lo_osc_types.h:104