1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 11:38:21 +02:00
Beef/BeefTools/BeefPerf/src/BPApp.bf
2019-09-04 11:39:56 -07:00

998 lines
No EOL
24 KiB
Beef

using System;
using Beefy;
using Beefy.widgets;
using Beefy.gfx;
using Beefy.theme.dark;
using Beefy.theme;
using System.IO;
using System.Threading;
using System.Collections.Generic;
using System.Diagnostics;
using Beefy.events;
using Beefy.sys;
using System.Text;
using System.Net;
namespace BeefPerf
{
class BPApp : BFApp
{
public new static BPApp sApp;
public float mTimePerFrame = 1.0f / 60;
public bool mWantsFullscreen = false;
public int32 mListenPort = 4208;
//public int32 mListenPort = 135;
WidgetWindow mMainWindow;
Widget mRootWidget;
public Widget mMainWidget;
public List<String> mLogLines = new List<String>() ~ DeleteContainerAndItems!(_);
//public PopupMenuManager mPopupMenuManager;
//public Trainer mTrainer ~ delete _;
public ScriptManager mScriptManager = new ScriptManager() ~ delete _;
public DarkDockingFrame mDockingFrame;
public MainFrame mMainFrame;
public WorkspacePanel mWorkspacePanel;
public Board mBoard;
public ProfilePanel mProfilePanel;
public FindPanel mFindPanel;
public Windows.ProcessInformation mProcessInformation;
public Socket mListenSocket ~ delete _;
public Thread mSocketThread ~ delete _;
public List<BpClient> mClients = new List<BpClient>() ~ delete _;
public List<BpSession> mSessions = new List<BpSession> ~ DeleteContainerAndItems!(_);
public Monitor mClientMonitor = new Monitor() ~ delete _;
public WaitEvent mShutdownEvent = new WaitEvent() ~ delete _;
public BpSession mCurSession;
bool mEnableGCCollect = true;
public bool mIsAutoOpened;
public int32 mStatBytesReceived;
public int32 mStatReportTick;
public int32 mStatBytesPerSec;
public bool mFailed;
public int32 mFailIdx;
public bool Listening
{
get
{
return mListenSocket.IsOpen;
}
set
{
if (value)
{
if (!mListenSocket.IsOpen)
{
if (mListenSocket.Listen(mListenPort) case .Err)
{
Fail(scope String()..AppendF("Failed to listen on port {0}", mListenPort));
}
}
}
else
{
if (mListenSocket.IsOpen)
{
mListenSocket.Close();
}
}
}
}
public this()
{
sApp = this;
gApp = this;
//RefreshRate = 120;
}
public ~this()
{
if (mSocketThread != null)
mSocketThread.Join();
for (var client in mClients)
{
if (!client.IsSessionInitialized)
delete client;
}
Widget.RemoveAndDelete(mWorkspacePanel);
Widget.RemoveAndDelete(mBoard);
Widget.RemoveAndDelete(mProfilePanel);
Widget.RemoveAndDelete(mFindPanel);
if (!mLogLines.IsEmpty)
{
var fs = scope FileStream();
if (fs.Open("BeefPerf.txt", .Append, .ReadWrite, .ReadWrite, 4096, .None, null) case .Ok)
{
var streamWriter = scope StreamWriter(fs, Encoding.UTF8, 4096);
for (var line in mLogLines)
streamWriter.WriteLine(line);
}
}
}
static uint32 TimeToUnixTime(DateTime ft)
{
// takes the last modified date
int64 date = ft.ToFileTime();
// 100-nanoseconds = milliseconds * 10000
int64 adjust = 11644473600000L * 10000;
// removes the diff between 1970 and 1601
date -= adjust;
// converts back from 100-nanoseconds to seconds
return (uint32)(date / 10000000L);
}
public void LogLine(String text)
{
mLogLines.Add(new String(text));
}
public void Fail(String text)
{
//MessageBeep(MessageBeepType.Error);
// Always write to STDOUT even if we're running as a GUI, allowing cases like RunAndWait to pass us a stdout handle
Console.WriteLine("ERROR: {0}", text);
mFailIdx++;
if (gApp.mScriptManager.mRunningCommand)
return;
if (mMainWindow == null)
{
LogLine(text);
mFailed = true;
if (!mShuttingDown)
Shutdown();
return;
}
Dialog aDialog = ThemeFactory.mDefault.CreateDialog("ERROR", text, DarkTheme.sDarkTheme.mIconError);
aDialog.mDefaultButton = aDialog.AddButton("OK");
aDialog.mEscButton = aDialog.mDefaultButton;
aDialog.PopupWindow(mMainWindow);
}
void StartFakeClient()
{
return;
#unwarn
ProcessStartInfo procInfo = scope ProcessStartInfo();
procInfo.UseShellExecute = false;
procInfo.RedirectStandardError = true;
procInfo.SetFileName(@"c:\proj\BeefPerf\x64\Debug\BeefPerf.exe");
procInfo.CreateNoWindow = true;
var spawnedProcess = scope SpawnedProcess();
spawnedProcess.Start(procInfo).IgnoreError();
//Process process = Process.Start(procInfo).GetValueOrDefault();
//delete process;
}
public void UpdateTitle()
{
String title = scope String();
if ((mBoard.mPerfView != null) && (mBoard.mPerfView.mSession.mClientName != null))
{
title.Append(mBoard.mPerfView.mSession.mClientName);
title.Append(" - ");
}
title.Append("BeefPerf");
mMainWindow.SetTitle(title);
}
public override void Init()
{
/*uint timeNow = GetCurrentUnixTime();
FitEntry[] fitEntries = new FitEntry[200];
for (int i = 0; i < fitEntries.Length; i++)
{
fitEntries[i].mElapsedTimeMS = i * 500;
fitEntries[i].mPower = i;
fitEntries[i].mCadence = 90;
}
int[] lapOffsets = scope int[] {100};
WriteFit("c:\\temp\\test.fit", UnixTimeToFitTime(timeNow), fitEntries.CArray(), fitEntries.Length, lapOffsets.CArray(), lapOffsets.Length);*/
base.Init();
mAutoDirty = false;
Socket.Init();
mListenSocket = new Socket();
Listening = true;
mSocketThread = new Thread(new => SocketThreadProc);
mSocketThread.Start(false);
DarkTheme aTheme = new DarkTheme();
aTheme.Init();
ThemeFactory.mDefault = aTheme;
mMainFrame = new MainFrame();
mDockingFrame = mMainFrame.mDockingFrame;
BFWindow.Flags windowFlags = BFWindow.Flags.Border | BFWindow.Flags.SysMenu | //| BFWindow.Flags.CaptureMediaKeys |
BFWindow.Flags.Caption | BFWindow.Flags.Minimize | BFWindow.Flags.QuitOnClose | BFWindowBase.Flags.Resizable |
BFWindow.Flags.Menu | BFWindow.Flags.SysMenu;
if (mWantsFullscreen)
windowFlags |= BFWindowBase.Flags.Fullscreen;
//mRootWidget = new Widget();
mWorkspacePanel = new WorkspacePanel();
mBoard = new Board();
mProfilePanel = new ProfilePanel();
mFindPanel = new FindPanel();
//mRootWidget = mBoard;
mMainWindow = new WidgetWindow(null, "BeefPerf", 0, 0, 1600, 1200, windowFlags, mMainFrame);
mMainWindow.mOnWindowKeyDown.Add(new => SysKeyDown);
mMainWindow.SetMinimumSize(480, 360);
mMainWindow.mIsMainWindow = true;
CreateMenu();
ShowWorkspacePanel();
ShowTimelinePanel();
ShowProfilePanel();
ShowFindPanel();
StartFakeClient();
GC.SetAutoCollectPeriod(mEnableGCCollect ? 20 : -1);
GC.SetCollectFreeThreshold(mEnableGCCollect ? 64*1024*1024 : -1);
}
public override void Stop()
{
base.Stop();
mListenSocket.Close();
}
void ShowWorkspacePanel()
{
if (mWorkspacePanel.mWidgetWindow != null)
{
return;
}
TabbedView tabbedView = CreateTabbedView();
SetupTab(tabbedView, "Workspace", mWorkspacePanel);
tabbedView.SetRequestedSize(320, 320);
if ((mDockingFrame.mSplitType == .Vert) || (mDockingFrame.mDockedWidgets.Count == 1))
mDockingFrame.AddDockedWidget(tabbedView, mDockingFrame.mDockedWidgets[0], DockingFrame.WidgetAlign.Left);
else
mDockingFrame.AddDockedWidget(tabbedView, null, DockingFrame.WidgetAlign.Top);
}
void ShowTimelinePanel()
{
if (mBoard.mWidgetWindow != null)
{
return;
}
TabbedView tabbedView = CreateTabbedView();
SetupTab(tabbedView, "Timeline", mBoard);
tabbedView.SetRequestedSize(250, 250);
tabbedView.mIsFillWidget = true;
if ((mDockingFrame.mSplitType == .Vert) || (mDockingFrame.mDockedWidgets.Count == 1))
mDockingFrame.AddDockedWidget(tabbedView, mDockingFrame.mDockedWidgets[0], DockingFrame.WidgetAlign.Right);
else
mDockingFrame.AddDockedWidget(tabbedView, null, DockingFrame.WidgetAlign.Top);
}
void ShowProfilePanel()
{
if (mProfilePanel.mWidgetWindow != null)
{
return;
}
var tabbedView = CreateTabbedView();
SetupTab(tabbedView, "Profile", mProfilePanel);
tabbedView.SetRequestedSize(300, 300);
if ((mDockingFrame.mSplitType == .Vert) && (mDockingFrame.mDockedWidgets.Count > 0))
mDockingFrame.AddDockedWidget(tabbedView, mDockingFrame.mDockedWidgets.Back, DockingFrame.WidgetAlign.Left);
else
mDockingFrame.AddDockedWidget(tabbedView, null, DockingFrame.WidgetAlign.Bottom);
}
void ShowFindPanel()
{
if (mFindPanel.mWidgetWindow != null)
{
return;
}
var tabbedView = CreateTabbedView();
SetupTab(tabbedView, "Find", mFindPanel);
tabbedView.SetRequestedSize(300, 300);
if ((mDockingFrame.mSplitType == .Vert) && (mDockingFrame.mDockedWidgets.Count > 0))
mDockingFrame.AddDockedWidget(tabbedView, mDockingFrame.mDockedWidgets.Back, DockingFrame.WidgetAlign.Right);
else
mDockingFrame.AddDockedWidget(tabbedView, null, DockingFrame.WidgetAlign.Bottom);
}
void SetupTab(TabbedView tabbedView, String label, Widget widget)
{
var tabButton = tabbedView.AddTab(label, 0, widget, false);
tabButton.mCloseClickedEvent.Add(new () =>
{
var tabbedView = tabButton.mTabbedView;
tabbedView.RemoveTab(tabButton);
if (tabbedView.mTabs.IsEmpty)
{
tabbedView.mParentDockingFrame.RemoveDockedWidget(tabbedView);
gApp.DeferDelete(tabbedView);
}
});
}
void ToggleCheck(IMenu menu, ref bool checkVal)
{
checkVal = !checkVal;
var sysMenu = (SysMenu)menu;
sysMenu.Modify(null, null, null, true, checkVal ? 1 : 0);
}
void ShowInfo()
{
int streamSize = 0;
int lodStreamSize = 0;
for (var client in mClients)
{
for (var thread in client.mThreads)
{
for (var streamData in thread.mStreamDataList)
{
streamSize += streamData.mBuffer.Count;
}
for (var streamLOD in thread.mStreamLODs)
{
for (var streamData in streamLOD.mStreamDataList)
{
lodStreamSize += streamData.mBuffer.Count;
}
}
}
}
Debug.WriteLine("Stream Size: {0}k", streamSize / 1024);
Debug.WriteLine("LOD Stream Size: {0}k", lodStreamSize / 1024);
}
public void CloseSession()
{
SetSession(null);
}
public void OpenSession()
{
List<int> iList = scope List<int>();
iList.Add(123);
var fileDialog = scope OpenFileDialog();
fileDialog.ShowReadOnly = false;
fileDialog.Title = "Open Session";
fileDialog.Multiselect = true;
fileDialog.ValidateNames = true;
fileDialog.DefaultExt = ".bfps";
fileDialog.SetFilter("BeefPerf Session (*.bfps)|*.bfps|All files (*.*)|*.*");
if (fileDialog.ShowDialog() case .Ok)
{
for (String origProjFilePath in fileDialog.FileNames)
{
var session = new BpSession(false);
switch (session.Load(origProjFilePath))
{
case .Ok:
mSessions.Add(session);
MarkDirty();
case .Err(let err):
switch (err)
{
case .FileNotFound, .FileError:
Fail(scope String()..AppendF("Failed to open file '{0}'", origProjFilePath));
case .InvalidData:
Fail(scope String()..AppendF("Invalid data in file '{0}'", origProjFilePath));
case .InvalidVersion:
Fail(scope String()..AppendF("Unsupported version in file '{0}'", origProjFilePath));
}
delete session;
}
}
}
}
public void SaveSession()
{
if (mCurSession == null)
return;
var fileDialog = scope SaveFileDialog();
//fileDialog.ShowReadOnly = false;
fileDialog.Title = "Save Session";
fileDialog.Multiselect = true;
fileDialog.ValidateNames = true;
fileDialog.DefaultExt = ".bfps";
fileDialog.SetFilter("BeefPerf Session (*.bfps)|*.bfps|All files (*.*)|*.*");
if (fileDialog.ShowDialog() case .Ok)
{
for (String origProjFilePath in fileDialog.FileNames)
{
if (mCurSession.Save(origProjFilePath) case .Err)
{
Fail(scope String()..AppendF("Failed to save file '{0}'", origProjFilePath));
}
}
}
}
public void RemoveSession()
{
if (mCurSession == null)
return;
var session = mCurSession;
SetSession(null);
mSessions.Remove(session);
using (mClientMonitor.Enter())
{
var client = session as BpClient;
if (client != null)
mClients.Remove(client);
delete session;
}
MarkDirty();
}
public void RemoveAllSessions()
{
SetSession(null);
using (mClientMonitor.Enter())
{
ClearAndDeleteItems(mSessions);
mSessions.Clear();
mClients.Clear();
}
MarkDirty();
}
public void CreateMenu()
{
SysMenu root = mMainWindow.mSysMenu;
SysMenu subMenu = root.AddMenuItem("&File");
subMenu.AddMenuItem("&Open Session", "Ctrl+O", new (menu) => { OpenSession(); });
subMenu.AddMenuItem("&Save Session", "Ctrl+S", new (menu) => { SaveSession(); });
subMenu.AddMenuItem("&Close Session", "Ctrl+W", new (menu) => { CloseSession(); });
subMenu.AddMenuItem("&Remove Session", null, new (menu) => { RemoveSession(); });
subMenu.AddMenuItem("Remove &All Sessions", null, new (menu) => { RemoveAllSessions(); });
subMenu.AddMenuItem("&Info", "Ctrl+I", new (menu) => { ShowInfo(); });
subMenu.AddMenuItem("E&xit", null, new (menu) => { mMainWindow.Close(); });
subMenu = root.AddMenuItem("&View");
subMenu.AddMenuItem("&Workspace", "Ctrl+Alt+W", new (menu) => { ShowWorkspacePanel(); });
subMenu.AddMenuItem("&Timeline", "Ctrl+Alt+T", new (menu) => { ShowTimelinePanel(); });
subMenu.AddMenuItem("&Profile", "Ctrl+Alt+P", new (menu) => { ShowProfilePanel(); });
subMenu.AddMenuItem("&Find", "Ctrl+Alt+F", new (menu) => { ShowFindPanel(); });
subMenu = root.AddMenuItem("&Debug");
subMenu.AddMenuItem("GC Collect", null, new (menu) =>
{
if (Profiler.StartSampling() case .Ok(let id))
{
GC.Collect();
id.Dispose();
}
});
subMenu.AddMenuItem("Enable GC Collect", null, new (menu) => { ToggleCheck(menu, ref mEnableGCCollect); }, null, null, true, mEnableGCCollect ? 1 : 0);
}
public override void Shutdown()
{
base.Shutdown();
mShutdownEvent.Set(true);
}
public override bool HandleCommandLineParam(String key, String value)
{
switch (key)
{
case "-autoOpened":
mIsAutoOpened = true;
return true;
case "-cmd":
if (value == null)
return false;
Socket.Init();
LogLine(scope String()..AppendF("Cmd: {0}", value));
bool alreadyRunning = false;
//
{
Socket socket = scope Socket();
if (socket.Listen(mListenPort) case .Err)
alreadyRunning = true;
}
if (!alreadyRunning)
{
LogLine("Launching BeefPerf process");
var exePath = scope String();
var curProcess = scope Process();
curProcess.GetProcessById(Process.CurrentId);
exePath.Append(curProcess.ProcessName);
ProcessStartInfo procInfo = scope ProcessStartInfo();
procInfo.SetFileName(exePath);
procInfo.SetArguments("-autoOpened");
SpawnedProcess spawnedProcess = scope SpawnedProcess();
spawnedProcess.Start(procInfo);
}
// Try for 10 seconds
for (int i < 100)
{
Socket socket = scope Socket();
if (socket.Connect("127.0.0.1", mListenPort) case .Err)
{
Thread.Sleep(100);
continue;
}
DynMemStream memStream = scope DynMemStream();
memStream.Write((int32)0); // Size placeholder
memStream.Write((uint8)BpCmd.Cmd);
String cmdStr = value;
memStream.Write(cmdStr);
memStream.Write((uint8)0);
(*(int32*)memStream.Ptr) = (int32)memStream.Length - 4;
// Try 10 seconds to send
for (int sendItr < 100)
{
if (memStream.IsEmpty)
break;
switch (socket.Send(memStream.Ptr, memStream.Length))
{
case .Ok(let sendLen):
memStream.RemoveFromStart(sendLen);
case .Err:
Fail("Failed to send command");
}
if (memStream.IsEmpty)
break;
Thread.Sleep(100); // Wait until we can send more...
}
// Try 10 seconds for a response
bool gotResult = false;
RecvLoop: for (int recvStr < 100)
{
int result = 0;
switch (socket.Recv(&result, 1))
{
case .Ok(let recvLen):
if (recvLen > 0)
{
if (result != 1)
Fail("Command failed");
gotResult = true;
break RecvLoop;
}
case .Err:
break;
}
Thread.Sleep(100);
}
if (!gotResult)
{
Fail("Failed to receive command response");
}
if (!mShuttingDown)
Shutdown();
return true;
}
Fail("Failed to connect to BeefPerf");
case "-fullscreen":
mWantsFullscreen = true;
case "-windowed":
mWantsFullscreen = false;
default:
return base.HandleCommandLineParam(key, value);
}
return true;
}
public override void UnhandledCommandLine(String key, String value)
{
Fail(StackStringFormat!("Unhandled command line param: {0}", key));
}
void SetupNewWindow(WidgetWindow window)
{
window.mOnWindowKeyDown.Add(new => SysKeyDown);
//window.mWindowCloseQueryHandler.Add(new => SecondaryAllowClose);
}
DarkTabbedView CreateTabbedView()
{
var tabbedView = new DarkTabbedView();
tabbedView.mSharedData.mOpenNewWindowDelegate.Add(new (fromTabbedView, newWindow) => SetupNewWindow(newWindow));
return tabbedView;
}
public void PushMainWidget(Widget widget)
{
if (mMainWidget != null)
{
mMainWidget.RemoveSelf();
DeferDelete(mMainWidget);
}
mMainWidget = widget;
mRootWidget.AddWidget(widget);
widget.Resize(0, 0, mRootWidget.mWidth, mRootWidget.mHeight);
widget.SetFocus();
}
void SocketThreadProc()
{
while (true)
{
if (mShutdownEvent.WaitFor(0))
return;
//TODO: Add client sockets to the select set
var readSet = default(Socket.FDSet);
var writeSet = default(Socket.FDSet);
var exceptSet = default(Socket.FDSet);
void Add(Socket socket)
{
readSet.Add(socket.[Friend]mHandle);
exceptSet.Add(socket.[Friend]mHandle);
}
Add(mListenSocket);
using (mClientMonitor.Enter())
{
for (var client in mClients)
Add(client.mSocket);
}
#unwarn
int selectResult = Socket.Select(&readSet, &writeSet, &exceptSet, 20*1000);
int clientIdx = 0;
while (true)
{
BpClient client = null;
using (mClientMonitor.Enter())
{
if (clientIdx < mClients.Count)
{
client = mClients[clientIdx++];
}
if (client == null)
break;
client.TryRecv();
}
}
}
}
public override void Update(bool batchStart)
{
base.Update(batchStart);
/*if (!mListenSocket.IsConnected)
{
Listen();
}*/
Socket newConnection = new Socket();
if (newConnection.AcceptFrom(mListenSocket) case .Ok)
{
using (mClientMonitor.Enter())
{
BpClient client = new BpClient();
//client.mProfileId = Profiler.StartSampling();
client.mConnectTime = DateTime.Now;
client.mSocket = newConnection;
mClients.Add(client);
}
/*{
// Kill all old clients - remove this when we support switching between clients
ClearAndDeleteItems(mClients);
mFindPanel.Clear();
mProfilePanel.Clear();
mFindPanel.mNeedsRestartSearch = true;
BpClient client = new BpClient();
client.mSocket = newConnection;
mClients.Add(client);
SetClient(client);
}*/
}
else
delete newConnection;
using (mClientMonitor.Enter())
{
for (var client in mClients)
{
client.Update();
if (client.mSessionOver)
{
if (!client.IsSessionInitialized)
delete client;
@client.Remove();
if (mClients.Count == 0)
{
gApp.mStatBytesPerSec = 0;
}
MarkDirty();
}
if (mUpdateCnt % 20 == 0)
MarkDirty();
}
}
if (mUpdateCnt - mStatReportTick >= 60)
{
mStatBytesPerSec = mStatBytesReceived;
mStatBytesReceived = 0;
mStatReportTick = mUpdateCnt;
}
}
void SysKeyDown(KeyDownEvent evt)
{
var window = (WidgetWindow)evt.mSender;
#unwarn
Widget focusWidget = window.mFocusWidget;
if (evt.mKeyFlags == 0) // No ctrl/shift/alt
{
switch (evt.mKeyCode)
{
default:
}
}
if (evt.mKeyFlags == .Ctrl)
{
switch (evt.mKeyCode)
{
case (KeyCode)'F':
ShowFind();
case (KeyCode)'C':
if (DarkTooltipManager.sTooltip != null)
{
SetClipboardText(DarkTooltipManager.sTooltip.mText);
}
default:
}
}
}
enum ShowTabResult
{
Existing,
OpenedNew
}
public void WithDocumentTabbedViews(Action<DarkTabbedView> func)
{
for (int32 windowIdx = 0; windowIdx < mWindows.Count; windowIdx++)
{
var window = mWindows[windowIdx];
var widgetWindow = window as WidgetWindow;
if (widgetWindow != null)
{
var darkDockingFrame = widgetWindow.mRootWidget as DarkDockingFrame;
if (widgetWindow == mMainWindow)
darkDockingFrame = mDockingFrame;
if (darkDockingFrame != null)
{
darkDockingFrame.WithAllDockedWidgets(scope (dockedWidget) =>
{
var tabbedView = dockedWidget as DarkTabbedView;
if (tabbedView != null)
func(tabbedView);
});
}
}
}
}
public void WithTabs(Action<TabbedView.TabButton> func)
{
WithDocumentTabbedViews(scope (documentTabbedView) =>
{
documentTabbedView.WithTabs(func);
});
}
public TabbedView.TabButton GetTab(Widget content)
{
TabbedView.TabButton tab = null;
WithTabs(scope [&] (checkTab) =>
{
if (checkTab.mContent == content)
tab = checkTab;
});
return tab;
}
TabbedView FindTabbedView(DockingFrame dockingFrame, int32 xDir, int32 yDir)
{
bool useFirst = true;
if (dockingFrame.mSplitType == DockingFrame.SplitType.Horz)
{
useFirst = xDir > 0;
}
else
useFirst = yDir > 0;
for (int32 pass = 0; pass < 2; pass++)
{
for (int32 i = 0; i < dockingFrame.mDockedWidgets.Count; i++)
{
if ((useFirst) && (i == 0) && (pass == 0))
continue;
var widget = dockingFrame.mDockedWidgets[i];
if (widget is TabbedView)
return (TabbedView)widget;
DockingFrame childFrame = widget as DockingFrame;
if (childFrame != null)
{
TabbedView tabbedView = FindTabbedView(childFrame, xDir, yDir);
if (tabbedView != null)
return tabbedView;
}
}
}
return null;
}
ShowTabResult ShowTab(Widget tabContent, String name, float width, bool ownsContent)
{
var result = ShowTabResult.Existing;
var tabButton = GetTab(tabContent);
if (tabButton == null)
{
TabbedView tabbedView = FindTabbedView(mDockingFrame, -1, 1);
if (tabbedView != null)
{
tabButton = tabbedView.AddTab(name, width, tabContent, ownsContent);
result = ShowTabResult.OpenedNew;
}
}
if (tabButton != null)
tabButton.Activate();
return result;
}
void ShowPanel(Widget panel, String label)
{
//RecordHistoryLocation();
ShowTab(panel, label, 150, false);
//panel.FocusForKeyboard();
}
public void ShowFind()
{
ShowPanel(mFindPanel, "Find");
mFindPanel.mEntryEdit.SetFocus();
}
public void SetSession(BpSession session)
{
if (session == mCurSession)
return;
mFindPanel.Clear();
mProfilePanel.Clear();
mFindPanel.mNeedsRestartSearch = true;
mCurSession = session;
mBoard.ShowSession(session);
mFindPanel.Show(mBoard.mPerfView);
mFindPanel.Clear();
MarkDirty();
/*if (mBoard.mPerfView != null)
{
mBoard.mPerfView.SaveSummary("BfCompiler_Compile", @"c:\temp\save.txt");
}*/
}
public void ZoneSelected(PerfView perfView, BPSelection selection)
{
mProfilePanel.Show(perfView, selection);
}
public void ReportBytesReceived(int32 count)
{
mStatBytesReceived += count;
}
public bool HandleClientCommand(BpClient client, StringView cmd)
{
int failIdx = mFailIdx;
mScriptManager.Exec(cmd);
return failIdx == mFailIdx;
}
public void SessionInitialized(BpClient bpClient)
{
mSessions.Add(bpClient);
UpdateTitle();
MarkDirty();
}
}
}
static
{
static BeefPerf.BPApp gApp;
}