C++ Client#

This client provides a C++ API for interacting with a kRPC server.

Installing#

vcpkg#

The C++ client is available from vcpkg, which builds it along with its ASIO (network communication) and protobuf (message serialization) dependencies. It can be installed as follows:

vcpkg install krpc

Then integrate with your CMake project by passing the vcpkg toolchain file at configure time:

cmake -B build -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake

CMake#

The C++ client requires ASIO (for network communication) and protobuf (for message serialization). By default, CMake looks for these as system-installed packages. On Ubuntu they can be installed using:

apt-get install libasio-dev \
    libprotobuf-dev protobuf-compiler

CMake 3.15 or later is required. Download the source archive, extract it and run:

cmake -B build
cmake --build build
cmake --install build

To download all dependencies automatically via FetchContent instead of using system packages, pass -DKRPC_FETCH_DEPS=ON to the CMake configure step. Fine-grained options -DKRPC_FETCH_PROTOBUF=ON, -DKRPC_FETCH_ASIO=ON, and -DKRPC_FETCH_ABSL=ON are also available. When an option is OFF (the default) the system package is required.

Getting Started#

The following example program connects to the server, queries it for its version and prints it out:

#include <iostream>
#include <krpc.hpp>
#include <krpc/services/krpc.hpp>

int main() {
  auto conn = krpc::connect();
  krpc::services::KRPC krpc(&conn);
  std::cout << "Connected to kRPC server version " << krpc.get_status().version() << std::endl;
}

A kRPC program needs to be compiled with C++17 support enabled, and linked against libkrpc, libprotobuf-lite and libz.

To compile this example using GCC, save the source as main.cpp and run the following:

g++ main.cpp -std=c++17 -lkrpc -lprotobuf-lite -lz

If you build your program with CMake, link against the installed library in your CMakeLists.txt:

find_package(krpc CONFIG REQUIRED)
target_link_libraries(my_app PRIVATE krpc::krpc)

Connecting to the Server#

The krpc::connect() function is used to open a connection to a server. It returns a client object (of type krpc::Client) through which you can interact with the server. When called without any arguments, it will connect to the local machine on the default port numbers. You can specify different connection settings, and also a descriptive name for the connection, as follows:

#include <iostream>
#include <krpc.hpp>
#include <krpc/services/krpc.hpp>

int main() {
  auto conn = krpc::connect("My Example Program", "192.168.1.10", 1000, 1001);
  krpc::services::KRPC krpc(&conn);
  std::cout << krpc.get_status().version() << std::endl;
}

Calling Remote Procedures#

The kRPC server provides procedures that a client can run. These procedures are arranged in groups called services to keep things organized. The functionality for the services are defined in the header files in krpc/services/.... For example, all of the functionality provided by the SpaceCenter service is contained in the header file krpc/services/space_center.hpp.

To interact with a service, you must include its header file and create an instance of the service, passing a krpc::Client object to its constructor.

The following example demonstrates how to invoke remote procedures using the C++ client. It instantiates the SpaceCenter service and calls krpc::services::SpaceCenter::active_vessel() to get an object representing the active vessel (of type krpc::services::SpaceCenter::Vessel). It sets the name of the vessel and then prints out its altitude:

#include <iostream>
#include <krpc.hpp>
#include <krpc/services/space_center.hpp>

int main() {
  auto conn = krpc::connect();
  krpc::services::SpaceCenter sc(&conn);
  auto vessel = sc.active_vessel().value();
  vessel.set_name("My Vessel");
  auto flight_info = vessel.flight();
  std::cout << flight_info.mean_altitude() << std::endl;
}

Many procedures return an object identifying something in the game, such as a vessel or a part. See Object Lifetime for how such an object behaves when a game is loaded or what it identifies is destroyed.

Server Side Functions#

A server side function is code that runs inside the game, on the server. krpc::run() evaluates one once and returns its value. Every value it reads comes from the same physics tick. For example, the following reads the vessel’s altitude and speed together:

#include <iostream>
#include <tuple>

#include <krpc.hpp>
#include <krpc/function_stream.hpp>
#include <krpc/services/krpc.hpp>
#include <krpc/services/space_center.hpp>

