Major overhaul of DebugPrint
This commit is contained in:
@@ -1,37 +1,150 @@
|
||||
#include "CoreMinimal.h"
|
||||
#include "engineutil.hpp"
|
||||
|
||||
namespace engineutil {
|
||||
using DPrintCallback = DebugPrintControl::DPrintCallback;
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DPrintState
|
||||
//
|
||||
// The global state of the DPrint routine. There is only
|
||||
// ever one of these, and it is owned by DPrintAccess below.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
struct DPrintState {
|
||||
// True if buffering is enabled.
|
||||
bool Collect;
|
||||
|
||||
// The array of buffered messages.
|
||||
TArray<FString> Messages;
|
||||
|
||||
// The array of callback functions.
|
||||
TArray<DPrintCallback> Callbacks;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DPrintAccess
|
||||
//
|
||||
// This class grants you safe access to the global state
|
||||
// of the DPrint routine. Constructing an object of
|
||||
// class DPrintAccess will lock the global mutex and make
|
||||
// sure that the DPrintState is initialized. Then it will
|
||||
// give you unrestricted access to the DPrintState through
|
||||
// operator right arrow.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
class DPrintAccess {
|
||||
private:
|
||||
// The Mutex that protects the global state.
|
||||
static FCriticalSection Mutex;
|
||||
|
||||
// The Global State. A pointer, to avoid static init issues.
|
||||
static DPrintState* State;
|
||||
|
||||
public:
|
||||
// Constructor. Locks mutex and initializes state if necessary.
|
||||
DPrintAccess() {
|
||||
Mutex.Lock();
|
||||
if (State == nullptr) {
|
||||
State = new DPrintState;
|
||||
State->Collect = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Destructor. Releases mutex.
|
||||
~DPrintAccess() {
|
||||
Mutex.Unlock();
|
||||
}
|
||||
|
||||
// Access the DPrintState.
|
||||
DPrintState* operator ->() {
|
||||
return State;
|
||||
}
|
||||
};
|
||||
|
||||
FCriticalSection DPrintAccess::Mutex;
|
||||
DPrintState* DPrintAccess::State;
|
||||
|
||||
|
||||
// The DPrint array. This stores the dprints
|
||||
// until they can be collected by the console implementation.
|
||||
static TArray<FString> dprint_array;
|
||||
static FCriticalSection dprint_mutex;
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Namespace DebugPrint.
|
||||
//
|
||||
// This contains all the various versions of the DPrint routine.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
void DPrint(const FString& fs) {
|
||||
FScopeLock lk(&dprint_mutex);
|
||||
dprint_array.Emplace(fs);
|
||||
}
|
||||
namespace DebugPrint {
|
||||
|
||||
void DPrint(const char* msg) {
|
||||
FScopeLock lk(&dprint_mutex);
|
||||
dprint_array.Emplace(msg);
|
||||
}
|
||||
// DPrint. Invoke all the callbacks, and store the message.
|
||||
void DPrint(const FString& fs) {
|
||||
DPrintAccess state;
|
||||
for (DPrintCallback cb : state->Callbacks) {
|
||||
cb(fs);
|
||||
}
|
||||
if (state->Collect) {
|
||||
state->Messages.Emplace(fs);
|
||||
}
|
||||
}
|
||||
|
||||
void DPrintHook(const char* msg, size_t len) {
|
||||
FScopeLock lk(&dprint_mutex);
|
||||
dprint_array.Emplace(len, (const UTF8CHAR*)msg);
|
||||
}
|
||||
// Alternative interface to the dispatcher.
|
||||
void DPrint(const char* msg) {
|
||||
DPrint(FString(msg));
|
||||
}
|
||||
|
||||
TArray<FString> DPrintGetStored() {
|
||||
FScopeLock lk(&dprint_mutex);
|
||||
TArray<FString> result = std::move(dprint_array);
|
||||
dprint_array.Empty();
|
||||
return result;
|
||||
}
|
||||
// Alternative interface to the dispatcher.
|
||||
void DPrint(const char* msg, size_t len) {
|
||||
DPrint(FString(len, (const UTF8CHAR*)msg));
|
||||
}
|
||||
|
||||
void ConsoleOutput::Append(const FString& text) {
|
||||
} // namespace DebugPrint
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Namespace DebugPrintControl.
|
||||
//
|
||||
// Configuration and control for the DPrint routine.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
namespace DebugPrintControl {
|
||||
|
||||
// Register a callback. Check for duplication.
|
||||
void RegisterCallback(DPrintCallback cb) {
|
||||
DPrintAccess state;
|
||||
for (DPrintCallback old : state->Callbacks) {
|
||||
if (cb == old) return;
|
||||
}
|
||||
state->Callbacks.Add(cb);
|
||||
}
|
||||
|
||||
// Set the collection bit in the global state.
|
||||
void EnableCollection() {
|
||||
DPrintAccess state;
|
||||
state->Collect = true;
|
||||
}
|
||||
|
||||
// Get the array of collected messages, if any.
|
||||
TArray<FString> GetStored() {
|
||||
DPrintAccess state;
|
||||
TArray<FString> result = std::move(state->Messages);
|
||||
state->Messages.Empty();
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ConsoleOutput
|
||||
//
|
||||
// Storing the text that goes in the unreal console.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
void FConsoleOutput::Append(const FString& text) {
|
||||
if (!text.IsEmpty()) {
|
||||
Content += text;
|
||||
Truncate();
|
||||
@@ -39,7 +152,7 @@ void ConsoleOutput::Append(const FString& text) {
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleOutput::AppendLine(const FString& text) {
|
||||
void FConsoleOutput::AppendLine(const FString& text) {
|
||||
int csize = Content.Len();
|
||||
if ((csize > 0) && (Content[csize - 1] != '\n')) {
|
||||
Content += TEXT("\n");
|
||||
@@ -50,7 +163,7 @@ void ConsoleOutput::AppendLine(const FString& text) {
|
||||
Dirty = true;
|
||||
}
|
||||
|
||||
void ConsoleOutput::Truncate() {
|
||||
void FConsoleOutput::Truncate() {
|
||||
int lines = 50;
|
||||
int csize = Content.Len();
|
||||
int total = 0;
|
||||
@@ -65,5 +178,3 @@ void ConsoleOutput::Truncate() {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace engineutil
|
||||
|
||||
|
||||
Reference in New Issue
Block a user