25#include <DebugGUI/icons_font_awesome.h>
27#include "DebugGUI/imgui.h"
40 ImGui::TextUnformatted(title);
42 ImGui::TextUnformatted(
"Name");
44 ImGui::TextUnformatted(
"Port");
47 ImGui::TextUnformatted(channel.name.c_str());
49 ImGui::Text(
"%d", channel.port);
58 static std::vector<char> statesActive(
states.statesViews.size(),
false);
59 if (statesActive.size() !=
states.statesViews.size()) {
60 statesActive.resize(
states.statesViews.size(),
false);
63 if (ImGui::CollapsingHeader(
"Remote state", ImGuiTreeNodeFlags_DefaultOpen)) {
64 for (
size_t i = 0;
i <
states.stateNames.size(); ++
i) {
65 if (
states.stateNames[
i].empty()) {
68 auto& view =
states.statesViews[
i];
72 ImGui::Checkbox(
states.stateNames[
i].c_str(), (
bool*)&statesActive[
i]);
73 if (view.size && statesActive[
i] != 0) {
74 ImGui::Begin(
states.stateNames[
i].c_str());
75 ImGui::Text(
"%d-%d\n %.*s", view.first, view.first + view.size, view.size,
states.statesBuffer.data() + view.first);
82template <
typename Routes>
87 if (ImGui::CollapsingHeader(
label, ImGuiTreeNodeFlags_DefaultOpen)) {
88 std::string_view inputs(
states.statesBuffer.data() + view.first, view.size);
89 auto beginInputs = inputs.begin();
90 auto endInputs = beginInputs + view.size;
91 char const* input = beginInputs;
94 while (input != endInputs) {
95 auto end = std::find(input, endInputs,
';');
96 if ((
end - input) == 0) {
100 if (ImGui::IsItemHovered()) {
101 ImGui::BeginTooltip();
112 boost::property_tree::ptree
const& currentProvenance)
114 if (currentConfig.empty()) {
117 if (ImGui::CollapsingHeader(
"Current Config", ImGuiTreeNodeFlags_DefaultOpen)) {
119 auto labels = {
"Name",
"Value"};
120 for (
auto&
label : labels) {
121 ImGui::TextUnformatted(
label);
124 for (
auto& option : currentConfig) {
125 ImGui::TextUnformatted(option.first.c_str());
126 if (ImGui::IsItemHovered()) {
127 ImGui::BeginTooltip();
128 ImGui::TextUnformatted(option.first.c_str());
132 ImGui::Text(
"%s (%s)", option.second.data().c_str(), currentProvenance.get<std::string>(option.first).c_str());
133 if (ImGui::IsItemHovered()) {
134 ImGui::BeginTooltip();
135 ImGui::Text(
"%s (%s)", option.second.data().c_str(), currentProvenance.get<std::string>(option.first).c_str());
146 if (options.empty()) {
149 if (ImGui::CollapsingHeader(
label, ImGuiTreeNodeFlags_DefaultOpen)) {
151 auto labels = {
"Name",
"Value"};
152 for (
auto&
label : labels) {
153 ImGui::TextUnformatted(
label);
156 for (
auto& option : options) {
157 ImGui::TextUnformatted(option.name.c_str());
159 auto currentValueIt = control.
options.find(option.name);
162 if (currentValueIt == control.
options.end()) {
163 switch (option.type) {
165 ImGui::Text(R
"("%s" (default))", option.defaultValue.get<const char*>());
168 ImGui::Text(
"%d (default)", option.defaultValue.get<
int>());
171 ImGui::Text(
"%d (default)", option.defaultValue.get<int8_t>());
174 ImGui::Text(
"%d (default)", option.defaultValue.get<int16_t>());
177 ImGui::Text(
"%" PRId64
" (default)", option.defaultValue.get<int64_t>());
180 ImGui::Text(
"%d (default)", option.defaultValue.get<uint8_t>());
183 ImGui::Text(
"%d (default)", option.defaultValue.get<uint16_t>());
186 ImGui::Text(
"%d (default)", option.defaultValue.get<uint32_t>());
189 ImGui::Text(
"%" PRIu64
" (default)", option.defaultValue.get<uint64_t>());
192 ImGui::Text(
"%f (default)", option.defaultValue.get<
float>());
195 ImGui::Text(
"%f (default)", option.defaultValue.get<
double>());
198 ImGui::TextUnformatted(
"");
201 ImGui::TextUnformatted(
"unknown");
204 ImGui::TextUnformatted(currentValueIt->second.c_str());
215 if (services.empty()) {
218 if (ImGui::CollapsingHeader(
label, ImGuiTreeNodeFlags_DefaultOpen)) {
220 auto labels = {
"Service",
"Kind"};
221 for (
auto&
label : labels) {
222 ImGui::TextUnformatted(
label);
225 for (
auto& service : services) {
226 if (!service.name.empty()) {
227 ImGui::TextUnformatted(service.name.c_str());
229 ImGui::TextUnformatted(
"unknown");
232 switch (service.kind) {
234 ImGui::TextUnformatted(
"Serial");
237 ImGui::TextUnformatted(
"Global");
240 ImGui::TextUnformatted(
"Stream");
243 ImGui::TextUnformatted(
"unknown");
259 ImGui::Text(
"Name: %s", spec.
name.c_str());
260 ImGui::Text(
"Executable: %s", metadata.
executable.c_str());
262 ImGui::Text(
"Pid: %d", info.
pid);
264 ImGui::Text(
"Pid: %d (exit status: %d)", info.
pid, info.
exitStatus);
266 ImGui::Text(
"Device state: %s", info.
deviceState.data());
269 if (ImGui::Button(ICON_FA_BUG
"Attach debugger")) {
271 setenv(
"O2DEBUGGEDPID",
pid.c_str(), 1);
273 std::string defaultAppleDebugCommand =
274 "osascript -e 'tell application \"Terminal\" to activate'"
275 " -e 'tell application \"Terminal\" to do script \"lldb -p \" & (system attribute \"O2DEBUGGEDPID\") & \"; exit\"'";
276 setenv(
"O2DPLDEBUG", defaultAppleDebugCommand.c_str(), 0);
278 setenv(
"O2DPLDEBUG",
"xterm -hold -e gdb attach $O2DEBUGGEDPID &", 0);
280 int retVal = system(getenv(
"O2DPLDEBUG"));
285 if (ImGui::Button(
"Profile 30s")) {
287 setenv(
"O2PROFILEDPID",
pid.c_str(), 1);
289 auto defaultAppleProfileCommand = fmt::format(
290 "osascript -e 'tell application \"Terminal\"'"
292 " -e 'do script \"xcrun xctrace record --output dpl-profile-{0}.trace"
293 " --instrument os_signpost --time-limit 30s --template Time\\\\ Profiler --attach {0} "
294 " && open dpl-profile-{0}.trace && exit\"'"
298 setenv(
"O2DPLPROFILE", defaultAppleProfileCommand.c_str(), 0);
300 setenv(
"O2DPLPROFILE",
"xterm -hold -e perf record -a -g -p $O2PROFILEDPID > perf-$O2PROFILEDPID.data &", 0);
302 LOG(error) << getenv(
"O2DPLPROFILE");
303 int retVal = system(getenv(
"O2DPLPROFILE"));
308 if (ImGui::Button(
"Profile Allocations 30s")) {
310 setenv(
"O2PROFILEDPID",
pid.c_str(), 1);
311 auto defaultAppleProfileCommand = fmt::format(
312 "osascript -e 'tell application \"Terminal\"'"
314 " -e 'do script \"xcrun xctrace record --output dpl-profile-{0}.trace"
315 " --time-limit 30s --instrument os_signpost --template Allocations --attach {0} "
316 " && open dpl-profile-{0}.trace && exit\"'"
320 setenv(
"O2DPLPROFILE", defaultAppleProfileCommand.c_str(), 0);
321 LOG(error) << getenv(
"O2DPLPROFILE");
322 int retVal = system(getenv(
"O2DPLPROFILE"));
328 if (ImGui::Button(
"Offer SHM")) {
329 control.
controller->
write(
"/shm-offer 1000", strlen(
"/shm-offer 1000"));
333 ImGui::Text(ICON_FA_CLOCK_O);
335 if (ImGui::Button(
"Restart")) {
347 if (ImGui::CollapsingHeader(
"Labels", ImGuiTreeNodeFlags_DefaultOpen)) {
349 ImGui::Text(
"%s",
label.value.c_str());
353 if (ImGui::CollapsingHeader(
"Command line arguments", ImGuiTreeNodeFlags_DefaultOpen)) {
354 static ImGuiTextFilter
filter;
355 filter.Draw(ICON_FA_SEARCH);
357 if (
filter.PassFilter(arg.c_str())) {
358 ImGui::TextUnformatted(arg.c_str());
363 if (ImGui::CollapsingHeader(
"Channels", ImGuiTreeNodeFlags_DefaultOpen)) {
368 if (ImGui::CollapsingHeader(
"Policies")) {
374 if (ImGui::CollapsingHeader(
"Signals", ImGuiTreeNodeFlags_DefaultOpen)) {
375 if (ImGui::Button(
"SIGSTOP")) {
376 kill(info.
pid, SIGSTOP);
379 if (ImGui::Button(
"SIGTERM")) {
380 kill(info.
pid, SIGTERM);
383 if (ImGui::Button(
"SIGKILL")) {
384 kill(info.
pid, SIGKILL);
386 if (ImGui::Button(
"SIGCONT")) {
387 kill(info.
pid, SIGCONT);
390 if (ImGui::Button(
"SIGUSR1")) {
391 kill(info.
pid, SIGUSR1);
394 if (ImGui::Button(
"SIGUSR2")) {
395 kill(info.
pid, SIGUSR2);
399 bool logsChanged =
false;
400 if (ImGui::CollapsingHeader(
"Signposts", ImGuiTreeNodeFlags_DefaultOpen)) {
407 std::string cmd = fmt::format(
"/log-streams {}", control.
logStreams);
412 bool flagsChanged =
false;
413 if (ImGui::CollapsingHeader(
"Event loop tracing", ImGuiTreeNodeFlags_DefaultOpen)) {
434 std::string cmd = fmt::format(
"/trace {}", control.
tracingFlags);
std::vector< OutputRoute > routes
GLsizei GLenum const void GLuint GLsizei GLfloat * metrics
GLuint GLsizei const GLchar * label
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
State for the main GUI window.
void servicesTable(const char *label, std::vector< ServiceSpec > const &services)
void deviceStateTable(DataProcessingStates const &states)
void deviceInfoTable(char const *label, ProcessingStateId id, DataProcessingStates const &states, Routes const &routes, DeviceMetricsInfo const &metrics)
void configurationTable(boost::property_tree::ptree const ¤tConfig, boost::property_tree::ptree const ¤tProvenance)
void displayDeviceInspector(DeviceSpec const &spec, DeviceInfo const &info, DataProcessingStates const &states, DeviceMetricsInfo const &metrics, DataProcessorInfo const &metadata, DeviceControl &control)
Helper to display information about a device.
void optionsTable(const char *label, std::vector< ConfigParamSpec > const &options, const DeviceControl &control)
ProcessingStateId
Helper struct to define some known states.
std::string to_string(gsl::span< T, Size > span)
std::string name
Name of the policy itself.
std::vector< ConfigParamSpec > workflowOptions
The workflow options which are available for the associated DataProcessorSpec.
std::vector< std::string > cmdLineArgs
The argument passed on the command line for this DataProcessorSpec.
std::string executable
The executable name of the program which holds the DataProcessorSpec.
int logStreams
What kind of log streams should be enabled.
DeviceController * controller
Handler used to communicate with the device (if available)
std::map< std::string, std::string > options
Where the GUI should store the options it wants.
int requestedState
An incremental number to identify the device state.
int tracingFlags
What kind of events should run with the TRACE level.
void write(const char *message, size_t s)
bool active
Whether the device is active (running) or not.
boost::property_tree::ptree currentConfig
Current configuration for the device.
pid_t pid
The pid of the device associated to this device.
boost::property_tree::ptree currentProvenance
Current provenance for the configuration keys.
int providedState
An incremental number for the state of the device.
std::vector< DataProcessorLabel > labels
std::vector< InputRoute > inputs
size_t maxInputTimeslices
The maximum number of time pipelining for this device.
CompletionPolicy completionPolicy
The completion policy to use for this device.
std::vector< OutputChannelSpec > outputChannels
std::string name
The name of the associated DataProcessorSpec.
size_t inputTimesliceId
The time pipelining id of this particular device.
std::vector< OutputRoute > outputs
DispatchPolicy dispatchPolicy
SendingPolicy sendingPolicy
std::vector< InputChannelSpec > inputChannels
std::vector< ServiceSpec > services
@ DATA_PROCESSOR_CONTEXT_LOG
std::string name
Name of the policy itself.
static const char * getLifeTimeStr(Lifetime lifetime)
static void channelsTable(const char *title, const C &channels)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< ChannelData > channels