int main() {
  auto conn = krpc::connect();
  krpc::services::SpaceCenter sc(&conn);
  auto vessel = sc.active_vessel().value();
  auto flight = vessel.flight(vessel.orbit().body().reference_frame());

  // Get the remote procedure calls as message objects,
  // so they can be passed to the server
  auto mean_altitude_call = flight.mean_altitude_call();
  auto speed_call = flight.speed_call();

  // Build a function that reads the altitude and the speed
  typedef krpc::services::KRPC::Expression Expr;
  auto expr = Expr::create_tuple(conn, {
    Expr::call(conn, mean_altitude_call),
    Expr::call(conn, speed_call)});

  // Run the function once, so both values come from the same physics tick
  auto [altitude, speed] = krpc::run<std::tuple<double, double>>(expr);
  std::cout << "Altitude: " << altitude << " m, speed: " << speed << " m/s" << std::endl;
}

Use run for a function with effects, such as setting a property. An event or a function stream evaluates its function on every update, repeating the effects.

The server side functions tutorial shows how to build larger functions.

Note

krpc::add_stream(), krpc::run() and krpc::add_event() are defined in krpc/function_stream.hpp.

Streaming Data#

A common use case for kRPC is to continuously extract data from the game. The naive approach to do this would be to repeatedly call a remote procedure, such as in the following which repeatedly prints the position of the active vessel:

#include <iostream>
#include <iomanip>
#include <tuple>
#include <krpc.hpp>
#include <krpc/services/space_center.hpp>

int main() {
  auto conn = krpc::connect();
  krpc::services::SpaceCenter sc(&conn);
  auto vessel = sc.active_vessel().value();
  auto ref_frame = vessel.orbit().body().reference_frame();
  while (true) {
    auto pos = vessel.position(ref_frame);
    std::cout << std::fixed << std::setprecision(1);
    std::cout << std::get<0>(pos) << ", "
              << std::get<1>(pos) << ", "
              << std::get<2>(pos) << std::endl;
  }
}

This approach requires significant communication overhead as request/response messages are repeatedly sent between the client and server. kRPC provides a more efficient mechanism to achieve this, called streams.

A stream repeatedly executes a procedure on the server (with a fixed set of argument values) and sends the result to the client. It only requires a single message to be sent to the server to establish the stream, which will then continuously send data to the client until the stream is closed.

The following example does the same thing as above using streams:

#include <iostream>
#include <iomanip>
#include <tuple>
#include <krpc.hpp>
#include <krpc/services/space_center.hpp>

int main() {
  auto conn = krpc::connect();
  krpc::services::SpaceCenter sc(&conn);
  auto vessel = sc.active_vessel().value();
  auto ref_frame = vessel.orbit().body().reference_frame();
  auto pos_stream = vessel.position_stream(ref_frame);
  while (true) {
    auto pos = pos_stream();
    std::cout << std::fixed << std::setprecision(1);
    std::cout << std::get<0>(pos) << ", "
              << std::get<1>(pos) << ", "
              << std::get<2>(pos) << std::endl;
  }
}

It calls position_stream once at the start of the program to create the stream, and then repeatedly prints the position returned by the stream. The stream is automatically closed when the client disconnects.

A stream can be created for any function call (except property setters) by adding _stream to the end of the functions name. This returns a stream object of type template <typename T> krpc::Stream, where T is the return type of the original function. The most recent value of the stream can be obtained by calling krpc::Stream::operator()(). A stream can be stopped and removed from the server by calling krpc::Stream::remove() on the stream object. All of a clients streams are automatically stopped when it disconnects.

Each stream updates on its own, so two streams read one after the other can give values from different physics ticks. To read several values from one physics tick, make the calls while holding the tick, as described in Holding a Tick.

Note

A stream runs on the server until you remove it or the connection closes, even once every copy of the stream object is destroyed. Each call to a _stream function adds another stream.

Synchronizing with Stream Updates#

A common use case for kRPC is to wait until the value returned by a method or attribute changes, and then take some action. kRPC provides two mechanisms to do this efficiently: condition variables and callbacks.

Condition Variables#

Each stream has a condition variable associated with it, that is notified whenever the value of the stream changes. The condition variables are instances of krpc::Condition, used like std::condition_variable over the re-entrant mutex krpc::RecursiveMutex. A wait releases every level of the thread’s lock. These can be used to block the current thread of execution until the value of the stream changes.

The following example waits until the abort button is pressed in game, by waiting for the value of krpc::services::SpaceCenter::Control::abort() to change to true:

#include <iostream>
#include <krpc.hpp>
#include <krpc/services/space_center.hpp>

int main() {
  auto conn = krpc::connect();
  krpc::services::SpaceCenter sc(&conn);
  auto control = sc.active_vessel().value().control();
  auto abort = control.abort_stream();
  abort.acquire();
  while (!abort())
    abort.wait();
  abort.release();
}

