1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-07-02 22:36:00 +02:00

Added "Keep Native Console Open" option

This commit is contained in:
Brian Fiete 2024-07-24 09:41:08 +02:00
parent fd3bd861ae
commit 8052066ab0
18 changed files with 423 additions and 41 deletions

View file

@ -270,7 +270,7 @@ namespace IDE.Debugger
static extern char8* Debugger_GetCollectionContinuation(char8* continuationData, int32 callStackIdx, int32 count);
[CallingConvention(.Stdcall),CLink]
static extern void Debugger_ForegroundTarget();
static extern void Debugger_ForegroundTarget(int32 altProcessId);
[CallingConvention(.Stdcall),CLink]
static extern void CallStack_Update();
@ -314,6 +314,9 @@ namespace IDE.Debugger
[CallingConvention(.Stdcall),CLink]
static extern char8* Debugger_GetProcessInfo();
[CallingConvention(.Stdcall),CLink]
static extern int32 Debugger_GetProcessId();
[CallingConvention(.Stdcall),CLink]
static extern char8* Debugger_GetThreadInfo();
@ -912,9 +915,9 @@ namespace IDE.Debugger
outVal.Append(result);
}
public void ForegroundTarget()
public void ForegroundTarget(int32 altProcessId)
{
Debugger_ForegroundTarget();
Debugger_ForegroundTarget(altProcessId);
}
public void UpdateCallStack()
@ -1079,6 +1082,13 @@ namespace IDE.Debugger
outProcessInfo.Append(strPtr);
}
public int32 GetProcessId()
{
if (!mIsRunning)
return 0;
return Debugger_GetProcessId();
}
public void GetThreadInfo(String outThreadInfo)
{
if (!mIsRunning)

View file

@ -426,8 +426,15 @@ namespace IDE
public int mSampleRate;
}
class OpenDebugConsoleCmd : ExecutionCmd
{
}
class StartDebugCmd : ExecutionCmd
{
public bool mConnectedToConsole;
public int32 mConsoleProcessId;
public bool mWasCompiled;
public bool mHotCompileEnabled;
@ -9248,6 +9255,73 @@ namespace IDE
}
}
if (let startDebugCmd = next as StartDebugCmd)
{
#if BF_PLATFORM_WINDOWS
if ((mSettings.mDebugConsoleKind == .Native) && (mSettings.mKeepNativeConsoleOpen))
{
if (!startDebugCmd.mConnectedToConsole)
{
if (startDebugCmd.mConsoleProcessId == 0)
{
int32 processId = 0;
List<Process> processList = scope .();
Process.GetProcesses(processList);
defer processList.ClearAndDeleteItems();
for (var process in processList)
{
if ((process.ProcessName.Contains("BeefCon.exe")) || (process.ProcessName.Contains("BeefCon_d.exe")))
{
var title = process.GetMainWindowTitle(.. scope .());
if (title.EndsWith("Debug Console"))
{
processId = process.Id;
}
}
}
if (processId == 0)
{
var beefConExe = scope $"{gApp.mInstallDir}/BeefCon.exe";
ProcessStartInfo procInfo = scope ProcessStartInfo();
procInfo.UseShellExecute = false;
procInfo.SetFileName(beefConExe);
procInfo.SetArguments(scope $"{Process.CurrentId}");
procInfo.ActivateWindow = false;
var process = scope SpawnedProcess();
if (process.Start(procInfo) case .Ok)
{
processId = (.)process.ProcessId;
}
}
startDebugCmd.mConsoleProcessId = processId;
}
if (startDebugCmd.mConsoleProcessId != 0)
{
if (WinNativeConsoleProvider.AttachConsole(startDebugCmd.mConsoleProcessId))
{
// Worked
WinNativeConsoleProvider.ClearConsole();
mConsolePanel.mBeefConAttachState = .Attached(startDebugCmd.mConsoleProcessId);
startDebugCmd.mConnectedToConsole = true;
}
else
{
// Keep trying to attach
return;
}
}
}
}
#endif
}
defer delete next;
mExecutionQueue.RemoveAt(0);
@ -9336,6 +9410,19 @@ namespace IDE
}
else
OutputLine("Failed to start debugger");
/*#if BF_PLATFORM_WINDOWS
if ((mSettings.mDebugConsoleKind == .Native) && (mSettings.mKeepNativeConsoleOpen))
{
BeefConConsoleProvider.Pipe pipe = scope .();
//pipe.Connect(Process.CurrentId, )
pipe.Connect(123, -startDebugCmd.mConsoleProcessId).IgnoreError();
pipe.StartMessage(.Attached);
pipe.Stream.Write((int32)mDebugger.GetProcessId());
pipe.EndMessage();
}
#endif*/
}
}
else if (next is ExecutionQueueCmd)
@ -13781,7 +13868,12 @@ namespace IDE
if (mForegroundTargetCountdown > 0)
{
if ((--mForegroundTargetCountdown == 0) && (mDebugger.mIsRunning))
mDebugger.ForegroundTarget();
{
if (mConsolePanel.mBeefConAttachState case .Connected(let processId))
mDebugger.ForegroundTarget(processId);
else
mDebugger.ForegroundTarget(0);
}
}
if ((mDebugger != null) && (mExecutionPaused) && (mDebugger.mIsRunning))
@ -13845,6 +13937,33 @@ namespace IDE
DeleteAndNullify!(mLaunchData);
mErrorsPanel?.UpdateAlways();
if ((mConsolePanel != null) && (mConsolePanel.mBeefConAttachState case .Attached(let consoleProcessId)))
{
if (!mDebugger.mIsRunning)
{
mConsolePanel.Detach();
}
else
{
int32 debugProcessId = mDebugger.GetProcessId();
if (debugProcessId != 0)
{
BeefConConsoleProvider.Pipe pipe = scope .();
pipe.Connect(Process.CurrentId, -consoleProcessId).IgnoreError();
//pipe.Connect(Process.CurrentId, )
//pipe.Connect(123, -consoleProcessId).IgnoreError();
pipe.StartMessage(.Attached);
pipe.Stream.Write(debugProcessId);
pipe.EndMessage();
mConsolePanel.Detach();
mConsolePanel.mBeefConAttachState = .Connected(consoleProcessId);
mDebugger.ForegroundTarget(consoleProcessId);
}
}
}
}
public void ShowPassOutput(BfPassInstance bfPassInstance)

