diff --git a/src/emu/device.cpp b/src/emu/device.cpp index 8d4ec1b8d62..b2a2e3e325d 100644 --- a/src/emu/device.cpp +++ b/src/emu/device.cpp @@ -360,6 +360,10 @@ bool device_t::findit(bool isvalidation) const void device_t::start() { + // prepare the logerror buffer + if (m_machine->allow_logging()) + m_string_buffer.reserve(1024); + // find all the registered devices if (!findit(false)) throw emu_fatalerror("Missing some required objects, unable to proceed"); @@ -380,7 +384,7 @@ void device_t::start() device_sound_interface *sound; if (state_registrations == 0 && (interface(exec) || interface(sound)) && type() != SPEAKER) { - logerror("Device '%s' did not register any state to save!\n", tag()); + logerror("Device did not register any state to save!\n"); if ((machine().system().flags & MACHINE_SUPPORTS_SAVE) != 0) fatalerror("Device '%s' did not register any state to save!\n", tag()); } diff --git a/src/emu/device.h b/src/emu/device.h index 114e8e28b16..40d998bdf8e 100644 --- a/src/emu/device.h +++ b/src/emu/device.h @@ -361,6 +361,9 @@ private: bool m_config_complete; // have we completed our configuration? bool m_started; // true if the start function has succeeded finder_base * m_auto_finder_list; // list of objects to auto-find + + // string formatting buffer for logerror + mutable util::ovectorstream m_string_buffer; }; diff --git a/src/emu/device.ipp b/src/emu/device.ipp index 1501798f586..74d7eb45f2c 100644 --- a/src/emu/device.ipp +++ b/src/emu/device.ipp @@ -17,8 +17,6 @@ #ifndef __DEVICE_IPP__ #define __DEVICE_IPP__ -#include "strformat.h" - //************************************************************************** // MEMBER TEMPLATES //************************************************************************** @@ -26,15 +24,28 @@ template inline void device_t::popmessage(Format &&fmt, Params &&... args) const { - if (m_machine) + if (m_machine != nullptr) m_machine->popmessage(std::forward(fmt), std::forward(args)...); } template inline void device_t::logerror(Format &&fmt, Params &&... args) const { - if (m_machine) - m_machine->logerror(string_format("[%s] %s", tag(), std::forward(fmt)), std::forward(args)...); + if (m_machine != nullptr && m_machine->allow_logging()) + { + g_profiler.start(PROFILER_LOGERROR); + + // dump to the buffer + m_string_buffer.clear(); + m_string_buffer.seekp(0); + util::stream_format(m_string_buffer, "[%s] ", tag()); + util::stream_format(m_string_buffer, std::forward(fmt), std::forward(args)...); + m_string_buffer.put('\0'); + + m_machine->strlog(&m_string_buffer.vec()[0]); + + g_profiler.stop(); + } } #endif // __DEVICE_IPP__ diff --git a/src/emu/emu.h b/src/emu/emu.h index 7a506da1fe9..120615187db 100644 --- a/src/emu/emu.h +++ b/src/emu/emu.h @@ -29,9 +29,11 @@ #include "eminline.h" #include "profiler.h" -// commonly-referenecd utilities imported from lib/util +// commonly-referenced utilities imported from lib/util #include "palette.h" #include "unicode.h" +#include "strformat.h" +#include "vecstream.h" // emulator-specific utilities #include "attotime.h" diff --git a/src/emu/machine.cpp b/src/emu/machine.cpp index 4759432ff00..778403ef8a4 100644 --- a/src/emu/machine.cpp +++ b/src/emu/machine.cpp @@ -727,6 +727,19 @@ void running_machine::add_logerror_callback(logerror_callback callback) } +//------------------------------------------------- +// strlog - send an error logging string to the +// debugger and any OSD-defined output streams +//------------------------------------------------- + +void running_machine::strlog(const char *str) const +{ + // log to all callbacks + for (auto &cb : m_logerror_list) + cb->m_func(str); +} + + //------------------------------------------------- // debug_break - breaks into the debugger, if // enabled diff --git a/src/emu/machine.h b/src/emu/machine.h index 55af0512525..57665e7ffca 100644 --- a/src/emu/machine.h +++ b/src/emu/machine.h @@ -19,9 +19,6 @@ #include -#include "strformat.h" -#include "vecstream.h" - #include // forward declaration instead of osdepend.h @@ -198,6 +195,7 @@ public: emu_options &options() const { return m_config.options(); } attotime time() const { return m_scheduler.time(); } bool scheduled_event_pending() const { return m_exit_pending || m_hard_reset_pending; } + bool allow_logging() const { return !m_logerror_list.empty(); } // fetch items by name inline device_t *device(const char *tag) const { return root_device().subdevice(tag); } @@ -233,6 +231,7 @@ public: void popmessage() const { popmessage(static_cast(nullptr)); } template void popmessage(Format &&fmt, Params &&... args) const; template void logerror(Format &&fmt, Params &&... args) const; + void strlog(const char *str) const; UINT32 rand(); const char *describe_context(); @@ -387,7 +386,7 @@ template inline void running_machine::logerror(Format &&fmt, Params &&... args) const { // process only if there is a target - if (!m_logerror_list.empty()) + if (allow_logging()) { g_profiler.start(PROFILER_LOGERROR); @@ -397,10 +396,7 @@ inline void running_machine::logerror(Format &&fmt, Params &&... args) const util::stream_format(m_string_buffer, std::forward(fmt), std::forward(args)...); m_string_buffer.put('\0'); - // log to all callbacks - char const *const str(&m_string_buffer.vec()[0]); - for (auto &cb : m_logerror_list) - cb->m_func(str); + strlog(&m_string_buffer.vec()[0]); g_profiler.stop(); }