This code creates a stream, acquires a lock on the streams condition variable (by calling acquire) and then repeatedly checks the value of abort. It leaves the loop when it changes to true.

The body of the loop calls wait on the stream, which causes the program to block until the value changes. This prevents the loop from ‘spinning’ and so it does not consume processing resources whilst waiting.

Callbacks#

Streams allow you to register callback functions that are called whenever the value of the stream changes. Callback functions should take a single argument, which is the new value of the stream, and should return nothing.

For example the following program registers two callbacks that are invoked when the value of krpc::services::SpaceCenter::Control::abort() changes:

#include <iostream>
#include <krpc.hpp>
#include <krpc/services/space_center.hpp>

void check_abort1(bool x) {
  std::cout << "Abort 1 called with a value of " << x << std::endl;
}

void check_abort2(bool x) {
  std::cout << "Abort 2 called with a value of " << x << std::endl;
}

int main() {
  auto conn = krpc::connect();
  krpc::services::SpaceCenter sc(&conn);
  auto control = sc.active_vessel().value().control();
  auto abort = control.abort_stream();

  abort.add_callback(check_abort1);
  abort.add_callback(check_abort2);

  // Keep the program running...
  while (true) {
  }
}

A callback added to a stream that already has a value is called with that value straight away.

Note

The callback function may be called from a different thread than the one that created the stream. Any changes to shared state must therefore be protected with appropriate synchronization.

Stream Endings#

The following example streams the temperature of a part until the part is destroyed:

#include <iostream>
#include <krpc.hpp>
#include <krpc/services/krpc.hpp>
#include <krpc/services/space_center.hpp>

int main() {
  auto conn = krpc::connect();
  krpc::services::KRPC krpc(&conn);
  krpc::services::SpaceCenter sc(&conn);
  auto vessel = sc.active_vessel().value();
  auto temperature = vessel.parts().root().temperature_stream();

  try {
    temperature.acquire();
    while (true) {
      temperature.wait();
      std::cout << "Temperature " << temperature() << std::endl;
    }
  } catch (const krpc::services::KRPC::ObjectDestroyedException&) {
    std::cout << "The part was destroyed" << std::endl;
  }
  temperature.release();
}

Once a stream ends, reading the stream or waiting on it throws the exception that ended it. A stream ends when its procedure throws an exception, when the server removes it, when you remove it, or when the connection closes.

A stream that the server removes, such as an event that has finished, ends with krpc::services::KRPC::StreamRemovedException. A stream you remove ends with krpc::StreamError, and a closed connection with krpc::ConnectionError.

An exception for an object that is not loaded, or a procedure not available in the game scene, holds the stream instead. It resumes once the object or scene is available.

See also

Object Lifetime

To handle an ending in a callback, add an end callback with krpc::Stream::add_end_callback(). It is called once, with the exception.

Streaming Server Side Functions#

Pass a server side function to krpc::add_stream() to stream its value. The server evaluates the function on each stream update, within one physics tick. The value can be any type the server can send, including collections and objects. For example, the following streams the vessel’s altitude in kilometers:

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

#include <krpc.hpp>
#include <krpc/function_stream.hpp>
#include <krpc/services/krpc.hpp>
#include <krpc/services/space_center.hpp>

int main() {
  auto conn = krpc::connect();
  krpc::services::SpaceCenter sc(&conn);
  auto flight = sc.active_vessel().value().flight();

  // Build a function that computes
  // the vessel's altitude in kilometers
  typedef krpc::services::KRPC::Expression Expr;
  auto expr = Expr::divide(conn,
    Expr::call(conn, flight.mean_altitude_call()),
    Expr::constant_double(conn, 1000));

  // Stream the value of the function
  auto stream = krpc::add_stream<double>(expr);
  while (true) {
    std::cout << "Altitude: " << stream() << " km" << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(1));
  }
}

The template type must describe the function’s value, or krpc::add_stream() throws std::invalid_argument. A nested position that can hold null, such as a list element, needs a std::optional. The value itself can be a std::optional or not, and reading a null without one throws std::runtime_error.

A function stream or event ends on any exception its function throws. This includes krpc::services::KRPC::ObjectNotLoadedException, which a game load or an unloaded vessel causes. To keep running through a load, the function catches that exception with Expr::try_catch.

Events#