View file

@ -1122,6 +1122,7 @@ namespace IDE
public String mWindowsTerminal = new .("Powershell") ~ delete _;
public ConsoleKind mDebugConsoleKind;
public bool mAlwaysEnableConsole;
public bool mKeepNativeConsoleOpen;
public String mEmscriptenPath = new .() ~ delete _;
public bool mEnableDevMode;
public TutorialsFinished mTutorialsFinished = .();
@ -1184,6 +1185,7 @@ namespace IDE
sd.Add("WindowsTerminal", mWindowsTerminal);
sd.Add("DebugConsole", mDebugConsoleKind);
sd.Add("AlwaysEnableConsole", mAlwaysEnableConsole);
sd.Add("KeepNativeConsoleOpen", mKeepNativeConsoleOpen);
}
using (sd.CreateObject("Wasm"))
sd.Add("EmscriptenPath", mEmscriptenPath);
@ -1279,6 +1281,7 @@ namespace IDE
sd.Get("WindowsTerminal", mWindowsTerminal);
mDebugConsoleKind = sd.GetEnum<ConsoleKind>("DebugConsole", .Native);
mAlwaysEnableConsole = sd.GetBool("AlwaysEnableConsole");
mKeepNativeConsoleOpen = sd.GetBool("KeepNativeConsoleOpen");
}
using (sd.Open("Wasm"))
sd.Get("EmscriptenPath", mEmscriptenPath);

View file

