#pragma once ////////////////////////////////////////////////////////////// // // Namespace DebugPrint // // This namespace contains the function "DPrint", // which is short for debugging print. This // is what you should use if you want to print // a debugging message. // // Messages printed using "DPrint" will // be routed to several destinations. These // might include a logfile, the unreal console, // and the visual studio debugging log. // // In order for "DPrint" to work, you have to // configure them once, at program initialization // time. This is done using the functions in // namespace DebugPrintConfig, below. // // We promise that namespace DebugPrint will // only ever contain one function, 'DPrint.' // that way, it's safe for you to put // 'using namespace DebugPrint' in your code. // // All DPrint-related functionality is // thread-safe. A single 'DPrint' is meant to // be output atomically. // // It is fine for the content of the DPrint // string to contain newlines. // ////////////////////////////////////////////////////////////// namespace DebugPrint { // Print text into the debug log. void DPrint(const FString& fs); // Print text into the debug log. void DPrint(const char* msg); // Print text into the debug log. void DPrint(const char* msg, size_t len); }; ////////////////////////////////////////////////////////////// // // namespace DebugPrintControl // // This namespace contains the functions // necessary to initialize "DPrint", and // route its output to several destinations. // // "DPrint" is a callback-based design. // Initialization might consist of: register a // callback that sends a string to a logfile, // register another callback that sends a string // to visual studio's debug console, and register // a third one that sends a string to the // unreal console. Each time somebody calls // 'DPrint', all three callbacks will get invoked. // // There is also a 'collect' option where you // can ask "DPrint" to save the messages in a // buffer, which you can then collect at // your leisure. You can use buffering and // callbacks at the same time. Note that // buffering is inherently less than ideal for // messages that warn of imminent program aborts. // So it is recommended that you use at least one // callback that sends its output without delay. // ////////////////////////////////////////////////////////////// namespace DebugPrintControl { // The prototype for a callback function. // using DPrintCallback = void (*)(const FString& fs); // Register a callback. // // Registering a callback that is already // registered is a no-op. // void RegisterCallback(DPrintCallback f); // Enable collection in a buffer. // // If collection is already enabled, this is a no-op. // void EnableCollection(); // Collect all the stored messages, and clear the storage. // TArray GetStored(); }; ////////////////////////////////////////////////////////////// // // ConsoleOutput // // This class stores the text that's in the unreal console. // It stores it as one great big string, which contains // newlines to denote line breaks. // // This class also contains a 'dirty' bit. Each time somebody // appends a line of text to the console, the dirty bit is // automatically set. The bit can be checked using 'IsDirty' // and cleared using 'ClearDirty'. This makes it so that // you don't have to update the unreal widget unless the // text has actually changed. // ////////////////////////////////////////////////////////////// class FlxConsoleOutput { private: FString Content; bool Dirty; // Truncate the console to a reasonable number of // lines. The length is hardwired. void Truncate(); // Add a newline if there isn't one. Returns true if it changed anything. bool MaybeAppendNewline(); // Append text. Returns true if it changed anything. bool MaybeAppendText(const FString& text); public: // Append a line of text to the console. void Append(const FString& text); // Append a line of text to the console on a line by itself. void AppendLine(const FString& text); // Get the console text as a string. const FString& Get() const { return Content; } // Return if the dirty flag is set. bool IsDirty() const { return Dirty; } // Clear the dirty flag. void ClearDirty() { Dirty = false; } };