Some procedures return event objects of type krpc::Event. These allow you to wait until an event occurs, by calling krpc::Event::wait(). Under the hood, these are implemented using streams and condition variables.

A call to wait returns straight away if the event has fired since the previous call on the same event object, so no firing is missed between two calls. Several firings between two calls make wait return once.

You can also create a custom event from a server side function. The following builds the function mean_altitude > 1000, and creates an event that triggers when the function returns true:

#include <iostream>
#include <krpc.hpp>
#include <krpc/function_stream.hpp>
#include <krpc/services/krpc.hpp>
#include <krpc/services/space_center.hpp>

int main() {
  auto conn = krpc::connect();
  krpc::services::SpaceCenter sc(&conn);
  auto flight = sc.active_vessel().value().flight();

  // Get the remote procedure call as a message object,
  // so it can be passed to the server
  auto mean_altitude = flight.mean_altitude_call();

  // Build the function on the server
  typedef krpc::services::KRPC::Expression Expr;
  auto expr = Expr::greater_than(conn,
    Expr::call(conn, mean_altitude),
    Expr::constant_double(conn, 1000));

  auto event = krpc::add_event(expr);
  event.acquire();
  event.wait();
  std::cout << "Altitude reached 1000m" << std::endl;
  event.release();
}

Client API Reference#

Client connect(const std::string &name = "", const std::string &address = "127.0.0.1", unsigned int rpc_port = 50000, unsigned int stream_port = 50001, std::chrono::milliseconds timeout = std::chrono::milliseconds::zero())#

This function creates a connection to a kRPC server. It returns a krpc::Client object, through which the server can be communicated with.

Parameters:
  • name (std::string) – A descriptive name for the connection. This is passed to the server and appears in the in-game server window.

  • address (std::string) – The address of the server to connect to. Can either be a hostname or an IP address in dotted decimal notation. Defaults to ‘127.0.0.1’.

  • rpc_port (unsigned int) – The port number of the RPC Server. Defaults to 50000. This should match the RPC port number of the server you want to connect to.

  • stream_port (unsigned int) – The port number of the Stream Server. Defaults to 50001. This should match the stream port number of the server you want to connect to.

  • timeout (std::chrono::milliseconds) – How long to wait for a connection before giving up. Defaults to zero, which waits indefinitely. A network that drops a connection attempt rather than refusing it otherwise leaves the client waiting.

Client connect_local(const std::string &name = "", const std::string &rpc_path = "", const std::string &stream_path = "")#

This function creates a connection to a kRPC server running on the same machine, over unix domain sockets rather than TCP/IP. It returns a krpc::Client object, just as krpc::connect() does, and the connection behaves identically thereafter.

Unix domain sockets are available on Linux, macOS, and Windows 10 1803 and Windows Server 2019 or later.

Parameters:
  • name (std::string) – A descriptive name for the connection. This is passed to the server and appears in the in-game server window.

  • rpc_path (std::string) – The path of the socket the RPC Server is listening on. This should match the RPC socket path shown in the in-game server window. Leave empty for the path the server uses unless it was configured with another.

  • stream_path (std::string) – The path of the socket the Stream Server is listening on. This should match the stream socket path shown in the in-game server window. Defaults as rpc_path does.

template<typename T>
Stream<T> add_stream(const services::KRPC::Expression &function)#

Create a stream from a server side function, evaluated on each update. Each call creates a new stream. Throws std::invalid_argument if the template type does not describe the function’s value, and StreamError if the client has no stream connection. Throws krpc::services::KRPC::ArgumentException if the function has parameters.

Reading a null value throws std::runtime_error unless the template type is a std::optional. In a callback, that error is written to stderr and the callback does not run.

template<typename T = void, typename ...Args>
T run(const services::KRPC::Expression &function, const Args&... args)#

Run a server side function within a single physics tick, and return its value, or run it for its effects when the template type is void. The arguments are passed to the function’s parameters, with std::nullopt or nullptr for a null.

A number converts to a double parameter, and an integer or a float to a float parameter, as C++ converts it implicitly, which can round. An integer converts to a signed parameter that holds every value of its type, and an integer that is not negative to an unsigned parameter at least as wide. A number a collection or a tuple holds converts the same way.

Throws std::invalid_argument if the template type does not describe the function’s value, the number of arguments differs from the number of parameters, or an argument does not match its parameter. Throws std::runtime_error for a null value unless the template type is a std::optional.

A class, enumeration or structure argument is checked by kind only. The server checks its class, and a null for a parameter that is not nullable, and throws krpc::services::KRPC::ArgumentException for a mismatch.

