* SourceView can now show markers for stack frame instruction pointers.
Furthermore it automatically scrolls to the current IP of the currently
selected stack frame.
* TeamWindow:
- Be lazy setting the SourceCode, i.e. as long as no other source shall be
shown (e.g. another stack frame is selected) we keep the previous one.
- When a new stack strace is set, automatically select the top-most frame.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31170 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -11,32 +11,118 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <LayoutUtils.h>
|
||||
#include <Polygon.h>
|
||||
#include <ScrollBar.h>
|
||||
|
||||
#include <AutoLocker.h>
|
||||
#include <ObjectList.h>
|
||||
|
||||
#include "SourceCode.h"
|
||||
#include "StackFrame.h"
|
||||
#include "StackTrace.h"
|
||||
#include "Statement.h"
|
||||
#include "TeamDebugModel.h"
|
||||
|
||||
|
||||
static const int32 kLeftTextMargin = 3;
|
||||
static const float kMinViewHeight = 80.0f;
|
||||
|
||||
|
||||
class SourceView::MarkerView : public BView {
|
||||
class SourceView::BaseView : public BView {
|
||||
public:
|
||||
BaseView(const char* name, SourceView* sourceView, FontInfo* fontInfo)
|
||||
:
|
||||
BView(name, B_WILL_DRAW | B_SUBPIXEL_PRECISE),
|
||||
fSourceView(sourceView),
|
||||
fFontInfo(fontInfo),
|
||||
fSourceCode(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void SetSourceCode(SourceCode* sourceCode)
|
||||
{
|
||||
fSourceCode = sourceCode;
|
||||
|
||||
InvalidateLayout();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
virtual BSize PreferredSize()
|
||||
{
|
||||
return MinSize();
|
||||
}
|
||||
|
||||
protected:
|
||||
int32 LineCount() const
|
||||
{
|
||||
return fSourceCode != NULL ? fSourceCode->CountLines() : 0;
|
||||
}
|
||||
|
||||
float TotalHeight() const
|
||||
{
|
||||
float height = LineCount() * fFontInfo->lineHeight - 1;
|
||||
return std::max(height, kMinViewHeight);
|
||||
}
|
||||
|
||||
void GetLineRange(BRect rect, int32& minLine, int32& maxLine)
|
||||
{
|
||||
int32 lineHeight = (int32)fFontInfo->lineHeight;
|
||||
minLine = (int32)rect.top / lineHeight;
|
||||
maxLine = ((int32)ceilf(rect.bottom) + lineHeight - 1) / lineHeight;
|
||||
minLine = std::max(minLine, 0L);
|
||||
maxLine = std::min(maxLine, fSourceCode->CountLines() - 1);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
SourceView* fSourceView;
|
||||
FontInfo* fFontInfo;
|
||||
SourceCode* fSourceCode;
|
||||
};
|
||||
|
||||
|
||||
class SourceView::MarkerView : public BaseView {
|
||||
public:
|
||||
MarkerView(SourceView* sourceView, FontInfo* fontInfo)
|
||||
:
|
||||
BView("source marker view", B_WILL_DRAW),
|
||||
fSourceView(sourceView),
|
||||
fFontInfo(fontInfo)
|
||||
BaseView("source marker view", sourceView, fontInfo),
|
||||
fStackTrace(NULL),
|
||||
fStackFrame(NULL),
|
||||
fMarkers(20, true),
|
||||
fMarkersValid(false)
|
||||
{
|
||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
}
|
||||
|
||||
~MarkerView()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void SetSourceCode(SourceCode* sourceCode)
|
||||
{
|
||||
fMarkers.MakeEmpty();
|
||||
fMarkersValid = false;
|
||||
BaseView::SetSourceCode(sourceCode);
|
||||
}
|
||||
|
||||
void SetStackTrace(StackTrace* stackTrace)
|
||||
{
|
||||
fStackTrace = stackTrace;
|
||||
fMarkers.MakeEmpty();
|
||||
fMarkersValid = false;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void SetStackFrame(StackFrame* stackFrame)
|
||||
{
|
||||
fStackFrame = stackFrame;
|
||||
fMarkers.MakeEmpty();
|
||||
fMarkersValid = false;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
virtual BSize MinSize()
|
||||
{
|
||||
return BSize(40, 10);
|
||||
return BSize(40, TotalHeight());
|
||||
}
|
||||
|
||||
virtual BSize MaxSize()
|
||||
@@ -44,49 +130,184 @@ public:
|
||||
return BSize(MinSize().width, B_SIZE_UNLIMITED);
|
||||
}
|
||||
|
||||
virtual BSize PreferredSize()
|
||||
{
|
||||
return MinSize();
|
||||
}
|
||||
|
||||
virtual void Draw(BRect updateRect)
|
||||
{
|
||||
_UpdateMarkers();
|
||||
|
||||
if (fSourceCode == NULL || fMarkers.IsEmpty())
|
||||
return;
|
||||
|
||||
// get the lines intersecting with the update rect
|
||||
int32 minLine, maxLine;
|
||||
GetLineRange(updateRect, minLine, maxLine);
|
||||
|
||||
// draw the markers
|
||||
float width = Bounds().Width();
|
||||
// TODO: The markers should be sorted, so we don't need to iterate over
|
||||
// all of them.
|
||||
for (int32 i = 0; Marker* marker = fMarkers.ItemAt(i); i++) {
|
||||
int32 line = marker->Line();
|
||||
if (line < minLine || line > maxLine)
|
||||
continue;
|
||||
|
||||
float y = (float)line * fFontInfo->lineHeight;
|
||||
BRect rect(0, y, width, y + fFontInfo->lineHeight - 1);
|
||||
marker->Draw(this, rect);
|
||||
}
|
||||
|
||||
// TODO: Draw possible breakpoint marks!
|
||||
}
|
||||
|
||||
private:
|
||||
SourceView* fSourceView;
|
||||
FontInfo* fFontInfo;
|
||||
struct Marker {
|
||||
Marker(uint32 line)
|
||||
:
|
||||
fLine(line)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~Marker()
|
||||
{
|
||||
}
|
||||
|
||||
uint32 Line() const
|
||||
{
|
||||
return fLine;
|
||||
}
|
||||
|
||||
virtual void Draw(MarkerView* view, BRect rect) = 0;
|
||||
|
||||
private:
|
||||
uint32 fLine;
|
||||
};
|
||||
|
||||
struct InstructionPointerMarker : Marker {
|
||||
InstructionPointerMarker(uint32 line, bool topIP, bool currentIP)
|
||||
:
|
||||
Marker(line),
|
||||
fIsTopIP(topIP),
|
||||
fIsCurrentIP(currentIP)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Draw(MarkerView* view, BRect rect)
|
||||
{
|
||||
// Get the arrow color -- for the top IP, if current, we use blue,
|
||||
// otherwise a gray.
|
||||
rgb_color color;
|
||||
if (fIsCurrentIP && fIsTopIP) {
|
||||
color.set_to(0, 0, 255, 255);
|
||||
} else {
|
||||
color = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
|
||||
B_DARKEN_3_TINT);
|
||||
}
|
||||
|
||||
// Draw a filled array for the current IP, otherwise just an
|
||||
// outline.
|
||||
BPoint tip(rect.right - 3.5f, floorf((rect.top + rect.bottom) / 2));
|
||||
if (fIsCurrentIP) {
|
||||
_DrawArrow(view, tip, BSize(10, 10), BSize(5, 5), color, true);
|
||||
} else {
|
||||
_DrawArrow(view, tip + BPoint(-0.5f, 0), BSize(9, 8),
|
||||
BSize(5, 4), color, false);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void _DrawArrow(BView* view, BPoint tip, BSize size, BSize base,
|
||||
const rgb_color& color, bool fill)
|
||||
{
|
||||
view->SetHighColor(color);
|
||||
|
||||
float baseTop = tip.y - base.height / 2;
|
||||
float baseBottom = tip.y + base.height / 2;
|
||||
float top = tip.y - size.height / 2;
|
||||
float bottom = tip.y + size.height / 2;
|
||||
float left = tip.x - size.width;
|
||||
float middle = left + base.width;
|
||||
|
||||
BPoint points[7];
|
||||
points[0].Set(tip.x, tip.y);
|
||||
points[1].Set(middle, top);
|
||||
points[2].Set(middle, baseTop);
|
||||
points[3].Set(left, baseTop);
|
||||
points[4].Set(left, baseBottom);
|
||||
points[5].Set(middle, baseBottom);
|
||||
points[6].Set(middle, bottom);
|
||||
|
||||
if (fill)
|
||||
view->FillPolygon(points, 7);
|
||||
else
|
||||
view->StrokePolygon(points, 7);
|
||||
}
|
||||
|
||||
private:
|
||||
bool fIsTopIP;
|
||||
bool fIsCurrentIP;
|
||||
};
|
||||
|
||||
typedef BObjectList<Marker> MarkerList;
|
||||
|
||||
private:
|
||||
void _UpdateMarkers()
|
||||
{
|
||||
if (fMarkersValid)
|
||||
return;
|
||||
|
||||
fMarkers.MakeEmpty();
|
||||
|
||||
if (fSourceCode != NULL && fStackTrace != NULL) {
|
||||
for (int32 i = 0; StackFrame* frame = fStackTrace->FrameAt(i);
|
||||
i++) {
|
||||
target_addr_t ip = frame->InstructionPointer();
|
||||
Statement* statement = fSourceCode->StatementAtAddress(ip);
|
||||
if (statement == NULL)
|
||||
continue;
|
||||
uint32 line = statement->StartSourceLocation().Line();
|
||||
if (line >= (uint32)LineCount())
|
||||
continue;
|
||||
|
||||
Marker* marker = new(std::nothrow) InstructionPointerMarker(
|
||||
line, i == 0, frame == fStackFrame);
|
||||
if (marker == NULL || !fMarkers.AddItem(marker)) {
|
||||
delete marker;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: Filter duplicate IP markers (recursive functions)!
|
||||
|
||||
fMarkersValid = true;
|
||||
}
|
||||
|
||||
private:
|
||||
StackTrace* fStackTrace;
|
||||
StackFrame* fStackFrame;
|
||||
MarkerList fMarkers;
|
||||
bool fMarkersValid;
|
||||
};
|
||||
|
||||
|
||||
class SourceView::TextView : public BView {
|
||||
class SourceView::TextView : public BaseView {
|
||||
public:
|
||||
TextView(SourceView* sourceView, FontInfo* fontInfo)
|
||||
:
|
||||
BView("source text view", B_WILL_DRAW),
|
||||
fSourceView(sourceView),
|
||||
fFontInfo(fontInfo),
|
||||
fSourceCode(NULL),
|
||||
BaseView("source text view", sourceView, fontInfo),
|
||||
fMaxLineWidth(-1)
|
||||
{
|
||||
SetViewColor(ui_color(B_DOCUMENT_BACKGROUND_COLOR));
|
||||
fTextColor = ui_color(B_DOCUMENT_TEXT_COLOR);
|
||||
}
|
||||
|
||||
void SetSourceCode(SourceCode* sourceCode)
|
||||
virtual void SetSourceCode(SourceCode* sourceCode)
|
||||
{
|
||||
fSourceCode = sourceCode;
|
||||
fMaxLineWidth = -1;
|
||||
|
||||
InvalidateLayout();
|
||||
Invalidate();
|
||||
BaseView::SetSourceCode(sourceCode);
|
||||
}
|
||||
|
||||
virtual BSize MinSize()
|
||||
{
|
||||
float height = _LineCount() * fFontInfo->lineHeight;
|
||||
return BSize(kLeftTextMargin + _MaxLineWidth() - 1,
|
||||
std::max(height - 1, 100.0f));
|
||||
return BSize(kLeftTextMargin + _MaxLineWidth() - 1, TotalHeight());
|
||||
}
|
||||
|
||||
virtual BSize MaxSize()
|
||||
@@ -94,23 +315,14 @@ public:
|
||||
return BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED);
|
||||
}
|
||||
|
||||
virtual BSize PreferredSize()
|
||||
{
|
||||
return MinSize();
|
||||
}
|
||||
|
||||
virtual void Draw(BRect updateRect)
|
||||
{
|
||||
if (fSourceCode == NULL)
|
||||
return;
|
||||
|
||||
// get the lines intersecting with the update rect
|
||||
int32 lineHeight = (int32)fFontInfo->lineHeight;
|
||||
int32 minLine = (int32)updateRect.top / lineHeight;
|
||||
int32 maxLine = ((int32)ceilf(updateRect.bottom) + lineHeight - 1)
|
||||
/ lineHeight;
|
||||
minLine = std::max(minLine, 0L);
|
||||
maxLine = std::min(maxLine, fSourceCode->CountLines() - 1);
|
||||
int32 minLine, maxLine;
|
||||
GetLineRange(updateRect, minLine, maxLine);
|
||||
|
||||
// draw the affected lines
|
||||
SetHighColor(fTextColor);
|
||||
@@ -123,11 +335,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
int32 _LineCount() const
|
||||
{
|
||||
return fSourceCode != NULL ? fSourceCode->CountLines() : 0;
|
||||
}
|
||||
|
||||
float _MaxLineWidth()
|
||||
{
|
||||
if (fMaxLineWidth >= 0)
|
||||
@@ -145,9 +352,6 @@ private:
|
||||
}
|
||||
|
||||
private:
|
||||
SourceView* fSourceView;
|
||||
FontInfo* fFontInfo;
|
||||
SourceCode* fSourceCode;
|
||||
float fMaxLineWidth;
|
||||
rgb_color fTextColor;
|
||||
};
|
||||
@@ -160,6 +364,7 @@ SourceView::SourceView(TeamDebugModel* debugModel, Listener* listener)
|
||||
:
|
||||
BView("source view", 0),
|
||||
fDebugModel(debugModel),
|
||||
fStackTrace(NULL),
|
||||
fStackFrame(NULL),
|
||||
fSourceCode(NULL),
|
||||
fMarkerView(NULL),
|
||||
@@ -177,6 +382,8 @@ SourceView::SourceView(TeamDebugModel* debugModel, Listener* listener)
|
||||
SourceView::~SourceView()
|
||||
{
|
||||
SetStackFrame(NULL);
|
||||
SetStackTrace(NULL);
|
||||
SetSourceCode(NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -204,49 +411,112 @@ SourceView::UnsetListener()
|
||||
|
||||
|
||||
void
|
||||
SourceView::SetStackFrame(StackFrame* frame)
|
||||
SourceView::SetStackTrace(StackTrace* stackTrace)
|
||||
{
|
||||
printf("SourceView::SetStackFrame(%p)\n", frame);
|
||||
if (frame == fStackFrame)
|
||||
printf("SourceView::SetStackTrace(%p)\n", stackTrace);
|
||||
if (stackTrace == fStackTrace)
|
||||
return;
|
||||
|
||||
if (fStackFrame != NULL)
|
||||
fStackFrame->RemoveReference();
|
||||
if (fStackTrace != NULL) {
|
||||
fMarkerView->SetStackTrace(NULL);
|
||||
fStackTrace->RemoveReference();
|
||||
}
|
||||
|
||||
fStackFrame = frame;
|
||||
fStackTrace = stackTrace;
|
||||
|
||||
if (fStackFrame != NULL)
|
||||
fStackFrame->AddReference();
|
||||
if (fStackTrace != NULL)
|
||||
fStackTrace->AddReference();
|
||||
|
||||
UpdateSourceCode();
|
||||
fMarkerView->SetStackTrace(fStackTrace);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SourceView::UpdateSourceCode()
|
||||
SourceView::SetStackFrame(StackFrame* stackFrame)
|
||||
{
|
||||
// get a reference to the source code
|
||||
AutoLocker<TeamDebugModel> locker(fDebugModel);
|
||||
if (stackFrame == fStackFrame)
|
||||
return;
|
||||
|
||||
SourceCode* sourceCode = fStackFrame != NULL
|
||||
? fStackFrame->GetSourceCode() : NULL;
|
||||
Reference<SourceCode> sourceCodeReference(sourceCode);
|
||||
if (fStackFrame != NULL) {
|
||||
fMarkerView->SetStackFrame(NULL);
|
||||
fStackFrame->RemoveReference();
|
||||
}
|
||||
|
||||
locker.Unlock();
|
||||
fStackFrame = stackFrame;
|
||||
|
||||
if (fStackFrame != NULL)
|
||||
fStackFrame->AddReference();
|
||||
|
||||
fMarkerView->SetStackFrame(fStackFrame);
|
||||
|
||||
if (fStackFrame != NULL)
|
||||
ScrollToAddress(fStackFrame->InstructionPointer());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SourceView::SetSourceCode(SourceCode* sourceCode)
|
||||
{
|
||||
// set the source code, if it changed
|
||||
if (sourceCode == fSourceCode)
|
||||
return;
|
||||
|
||||
if (fSourceCode != NULL) {
|
||||
fTextView->SetSourceCode(NULL);
|
||||
fMarkerView->SetSourceCode(NULL);
|
||||
fSourceCode->RemoveReference();
|
||||
}
|
||||
|
||||
fSourceCode = sourceCodeReference.Detach();
|
||||
fSourceCode = sourceCode;
|
||||
|
||||
if (fSourceCode != NULL)
|
||||
fSourceCode->AddReference();
|
||||
|
||||
fTextView->SetSourceCode(fSourceCode);
|
||||
fMarkerView->SetSourceCode(fSourceCode);
|
||||
_UpdateScrollBars();
|
||||
|
||||
if (fStackFrame != NULL)
|
||||
ScrollToAddress(fStackFrame->InstructionPointer());
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SourceView::ScrollToAddress(target_addr_t address)
|
||||
{
|
||||
if (fSourceCode == NULL)
|
||||
return false;
|
||||
|
||||
Statement* statement = fSourceCode->StatementAtAddress(address);
|
||||
if (statement == NULL)
|
||||
return false;
|
||||
|
||||
return ScrollToLine(statement->StartSourceLocation().Line());
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SourceView::ScrollToLine(uint32 line)
|
||||
{
|
||||
printf("SourceView::ScrollToLine(%lu)\n", line);
|
||||
if (fSourceCode == NULL || line >= (uint32)fSourceCode->CountLines())
|
||||
return false;
|
||||
|
||||
float top = (float)line * fFontInfo.lineHeight;
|
||||
float bottom = top + fFontInfo.lineHeight - 1;
|
||||
|
||||
BRect visible = _VisibleRect();
|
||||
|
||||
// If not visible at all, scroll to the center, otherwise scroll so that at
|
||||
// least one more line is visible.
|
||||
if (top >= visible.bottom || bottom <= visible.top)
|
||||
ScrollTo(visible.left, top - (visible.Height() + 1) / 2);
|
||||
else if (top - fFontInfo.lineHeight < visible.top)
|
||||
ScrollBy(0, top - fFontInfo.lineHeight - visible.top);
|
||||
else if (bottom + fFontInfo.lineHeight > visible.bottom)
|
||||
ScrollBy(0, bottom + fFontInfo.lineHeight - visible.bottom);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -360,6 +630,13 @@ SourceView::_DataRectSize() const
|
||||
}
|
||||
|
||||
|
||||
BRect
|
||||
SourceView::_VisibleRect() const
|
||||
{
|
||||
return BRect(Bounds().LeftTop(), Frame().Size());
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Listener
|
||||
|
||||
|
||||
|
||||
@@ -8,9 +8,12 @@
|
||||
#include <Font.h>
|
||||
#include <View.h>
|
||||
|
||||
#include "ArchitectureTypes.h"
|
||||
|
||||
|
||||
class SourceCode;
|
||||
class StackFrame;
|
||||
class StackTrace;
|
||||
class TeamDebugModel;
|
||||
|
||||
|
||||
@@ -29,8 +32,12 @@ public:
|
||||
|
||||
void UnsetListener();
|
||||
|
||||
void SetStackFrame(StackFrame* frame);
|
||||
void UpdateSourceCode();
|
||||
void SetStackTrace(StackTrace* stackTrace);
|
||||
void SetStackFrame(StackFrame* stackFrame);
|
||||
void SetSourceCode(SourceCode* sourceCode);
|
||||
|
||||
bool ScrollToAddress(target_addr_t address);
|
||||
bool ScrollToLine(uint32 line);
|
||||
|
||||
virtual void TargetedByScrollView(BScrollView* scrollView);
|
||||
|
||||
@@ -41,6 +48,7 @@ public:
|
||||
virtual void DoLayout();
|
||||
|
||||
private:
|
||||
class BaseView;
|
||||
class MarkerView;
|
||||
class TextView;
|
||||
|
||||
@@ -54,9 +62,11 @@ private:
|
||||
void _Init();
|
||||
void _UpdateScrollBars();
|
||||
BSize _DataRectSize() const;
|
||||
BRect _VisibleRect() const;
|
||||
|
||||
private:
|
||||
TeamDebugModel* fDebugModel;
|
||||
StackTrace* fStackTrace;
|
||||
StackFrame* fStackFrame;
|
||||
SourceCode* fSourceCode;
|
||||
MarkerView* fMarkerView;
|
||||
|
||||
@@ -209,6 +209,22 @@ StackTraceView::SetStackTrace(StackTrace* stackTrace)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StackTraceView::SetStackFrame(StackFrame* stackFrame)
|
||||
{
|
||||
if (fStackTrace != NULL && stackFrame != NULL) {
|
||||
for (int32 i = 0; StackFrame* other = fStackTrace->FrameAt(i); i++) {
|
||||
if (stackFrame == other) {
|
||||
fFramesTable->SelectRow(i, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fFramesTable->DeselectAllRows();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StackTraceView::TableSelectionChanged(Table* table)
|
||||
{
|
||||
|
||||
@@ -28,6 +28,7 @@ public:
|
||||
void UnsetListener();
|
||||
|
||||
void SetStackTrace(StackTrace* stackTrace);
|
||||
void SetStackFrame(StackFrame* stackFrame);
|
||||
|
||||
private:
|
||||
class FramesTableModel;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "ImageListView.h"
|
||||
#include "MessageCodes.h"
|
||||
#include "RegisterView.h"
|
||||
#include "SourceCode.h"
|
||||
#include "StackTrace.h"
|
||||
#include "StackTraceView.h"
|
||||
#include "TeamDebugModel.h"
|
||||
@@ -35,7 +36,9 @@ TeamWindow::TeamWindow(TeamDebugModel* debugModel, Listener* listener)
|
||||
B_ASYNCHRONOUS_CONTROLS),
|
||||
fDebugModel(debugModel),
|
||||
fActiveThread(NULL),
|
||||
fActiveStackTrace(NULL),
|
||||
fActiveStackFrame(NULL),
|
||||
fActiveSourceCode(NULL),
|
||||
fListener(listener),
|
||||
fTabView(NULL),
|
||||
fLocalsTabView(NULL),
|
||||
@@ -69,6 +72,15 @@ TeamWindow::~TeamWindow()
|
||||
fSourceView->UnsetListener();
|
||||
|
||||
fDebugModel->GetTeam()->RemoveListener(this);
|
||||
|
||||
if (fActiveSourceCode != NULL)
|
||||
fActiveSourceCode->RemoveReference();
|
||||
if (fActiveStackFrame != NULL)
|
||||
fActiveStackFrame->RemoveReference();
|
||||
if (fActiveStackTrace != NULL)
|
||||
fActiveStackTrace->RemoveReference();
|
||||
if (fActiveThread != NULL)
|
||||
fActiveThread->RemoveReference();
|
||||
}
|
||||
|
||||
|
||||
@@ -283,8 +295,14 @@ TeamWindow::_SetActiveThread(::Thread* thread)
|
||||
if (thread == fActiveThread)
|
||||
return;
|
||||
|
||||
if (fActiveThread != NULL)
|
||||
fActiveThread->RemoveReference();
|
||||
|
||||
fActiveThread = thread;
|
||||
|
||||
if (fActiveThread != NULL)
|
||||
fActiveThread->AddReference();
|
||||
|
||||
AutoLocker<TeamDebugModel> locker(fDebugModel);
|
||||
_UpdateRunButtons();
|
||||
|
||||
@@ -295,11 +313,33 @@ TeamWindow::_SetActiveThread(::Thread* thread)
|
||||
|
||||
locker.Unlock();
|
||||
|
||||
fStackTraceView->SetStackTrace(stackTrace);
|
||||
_SetActiveStackTrace(stackTrace);
|
||||
_UpdateCpuState();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TeamWindow::_SetActiveStackTrace(StackTrace* stackTrace)
|
||||
{
|
||||
if (stackTrace == fActiveStackTrace)
|
||||
return;
|
||||
|
||||
if (fActiveStackTrace != NULL)
|
||||
fActiveStackTrace->RemoveReference();
|
||||
|
||||
fActiveStackTrace = stackTrace;
|
||||
|
||||
if (fActiveStackTrace != NULL)
|
||||
fActiveStackTrace->AddReference();
|
||||
|
||||
fStackTraceView->SetStackTrace(fActiveStackTrace);
|
||||
fSourceView->SetStackTrace(fActiveStackTrace);
|
||||
|
||||
if (fActiveStackTrace != NULL)
|
||||
_SetActiveStackFrame(fActiveStackTrace->FrameAt(0));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TeamWindow::_SetActiveStackFrame(StackFrame* frame)
|
||||
{
|
||||
@@ -315,10 +355,18 @@ TeamWindow::_SetActiveStackFrame(StackFrame* frame)
|
||||
|
||||
fActiveStackFrame = frame;
|
||||
|
||||
SourceCode* sourceCode = NULL;
|
||||
Reference<SourceCode> sourceCodeReference;
|
||||
bool setSourceCode = false;
|
||||
|
||||
if (fActiveStackFrame != NULL) {
|
||||
fActiveStackFrame->AddReference();
|
||||
fActiveStackFrame->AddListener(this);
|
||||
|
||||
sourceCode = fActiveStackFrame->GetSourceCode();
|
||||
sourceCodeReference.SetTo(sourceCode);
|
||||
setSourceCode = true;
|
||||
|
||||
// If the source code is not loaded yet, request it.
|
||||
if (fActiveStackFrame->SourceCodeState() == STACK_SOURCE_NOT_LOADED)
|
||||
fListener->StackFrameSourceCodeRequested(this, fActiveStackFrame);
|
||||
@@ -328,10 +376,32 @@ TeamWindow::_SetActiveStackFrame(StackFrame* frame)
|
||||
|
||||
locker.Unlock();
|
||||
|
||||
if (setSourceCode)
|
||||
_SetActiveSourceCode(sourceCode);
|
||||
|
||||
fStackTraceView->SetStackFrame(fActiveStackFrame);
|
||||
fSourceView->SetStackFrame(fActiveStackFrame);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TeamWindow::_SetActiveSourceCode(SourceCode* sourceCode)
|
||||
{
|
||||
if (sourceCode == fActiveSourceCode)
|
||||
return;
|
||||
|
||||
if (fActiveSourceCode != NULL)
|
||||
fActiveSourceCode->RemoveReference();
|
||||
|
||||
fActiveSourceCode = sourceCode;
|
||||
|
||||
if (fActiveSourceCode != NULL)
|
||||
fActiveSourceCode->AddReference();
|
||||
|
||||
fSourceView->SetSourceCode(fActiveSourceCode);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TeamWindow::_UpdateCpuState()
|
||||
{
|
||||
@@ -427,14 +497,26 @@ TeamWindow::_HandleStackTraceChanged(thread_id threadID)
|
||||
|
||||
locker.Unlock();
|
||||
|
||||
fStackTraceView->SetStackTrace(stackTrace);
|
||||
_SetActiveStackTrace(stackTrace);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TeamWindow::_HandleSourceCodeChanged()
|
||||
{
|
||||
fSourceView->UpdateSourceCode();
|
||||
// If we don't have an active stack frame anymore, the message is obsolete.
|
||||
if (fActiveStackFrame == NULL)
|
||||
return;
|
||||
|
||||
// get a reference to the source code
|
||||
AutoLocker<TeamDebugModel> locker(fDebugModel);
|
||||
|
||||
SourceCode* sourceCode = fActiveStackFrame->GetSourceCode();
|
||||
Reference<SourceCode> sourceCodeReference(sourceCode);
|
||||
|
||||
locker.Unlock();
|
||||
|
||||
_SetActiveSourceCode(sourceCode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ class BButton;
|
||||
class BTabView;
|
||||
class ImageListView;
|
||||
class RegisterView;
|
||||
class SourceCode;
|
||||
class TeamDebugModel;
|
||||
|
||||
|
||||
@@ -64,7 +65,9 @@ private:
|
||||
void _Init();
|
||||
|
||||
void _SetActiveThread(::Thread* thread);
|
||||
void _SetActiveStackTrace(StackTrace* stackTrace);
|
||||
void _SetActiveStackFrame(StackFrame* frame);
|
||||
void _SetActiveSourceCode(SourceCode* sourceCode);
|
||||
void _UpdateCpuState();
|
||||
void _UpdateRunButtons();
|
||||
|
||||
@@ -76,7 +79,9 @@ private:
|
||||
private:
|
||||
TeamDebugModel* fDebugModel;
|
||||
::Thread* fActiveThread;
|
||||
StackTrace* fActiveStackTrace;
|
||||
StackFrame* fActiveStackFrame;
|
||||
SourceCode* fActiveSourceCode;
|
||||
Listener* fListener;
|
||||
BTabView* fTabView;
|
||||
BTabView* fLocalsTabView;
|
||||
|
||||
Reference in New Issue
Block a user