@ -281,6 +281,13 @@ class ConsolePanel : Panel
}
}
public enum BeefConAttachState
{
case None;
case Attached(int32 processId);
case Connected(int32 processId);
}
public ConsoleProvider mConsoleProvider ~ delete _;
public DarkCheckBox mMousePassthroughCB;
public DarkCheckBox mPauseCB;
@ -290,6 +297,7 @@ class ConsolePanel : Panel
public int32 mCellHeight;
public (Position start, Position end)? mSelection;
public Position? mClickPos;
public BeefConAttachState mBeefConAttachState;
public bool Paused
{
@ -781,6 +789,14 @@ class ConsolePanel : Panel
public void Detach()
{
if (mBeefConAttachState case .Attached)
{
#if BF_PLATFORM_WINDOWS
WinNativeConsoleProvider.FreeConsole();
#endif
mBeefConAttachState = .None;
}
if (!mConsoleProvider.Attached)
return;
mConsoleProvider.Detach();

View file

@ -181,6 +181,7 @@ namespace IDE.ui
AddPropertiesItem(category, "Windows Terminal", "mWindowsTerminal");
AddPropertiesItem(category, "Debug Console", "mDebugConsoleKind");
AddPropertiesItem(category, "Always Enable Console", "mAlwaysEnableConsole");
AddPropertiesItem(category, "Keep Native Console Open", "mKeepNativeConsoleOpen");
category.Open(true, true);
}

View file

@ -250,10 +250,13 @@ class WinNativeConsoleProvider : ConsoleProvider
#if BF_PLATFORM_WINDOWS
[CLink, CallingConvention(.Stdcall)]
public static extern void AllocConsole();
public static extern Windows.IntBool AllocConsole();
[CLink, CallingConvention(.Stdcall)]
public static extern void AttachConsole(int processId);
public static extern void SetConsoleTitleW(char16* title);
[CLink, CallingConvention(.Stdcall)]
public static extern Windows.IntBool AttachConsole(int processId);
[CLink, CallingConvention(.Stdcall)]
public static extern void FreeConsole();
@ -290,6 +293,15 @@ class WinNativeConsoleProvider : ConsoleProvider
[CLink]
public static extern Windows.IntBool ReadConsoleInputW(Windows.Handle handle, INPUT_RECORD* eventsPtr, int32 eventCount, out int32 numEventsRead);
[CLink]
public static extern Windows.IntBool SetConsoleCursorPosition(Windows.Handle handle, POINT pos);
[CLink]
public static extern Windows.IntBool FillConsoleOutputCharacterW(Windows.Handle handle, char16 char, int32 length, POINT writeCoord, out int32 numCharsWritten);
[CLink]
public static extern Windows.IntBool FillConsoleOutputAttribute(Windows.Handle handle, uint16 attribute, int32 length, POINT writeCoord, out int32 numCharsWritten);
#endif
ScreenInfo mScreenInfo ~ delete _;
@ -789,6 +801,58 @@ class WinNativeConsoleProvider : ConsoleProvider
{
return (mScreenInfo != null) ? mScreenInfo.mColorTable[i] : 0xFF000000;
}
public static void ClearConsole()
{
var outHandle = Console.[Friend]GetStdHandle(Console.STD_OUTPUT_HANDLE);
POINT coordScreen = default; // home for the cursor
int32 cCharsWritten;
CONSOLE_SCREEN_BUFFER_INFOEX csbi = default;
csbi.mSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);
// Get the number of character cells in the current buffer.
if (!GetConsoleScreenBufferInfoEx(outHandle, ref csbi))
{
return;
}
let dwConSize = (int32)csbi.mWidth * csbi.mHeight;
// Fill the entire screen with blanks.
if (!FillConsoleOutputCharacterW(outHandle, // Handle to console screen buffer
' ', // Character to write to the buffer
dwConSize, // Number of cells to write
coordScreen, // Coordinates of first cell
out cCharsWritten)) // Receive number of characters written
{
return;
}
// Get the current text attribute.
if (!GetConsoleScreenBufferInfoEx(outHandle, ref csbi))
{
return;
}
// Set the buffer's attributes accordingly.
if (!FillConsoleOutputAttribute(outHandle, // Handle to console screen buffer
csbi.wAttributes, // Character attributes to use
dwConSize, // Number of cells to set attribute
coordScreen, // Coordinates of first cell
out cCharsWritten)) // Receive number of characters written
{
return;
}
// Put the cursor at its home coordinates.
SetConsoleCursorPosition(outHandle, coordScreen);
}
public void Clear()
{
ClearConsole();
}
}
class BeefConConsoleProvider : ConsoleProvider
@ -807,7 +871,8 @@ class BeefConConsoleProvider : ConsoleProvider
MouseUp,
MouseWheel,
ScrollTo,
Update
Update,
Attached
}
public class Pipe