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);
86 if (ImGui::CollapsingHeader(
label, ImGuiTreeNodeFlags_DefaultOpen)) {
87 std::string_view inputs(
states.statesBuffer.data() + view.first, view.size);
88 auto beginInputs = inputs.begin();
89 auto endInputs = beginInputs + view.size;
90 char const* input = beginInputs;
93 while (input != endInputs) {
94 auto end = std::find(input, endInputs,
';');
95 if ((
end - input) == 0) {
99 if (std::get_if<std::vector<InputRoute>>(&
routes)) {
100 return std::get<std::vector<InputRoute>>(
routes)[
i].matcher.lifetime;
102 return std::get<std::vector<OutputRoute>>(
routes)[
i].matcher.lifetime;
106 if (ImGui::IsItemHovered()) {
107 ImGui::BeginTooltip();
118 boost::property_tree::ptree
const& currentProvenance)
120 if (currentConfig.empty()) {
123 if (ImGui::CollapsingHeader(
"Current Config", ImGuiTreeNodeFlags_DefaultOpen)) {
125 auto labels = {
"Name",
"Value"};
126 for (
auto&
label : labels) {
127 ImGui::TextUnformatted(
label);
130 for (
auto& option : currentConfig) {
131 ImGui::TextUnformatted(option.first.c_str());
132 if (ImGui::IsItemHovered()) {
133 ImGui::BeginTooltip();
134 ImGui::TextUnformatted(option.first.c_str());
138 ImGui::Text(
"%s (%s)", option.second.data().c_str(), currentProvenance.get<std::string>(option.first).c_str());
139 if (ImGui::IsItemHovered()) {
140 ImGui::BeginTooltip();
141 ImGui::Text(
"%s (%s)", option.second.data().c_str(), currentProvenance.get<std::string>(option.first).c_str());
152 if (options.empty()) {
155 if (ImGui::CollapsingHeader(
label, ImGuiTreeNodeFlags_DefaultOpen)) {
157 auto labels = {
"Name",
"Value"};
158 for (
auto&
label : labels) {
159 ImGui::TextUnformatted(
label);
162 for (
auto& option : options) {
163 ImGui::TextUnformatted(option.name.c_str());
165 auto currentValueIt = control.
options.find(option.name);
168 if (currentValueIt == control.
options.end()) {
169 switch (option.type) {
171 ImGui::Text(R
"("%s" (default))", option.defaultValue.get<const char*>());
174 ImGui::Text(
"%d (default)", option.defaultValue.get<
int>());
177 ImGui::Text(
"%d (default)", option.defaultValue.get<int8_t>());
180 ImGui::Text(
"%d (default)", option.defaultValue.get<int16_t>());
183 ImGui::Text(
"%" PRId64
" (default)", option.defaultValue.get<int64_t>());
186 ImGui::Text(
"%d (default)", option.defaultValue.get<uint8_t>());
189 ImGui::Text(
"%d (default)", option.defaultValue.get<uint16_t>());
192 ImGui::Text(
"%d (default)", option.defaultValue.get<uint32_t>());
195 ImGui::Text(
"%" PRIu64
" (default)", option.defaultValue.get<uint64_t>());
198 ImGui::Text(
"%f (default)", option.defaultValue.get<
float>());
201 ImGui::Text(
"%f (default)", option.defaultValue.get<
double>());
204 ImGui::TextUnformatted(
"");
207 ImGui::TextUnformatted(
"unknown");
210 ImGui::TextUnformatted(currentValueIt->second.c_str());
221 if (services.empty()) {
224 if (ImGui::CollapsingHeader(
label, ImGuiTreeNodeFlags_DefaultOpen)) {
226 auto labels = {
"Service",
"Kind"};
227 for (
auto&
label : labels) {
228 ImGui::TextUnformatted(
label);
231 for (
auto& service : services) {
232 if (!service.name.empty()) {
233 ImGui::TextUnformatted(service.name.c_str());
235 ImGui::TextUnformatted(
"unknown");
238 switch (service.kind) {
240 ImGui::TextUnformatted(
"Serial");
243 ImGui::TextUnformatted(
"Global");
246 ImGui::TextUnformatted(
"Stream");
249 ImGui::TextUnformatted(
"unknown");
265 ImGui::Text(
"Name: %s", spec.
name.c_str());
266 ImGui::Text(
"Executable: %s", metadata.
executable.c_str());
268 ImGui::Text(
"Pid: %d", info.
pid);
270 ImGui::Text(
"Pid: %d (exit status: %d)", info.
pid, info.
exitStatus);
272 ImGui::Text(
"Device state: %s", info.
deviceState.data());
275 if (ImGui::Button(ICON_FA_BUG
"Attach debugger")) {
277 setenv(
"O2DEBUGGEDPID",
pid.c_str(), 1);
279 std::string defaultAppleDebugCommand =
280 "osascript -e 'tell application \"Terminal\" to activate'"
281 " -e 'tell application \"Terminal\" to do script \"lldb -p \" & (system attribute \"O2DEBUGGEDPID\") & \"; exit\"'";
282 setenv(
"O2DPLDEBUG", defaultAppleDebugCommand.c_str(), 0);
284 setenv(
"O2DPLDEBUG",
"xterm -hold -e gdb attach $O2DEBUGGEDPID &", 0);
286 int retVal = system(getenv(
"O2DPLDEBUG"));
291 if (ImGui::Button(
"Profile 30s")) {
293 setenv(
"O2PROFILEDPID",
pid.c_str(), 1);
295 auto defaultAppleProfileCommand = fmt::format(
296 "osascript -e 'tell application \"Terminal\"'"
298 " -e 'do script \"xcrun xctrace record --output dpl-profile-{0}.trace"
299 " --instrument os_signpost --time-limit 30s --template Time\\\\ Profiler --attach {0} "
300 " && open dpl-profile-{0}.trace && exit\"'"
304 setenv(
"O2DPLPROFILE", defaultAppleProfileCommand.c_str(), 0);
306 setenv(
"O2DPLPROFILE",
"xterm -hold -e perf record -a -g -p $O2PROFILEDPID > perf-$O2PROFILEDPID.data &", 0);
308 LOG(error) << getenv(
"O2DPLPROFILE");
309 int retVal = system(getenv(
"O2DPLPROFILE"));
314 if (ImGui::Button(
"Profile Allocations 30s")) {
316 setenv(
"O2PROFILEDPID",
pid.c_str(), 1);
317 auto defaultAppleProfileCommand = fmt::format(
318 "osascript -e 'tell application \"Terminal\"'"
320 " -e 'do script \"xcrun xctrace record --output dpl-profile-{0}.trace"
321 " --time-limit 30s --instrument os_signpost --template Allocations --attach {0} "
322 " && open dpl-profile-{0}.trace && exit\"'"
326 setenv(
"O2DPLPROFILE", defaultAppleProfileCommand.c_str(), 0);
327 LOG(error) << getenv(
"O2DPLPROFILE");
328 int retVal = system(getenv(
"O2DPLPROFILE"));
334 if (ImGui::Button(
"Offer SHM")) {
335 control.
controller->
write(
"/shm-offer 1000", strlen(
"/shm-offer 1000"));
339 ImGui::Text(ICON_FA_CLOCK_O);
341 if (ImGui::Button(
"Restart")) {
353 if (ImGui::CollapsingHeader(
"Labels", ImGuiTreeNodeFlags_DefaultOpen)) {
355 ImGui::Text(
"%s",
label.value.c_str());
359 if (ImGui::CollapsingHeader(
"Command line arguments", ImGuiTreeNodeFlags_DefaultOpen)) {
360 static ImGuiTextFilter
filter;
361 filter.Draw(ICON_FA_SEARCH);
363 if (
filter.PassFilter(arg.c_str())) {
364 ImGui::TextUnformatted(arg.c_str());
369 if (ImGui::CollapsingHeader(
"Channels", ImGuiTreeNodeFlags_DefaultOpen)) {
374 if (ImGui::CollapsingHeader(
"Policies")) {
380 if (ImGui::CollapsingHeader(
"Signals", ImGuiTreeNodeFlags_DefaultOpen)) {
381 if (ImGui::Button(
"SIGSTOP")) {
382 kill(info.
pid, SIGSTOP);
385 if (ImGui::Button(
"SIGTERM")) {
386 kill(info.
pid, SIGTERM);
389 if (ImGui::Button(
"SIGKILL")) {
390 kill(info.
pid, SIGKILL);
392 if (ImGui::Button(
"SIGCONT")) {
393 kill(info.
pid, SIGCONT);
396 if (ImGui::Button(
"SIGUSR1")) {
397 kill(info.
pid, SIGUSR1);
400 if (ImGui::Button(
"SIGUSR2")) {
401 kill(info.
pid, SIGUSR2);
405 bool logsChanged =
false;
406 if (ImGui::CollapsingHeader(
"Signposts", ImGuiTreeNodeFlags_DefaultOpen)) {
413 std::string cmd = fmt::format(
"/log-streams {}", control.
logStreams);
418 bool flagsChanged =
false;
419 if (ImGui::CollapsingHeader(
"Event loop tracing", ImGuiTreeNodeFlags_DefaultOpen)) {
440 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 configurationTable(boost::property_tree::ptree const ¤tConfig, boost::property_tree::ptree const ¤tProvenance)
void deviceInfoTable(char const *label, ProcessingStateId id, DataProcessingStates const &states, std::variant< std::vector< InputRoute >, std::vector< OutputRoute > > routes, DeviceMetricsInfo const &metrics)
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)
Lifetime
Possible Lifetime of objects being exchanged by the DPL.
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 std::string getLifeTimeStr(Lifetime lifetime)
static void channelsTable(const char *title, const C &channels)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< ChannelData > channels