@@ -86,6 +86,27 @@ struct GPUDisplayFrontend::configRTTIInfo {
8686 std::apply ([&](auto ... s) { ((retVal = i++ == index ? reinterpret_cast <char *>(&(display.*s)) : retVal), ...); }, configStructs);
8787 return retVal;
8888 }
89+ std::optional<std::string> valueString (GPUDisplay& display, uint32_t index) const // Current value of an option, printed with print_type as in qconfig.cxx, nullopt for unsupported types
90+ {
91+ const auto & e = rttiEntries[index];
92+ const char * ptr = configStructPtr (display, e.configStructIndex ) + e.offset ;
93+ if (e.isVector || e.arraySize ) {
94+ return std::nullopt ;
95+ } else if (e.type == " bool" ) {
96+ return qConfig::print_type (*(const bool *)ptr);
97+ } else if (e.type == " float" ) {
98+ return qConfig::print_type (*(const float *)ptr);
99+ } else if (e.type == " int8_t" ) {
100+ return qConfig::print_type (*(const int8_t *)ptr);
101+ } else if (e.type == " uint8_t" ) {
102+ return qConfig::print_type (*(const uint8_t *)ptr);
103+ } else if (e.type == " int32_t" || e.type == " int" ) {
104+ return qConfig::print_type (*(const int32_t *)ptr);
105+ } else if (e.type == " uint32_t" ) {
106+ return qConfig::print_type (*(const uint32_t *)ptr);
107+ }
108+ return std::nullopt ;
109+ }
89110 template <class T , class M >
90111 uint32_t getRTTIIndex (GPUDisplay& display, M T::* member) // RTTI index of a direct member of a config struct
91112 {
@@ -306,41 +327,24 @@ void GPUDisplay::buildConfig()
306327 buildConfigKeys ();
307328
308329 rtti->configInfos .resize (rtti->rttiEntries .size ());
309- auto messageInfo = [this ]<typename T>(const std::string& message, const T* value) { // Info from the qConfig message, value printed with print_type as in qconfig.cxx
310- return configKeyCallback ([this , message, value]() {
311- char buffer[256 ];
312- const int32_t n = snprintf (buffer, sizeof (buffer), message.c_str (), qConfig::print_type (*value).c_str ());
313- if (n < 0 || n >= (int32_t )sizeof (buffer)) {
314- GPUError (" Info message too long: %s" , message.c_str ());
315- return ;
316- }
317- SetInfo (" %s" , buffer);
318- });
319- };
320- for (uint32_t i = 0 ; i < rtti->rttiEntries .size (); i++) {
330+ for (uint32_t i = 0 ; i < rtti->rttiEntries .size (); i++) { // Info from the qConfig message, with the value as %s as in qconfig.cxx
321331 const auto & e = rtti->rttiEntries [i];
322- if (e.message .empty () || e. isVector || e. arraySize ) {
332+ if (e.message .empty ()) {
323333 continue ;
324334 }
325- const char * ptr = GPUDisplayFrontend::configRTTIInfo::configStructPtr (*this , e.configStructIndex ) + e.offset ;
326- configKeyCallback info;
327- if (e.type == " bool" ) {
328- info = messageInfo (e.message , (const bool *)ptr);
329- } else if (e.type == " float" ) {
330- info = messageInfo (e.message , (const float *)ptr);
331- } else if (e.type == " int8_t" ) {
332- info = messageInfo (e.message , (const int8_t *)ptr);
333- } else if (e.type == " uint8_t" ) {
334- info = messageInfo (e.message , (const uint8_t *)ptr);
335- } else if (e.type == " int32_t" || e.type == " int" ) {
336- info = messageInfo (e.message , (const int32_t *)ptr);
337- } else if (e.type == " uint32_t" ) {
338- info = messageInfo (e.message , (const uint32_t *)ptr);
339- } else {
335+ if (!rtti->valueString (*this , i)) {
340336 GPUError (" No info message support for type %s of %s" , e.type .c_str (), e.name .c_str ());
341337 continue ;
342338 }
343- rtti->configInfos [i] = std::move (info);
339+ rtti->configInfos [i] = [this , i, message = e.message ]() {
340+ char buffer[256 ];
341+ const int32_t n = snprintf (buffer, sizeof (buffer), message.c_str (), mFrontend ->mConfigRTTI ->valueString (*this , i)->c_str ());
342+ if (n < 0 || n >= (int32_t )sizeof (buffer)) {
343+ GPUError (" Info message too long: %s" , message.c_str ());
344+ return ;
345+ }
346+ SetInfo (" %s" , buffer);
347+ };
344348 }
345349 buildConfigInfo ();
346350 rtti->buildHelpText ();
@@ -353,14 +357,24 @@ bool GPUDisplayFrontend::processKeyLambda(uint32_t key)
353357 }
354358 if (key < mConfigRTTI ->configKeys .size () && mConfigRTTI ->configKeys [key].callback ) {
355359 mConfigRTTI ->configKeys [key].callback ();
356- if (const uint32_t index = mConfigRTTI ->configKeys [key].configRTTIIndex ; index < mConfigRTTI ->configInfos .size () && mConfigRTTI -> configInfos [index] ) {
357- mConfigRTTI -> configInfos [index]( );
360+ if (const uint32_t index = mConfigRTTI ->configKeys [key].configRTTIIndex ; index < mConfigRTTI ->configInfos .size ()) {
361+ showConfigInfo (index );
358362 }
359363 return true ;
360364 }
361365 return false ;
362366}
363367
368+ void GPUDisplayFrontend::showConfigInfo (uint32_t index)
369+ {
370+ if (mConfigRTTI ->configInfos [index]) {
371+ mConfigRTTI ->configInfos [index]();
372+ } else if (const auto value = mConfigRTTI ->valueString (*mDisplay , index)) { // Generic info for options without info callback
373+ const auto & e = mConfigRTTI ->rttiEntries [index];
374+ mDisplay ->SetInfo (" %s.%s changed to %s" , mConfigRTTI ->configStructNames [e.configStructIndex ].c_str (), e.name .c_str (), value->c_str ());
375+ }
376+ }
377+
364378void GPUDisplay::HandleKey (uint8_t key)
365379{
366380 if (key == mFrontend ->KEY_ALT ) {
0 commit comments