Event add_event(const services::KRPC::Expression &function)#

Create an event from a server side function that evaluates to a boolean value. Each call creates a new event. Throws StreamError if the client has no stream connection, and krpc::services::KRPC::ArgumentException if the function does not evaluate to a boolean value or has parameters.

template<typename T>
class Object#

The base class for remote objects.

template<typename T>
uint64_t get_object_id(const Object<T> &object)#

The identifier of a remote object on the server, e.g. to pass to krpc::services::KRPC::Expression::constant_object(). Throws std::invalid_argument for a null object, whose identifier is 0.

class Client#

This class provides the interface for communicating with the server. It is used by service class instances to invoke remote procedure calls. Instances of this class can be obtained by calling krpc::connect().

~Client()#

Destructs the client object and closes the connection to the server.

Condition &get_stream_update_condition() const#

A condition variable that is notified whenever a stream update message finishes processing.

std::unique_lock<RecursiveMutex> &get_stream_update_condition_lock() const#

A lock on the re-entrant mutex for the stream update condition variable. Every copy of the client shares the lock, so one thread at a time uses it.

void acquire_stream_update()#

Locks the mutex for the stream update condition variable.

void release_stream_update()#

Unlocks the mutex for the stream update condition variable.

void wait_for_stream_update(double timeout = -1)#

This method blocks until a stream update message finishes processing or the operation times out.

The stream update condition variable must be locked (by calling acquire_stream_update) before calling this method.

If timeout is specified and is greater than or equal to 0, it is the timeout in seconds for the operation.

int add_stream_update_callback(const std::function<void()> &callback)#

Adds a callback function that is invoked whenever a stream update message finishes processing. Returns a unique identifier for the callback which can be used to remove it.

Note

The callback function may be called from a different thread than the one that created the stream. Any changes to shared state must therefore be protected with appropriate synchronization.

void remove_stream_update_callback(int tag)#

Removes a stream update callback function. The tag is the identifier returned when the callback was added.

template<typename T>
class Stream#

This class represents a stream. See Streaming Data.

Streams are created by calling a remote procedure with _stream appended to its name.

Stream objects are copy constructible and assignable, and every copy refers to the same stream. Call remove() to remove the stream from the server.

float rate() const#
void set_rate(float rate)#

The update rate of the stream in Hertz. When set to zero, the rate is unlimited.

T operator()()#

Get the most recently received value from the stream, waiting for the first value if none has arrived yet. Throws the exception that ended the stream, if it has ended, such as an exception thrown by the remote procedure.

Condition &get_condition() const#

A condition variable that is notified whenever the value of the stream changes. Every copy of the stream object shares it.

std::unique_lock<RecursiveMutex> &get_condition_lock() const#

A lock on the re-entrant mutex for the condition variable. Each stream object has its own lock, used by one thread, so a thread waiting on a stream uses its own copy of the stream object.

void acquire()#

Locks the mutex for the condition variable. Every copy of the stream object shares the mutex, so a lock taken through one copy can be released through another.

void release()#

Unlocks the mutex for the condition variable.

bool wait(double timeout = -1)#

This method blocks until the value of the stream changes or the operation times out. Returns true if the value changed, and false on a timeout.

The method locks the condition variable itself, unless the thread holds it. To wait for a change from a value you have read, call acquire before reading it, so that no update lands between the read and the wait.

If timeout is specified and is greater than or equal to 0, it is the timeout in seconds for the operation. Throws the exception that ended the stream, if it ends before or during the wait.

int add_callback(const std::function<void(T)> &callback)#

Adds a callback function that is invoked whenever the value of the stream changes. The callback function should take one argument, which is passed the new value of the stream. If the stream already has a value, the callback is invoked with it straight away. An error from the stream does not invoke the callback. Calling the stream throws it. Returns a unique identifier for the callback which can be used to remove it.

Note

The callback function may be called from a different thread than the one that created the stream. Any changes to shared state must therefore be protected with appropriate synchronization.

void remove_callback(int tag)#

Removes a callback from the stream. The tag is the identifier returned when the callback was added.

int add_end_callback(const std::function<void(std::exception_ptr)> &callback)#

Adds a callback function that is invoked once when the stream ends. The callback function is passed the exception that ended the stream. It is invoked straight away if the stream has already ended. Returns a unique identifier for the callback which can be used to remove it.

void remove_end_callback(int tag)#

Removes an end callback from the stream. The tag is the identifier returned when the callback was added.

void remove()#

Removes the stream from the server. Every copy of the stream object refers to the same stream. Another stream added for the same call stays live.

bool operator==(const Stream<T> &rhs)#

Returns true if the two stream objects are bound to the same stream. Each call to a _stream function adds a new stream, so two streams added for the same call are not equal.

bool operator!=(const Stream<T> &rhs)#

Returns true if the two stream objects are bound to different streams.

operator bool()#

Returns whether the stream object is bound to a stream.

class Event#

This class represents an event. See Events. It is wrapper around a Stream<bool> that indicates when the event occurs.

Event objects are copy constructible and assignable, and every copy refers to the same event. Call remove() to remove the event from the server.

Condition &get_condition() const#

A condition variable that is notified whenever the event occurs. Every copy of the event object shares it.

std::unique_lock<RecursiveMutex> &get_condition_lock() const#

A lock on the re-entrant mutex for the condition variable. Each event object has its own lock, used by one thread, so a thread waiting on an event uses its own copy of the event object.

void acquire()#

Locks the mutex for the condition variable. Every copy of the event object, and its underlying stream, shares the mutex.

void release()#

Unlocks the mutex for the condition variable.

bool wait(double timeout = -1)#

This method blocks until the event occurs or the operation times out. It returns straight away if the event has occurred since the previous call on this event object. Returns true if the event occurred, and false on a timeout.

The method locks the condition variable itself, unless the thread holds it.

If timeout is specified and is greater than or equal to 0, it is the timeout in seconds for the operation. Throws the exception that ended the event, if it ends before or during the wait.

int add_callback(const std::function<void()> &callback)#

Adds a callback function that is invoked whenever the event occurs. The callback function should be a function that takes zero arguments. If the event has occurred since the previous call to wait on this event object, and no callback was invoked for it, the callback is invoked once straight away. A callback added after the event has ended is not invoked for an earlier firing. An error from the event does not invoke the callback. Waiting on the event throws it. Returns a unique identifier for the callback which can be used to remove the callback.

void remove_callback(int tag)#

Removes a callback from the event. The tag is the identifier returned when the callback was added.

int add_end_callback(const std::function<void(std::exception_ptr)> &callback)#

Adds a callback function that is invoked once when the event ends, with the exception that ended it. It is invoked straight away if the event has already ended. Returns a unique identifier for the callback which can be used to remove it.

void remove_end_callback(int tag)#

Removes an end callback from the event. The tag is the identifier returned when the callback was added.

void remove()#

Removes the event from the server.

Stream<bool> stream()#

Returns the underlying stream for the event.

bool operator==(const Event &rhs)#

Returns true if the two event objects are bound to the same underlying stream.

bool operator!=(const Event &rhs)#

Returns true if the two event objects are bound to different underlying streams.

operator bool()#

Returns whether the event object is bound to a stream.

class RecursiveMutex#

The mutex of a stream’s, an event’s or the stream update’s condition variable. The thread holding it can lock it again, and each lock is matched by an unlock. It provides lock, try_lock, try_lock_for, try_lock_until and unlock, so it can be held with std::unique_lock and std::lock_guard.

bool held_by_this_thread() const#

Whether the calling thread holds the mutex.

class Condition#

The condition variable of a stream, an event or the stream update. Its wait, wait_for and wait_until take a std::unique_lock<RecursiveMutex>, with or without a predicate, as std::condition_variable does. A wait releases every lock the calling thread holds on the mutex, and takes them again before it returns.

void wait()#
template<typename Rep, typename Period>
std::cv_status wait_for(const std::chrono::duration<Rep, Period> &duration)#
template<typename Clock, typename Duration>
std::cv_status wait_until(const std::chrono::time_point<Clock, Duration> &deadline)#

Waits as the overloads taking a lock do, for a thread that holds the mutex through acquire or a lock of its own.

void notify_one()#
void notify_all()#
template<typename T>
std::size_t hash_value(const T &value)#

Returns a hash of a value of any type the client carries: the arithmetic types, strings, enumerations, class objects, tuples, and the list, set and dictionary collection types, nested however deeply. A structure is also hashed by this function, and is given a std::hash of its own, so an unordered container can be keyed by one directly.

class hash#

A function object that calls hash_value(), to give a standard container that takes its hash as a template argument. The standard library hashes neither std::tuple nor any of the collection types, so a container keyed by one needs this:

std::unordered_set<std::tuple<double, double, double>, krpc::hash> points;