* Changed the layout of the team window. Trying a single window approach.

* Added Run/Step* buttons.
* Added some handling for selection in the thread list.
* Extended listener mechanisms all over the place (in models and views).
* The team debugger now gets the initial states for the team's threads.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31097 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-06-18 00:35:12 +00:00
parent 6d9fec816e
commit ae53f49064
18 changed files with 536 additions and 61 deletions
+2 -1
View File
@@ -6,8 +6,9 @@
#include "Image.h" #include "Image.h"
Image::Image(const image_info& imageInfo) Image::Image(Team* team,const image_info& imageInfo)
: :
fTeam(team),
fInfo(imageInfo) fInfo(imageInfo)
{ {
} }
+7 -1
View File
@@ -11,18 +11,24 @@
#include <util/DoublyLinkedList.h> #include <util/DoublyLinkedList.h>
class Team;
class Image : public Referenceable, public DoublyLinkedListLinkImpl<Image> { class Image : public Referenceable, public DoublyLinkedListLinkImpl<Image> {
public: public:
Image(const image_info& imageInfo); Image(Team* team, const image_info& imageInfo);
~Image(); ~Image();
status_t Init(); status_t Init();
Team* GetTeam() const { return fTeam; }
image_id ID() const { return fInfo.id; } image_id ID() const { return fInfo.id; }
const char* Name() const { return fInfo.name; } const char* Name() const { return fInfo.name; }
const image_info& Info() const { return fInfo; } const image_info& Info() const { return fInfo; }
private: private:
Team* fTeam;
image_info fInfo; image_info fInfo;
}; };
+2 -1
View File
@@ -20,8 +20,9 @@ Application Debugger :
ElfFile.cpp ElfFile.cpp
Image.cpp Image.cpp
TeamDebugger.cpp
Team.cpp Team.cpp
TeamDebugger.cpp
TeamDebugModel.cpp
Thread.cpp Thread.cpp
# DebugAnalyzer:util # DebugAnalyzer:util
+17
View File
@@ -0,0 +1,17 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef MESSAGE_CODES_H
#define MESSAGE_CODES_H
enum {
MSG_THREAD_RUN = 'run_',
MSG_THREAD_STEP_OVER = 'stov',
MSG_THREAD_STEP_INTO = 'stin',
MSG_THREAD_STEP_OUT = 'stou'
};
#endif // MESSAGE_CODES_H
+48 -10
View File
@@ -7,6 +7,8 @@
#include <new> #include <new>
#include <AutoLocker.h>
// #pragma mark - Team // #pragma mark - Team
@@ -53,7 +55,7 @@ Team::AddThread(Thread* thread)
status_t status_t
Team::AddThread(const thread_info& threadInfo, Thread** _thread) Team::AddThread(const thread_info& threadInfo, Thread** _thread)
{ {
Thread* thread = new(std::nothrow) Thread(threadInfo.thread); Thread* thread = new(std::nothrow) Thread(this, threadInfo.thread);
if (thread == NULL) if (thread == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
@@ -134,7 +136,7 @@ Team::AddImage(Image* image)
status_t status_t
Team::AddImage(const image_info& imageInfo, Image** _image) Team::AddImage(const image_info& imageInfo, Image** _image)
{ {
Image* image = new(std::nothrow) Image(imageInfo); Image* image = new(std::nothrow) Image(this, imageInfo);
if (image == NULL) if (image == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
@@ -197,6 +199,7 @@ Team::Images() const
void void
Team::AddListener(Listener* listener) Team::AddListener(Listener* listener)
{ {
AutoLocker<Team> locker(this);
fListeners.Add(listener); fListeners.Add(listener);
} }
@@ -204,6 +207,7 @@ Team::AddListener(Listener* listener)
void void
Team::RemoveListener(Listener* listener) Team::RemoveListener(Listener* listener)
{ {
AutoLocker<Team> locker(this);
fListeners.Remove(listener); fListeners.Remove(listener);
} }
@@ -213,7 +217,7 @@ Team::_NotifyThreadAdded(Thread* thread)
{ {
for (ListenerList::Iterator it = fListeners.GetIterator(); for (ListenerList::Iterator it = fListeners.GetIterator();
Listener* listener = it.Next();) { Listener* listener = it.Next();) {
listener->ThreadAdded(this, thread); listener->ThreadAdded(ThreadEvent(TEAM_EVENT_THREAD_ADDED, thread));
} }
} }
@@ -223,7 +227,7 @@ Team::_NotifyThreadRemoved(Thread* thread)
{ {
for (ListenerList::Iterator it = fListeners.GetIterator(); for (ListenerList::Iterator it = fListeners.GetIterator();
Listener* listener = it.Next();) { Listener* listener = it.Next();) {
listener->ThreadRemoved(this, thread); listener->ThreadRemoved(ThreadEvent(TEAM_EVENT_THREAD_REMOVED, thread));
} }
} }
@@ -233,7 +237,7 @@ Team::_NotifyImageAdded(Image* image)
{ {
for (ListenerList::Iterator it = fListeners.GetIterator(); for (ListenerList::Iterator it = fListeners.GetIterator();
Listener* listener = it.Next();) { Listener* listener = it.Next();) {
listener->ImageAdded(this, image); listener->ImageAdded(ImageEvent(TEAM_EVENT_IMAGE_ADDED, image));
} }
} }
@@ -243,37 +247,71 @@ Team::_NotifyImageRemoved(Image* image)
{ {
for (ListenerList::Iterator it = fListeners.GetIterator(); for (ListenerList::Iterator it = fListeners.GetIterator();
Listener* listener = it.Next();) { Listener* listener = it.Next();) {
listener->ImageRemoved(this, image); listener->ImageRemoved(ImageEvent(TEAM_EVENT_IMAGE_REMOVED, image));
} }
} }
// #pragma mark - Event
Team::Event::Event(uint32 type, Team* team)
:
fEventType(type),
fTeam(team)
{
}
// #pragma mark - ThreadEvent
Team::ThreadEvent::ThreadEvent(uint32 type, Thread* thread)
:
Event(type, thread->GetTeam()),
fThread(thread)
{
}
// #pragma mark - ImageEvent
Team::ImageEvent::ImageEvent(uint32 type, Image* image)
:
Event(type, image->GetTeam()),
fImage(image)
{
}
// #pragma mark - Listener // #pragma mark - Listener
Team::Listener::~Listener() Team::Listener::~Listener()
{ {
} }
void void
Team::Listener::ThreadAdded(Team* team, Thread* thread) Team::Listener::ThreadAdded(const Team::ThreadEvent& event)
{ {
} }
void void
Team::Listener::ThreadRemoved(Team* team, Thread* thread) Team::Listener::ThreadRemoved(const Team::ThreadEvent& event)
{ {
} }
void void
Team::Listener::ImageAdded(Team* team, Image* image) Team::Listener::ImageAdded(const Team::ImageEvent& event)
{ {
} }
void void
Team::Listener::ImageRemoved(Team* team, Image* image) Team::Listener::ImageRemoved(const Team::ImageEvent& event)
{ {
} }
+51 -4
View File
@@ -11,8 +11,20 @@
#include "Thread.h" #include "Thread.h"
// team event types
enum {
TEAM_EVENT_THREAD_ADDED,
TEAM_EVENT_THREAD_REMOVED,
TEAM_EVENT_IMAGE_ADDED,
TEAM_EVENT_IMAGE_REMOVED
};
class Team : public BLocker { class Team : public BLocker {
public: public:
class Event;
class ThreadEvent;
class ImageEvent;
class Listener; class Listener;
public: public:
@@ -65,15 +77,50 @@ private:
}; };
class Team::Event {
public:
Event(uint32 type, Team* team);
uint32 EventType() const { return fEventType; }
Team* GetTeam() const { return fTeam; }
protected:
uint32 fEventType;
Team* fTeam;
};
class Team::ThreadEvent : public Event {
public:
ThreadEvent(uint32 type, Thread* thread);
Thread* GetThread() const { return fThread; }
protected:
Thread* fThread;
};
class Team::ImageEvent : public Event {
public:
ImageEvent(uint32 type, Image* image);
Image* GetImage() const { return fImage; }
protected:
Image* fImage;
};
class Team::Listener : public DoublyLinkedListLinkImpl<Team::Listener> { class Team::Listener : public DoublyLinkedListLinkImpl<Team::Listener> {
public: public:
virtual ~Listener(); virtual ~Listener();
virtual void ThreadAdded(Team* team, Thread* thread); virtual void ThreadAdded(const Team::ThreadEvent& event);
virtual void ThreadRemoved(Team* team, Thread* thread); virtual void ThreadRemoved(const Team::ThreadEvent& event);
virtual void ImageAdded(Team* team, Image* image); virtual void ImageAdded(const Team::ImageEvent& event);
virtual void ImageRemoved(Team* team, Image* image); virtual void ImageRemoved(const Team::ImageEvent& event);
}; };
+67
View File
@@ -0,0 +1,67 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "TeamDebugModel.h"
#include <new>
#include <AutoLocker.h>
// #pragma mark - TeamDebugModel
TeamDebugModel::TeamDebugModel(Team* team)
:
fTeam(team)
{
}
TeamDebugModel::~TeamDebugModel()
{
}
status_t
TeamDebugModel::Init()
{
return B_OK;
}
void
TeamDebugModel::AddListener(Listener* listener)
{
AutoLocker<TeamDebugModel> locker(this);
fListeners.Add(listener);
}
void
TeamDebugModel::RemoveListener(Listener* listener)
{
AutoLocker<TeamDebugModel> locker(this);
fListeners.Remove(listener);
}
// #pragma mark - Event
TeamDebugModel::Event::Event(uint32 type, TeamDebugModel* model)
:
fEventType(type),
fModel(model)
{
}
// #pragma mark - Listener
TeamDebugModel::Listener::~Listener()
{
}
+68
View File
@@ -0,0 +1,68 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef TEAM_DEBUG_MODEL_H
#define TEAM_DEBUG_MODEL_H
#include "Team.h"
// team debug model event types
//enum {
// TEAM_EVENT_THREAD_ADDED
//};
class TeamDebugModel {
public:
class Event;
class Listener;
public:
TeamDebugModel(Team* team);
~TeamDebugModel();
status_t Init();
bool Lock() { return fTeam->Lock(); }
void Unlock() { fTeam->Unlock(); }
Team* GetTeam() const { return fTeam; }
void AddListener(Listener* listener);
void RemoveListener(Listener* listener);
private:
typedef DoublyLinkedList<Listener> ListenerList;
private:
Team* fTeam;
ListenerList fListeners;
};
class TeamDebugModel::Event {
public:
Event(uint32 type, TeamDebugModel* model);
uint32 EventType() const { return fEventType; }
TeamDebugModel* Model() const { return fModel; }
protected:
uint32 fEventType;
TeamDebugModel* fModel;
};
class TeamDebugModel::Listener
: public DoublyLinkedListLinkImpl<TeamDebugModel::Listener> {
public:
virtual ~Listener();
// virtual void ThreadAdded(const Team::ThreadEvent& event);
};
#endif // TEAM_DEBUG_MODEL_H
+45 -2
View File
@@ -16,12 +16,14 @@
#include "debug_utils.h" #include "debug_utils.h"
#include "Team.h" #include "Team.h"
#include "TeamDebugModel.h"
TeamDebugger::TeamDebugger() TeamDebugger::TeamDebugger()
: :
BLooper("team debugger"), BLooper("team debugger"),
fTeam(NULL), fTeam(NULL),
fDebugModel(NULL),
fTeamID(-1), fTeamID(-1),
fDebuggerPort(-1), fDebuggerPort(-1),
fNubPort(-1), fNubPort(-1),
@@ -29,6 +31,7 @@ TeamDebugger::TeamDebugger()
fTeamWindow(NULL), fTeamWindow(NULL),
fTerminating(false) fTerminating(false)
{ {
fDebugContext.reply_port = -1;
} }
@@ -46,6 +49,9 @@ TeamDebugger::~TeamDebugger()
if (fDebugEventListener >= 0) if (fDebugEventListener >= 0)
wait_for_thread(fDebugEventListener, NULL); wait_for_thread(fDebugEventListener, NULL);
destroy_debug_context(&fDebugContext);
delete fDebugModel;
delete fTeam; delete fTeam;
} }
@@ -72,6 +78,15 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain)
fTeam->SetName(teamInfo.args); fTeam->SetName(teamInfo.args);
// TODO: Set a better name! // TODO: Set a better name!
// create the team debug model
fDebugModel = new(std::nothrow) TeamDebugModel(fTeam);
if (fDebugModel == NULL)
return B_NO_MEMORY;
error = fDebugModel->Init();
if (error != B_OK)
return error;
// create debugger port // create debugger port
char buffer[128]; char buffer[128];
snprintf(buffer, sizeof(buffer), "team %ld debugger", fTeamID); snprintf(buffer, sizeof(buffer), "team %ld debugger", fTeamID);
@@ -99,9 +114,12 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain)
thread_info threadInfo; thread_info threadInfo;
int32 cookie = 0; int32 cookie = 0;
while (get_next_thread_info(fTeamID, &cookie, &threadInfo) == B_OK) { while (get_next_thread_info(fTeamID, &cookie, &threadInfo) == B_OK) {
error = fTeam->AddThread(threadInfo); ::Thread* thread;
error = fTeam->AddThread(threadInfo, &thread);
if (error != B_OK) if (error != B_OK)
return error; return error;
_UpdateThreadState(thread);
} }
image_info imageInfo; image_info imageInfo;
@@ -128,7 +146,7 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain)
// create the team window // create the team window
try { try {
fTeamWindow = TeamWindow::Create(fTeam, this); fTeamWindow = TeamWindow::Create(fDebugModel, this);
} catch (...) { } catch (...) {
// TODO: Notify the user! // TODO: Notify the user!
fprintf(stderr, "Error: Failed to create team window!\n"); fprintf(stderr, "Error: Failed to create team window!\n");
@@ -303,3 +321,28 @@ TeamDebugger::_HandleImageDeleted(const debug_image_deleted& message)
fTeam->RemoveImage(message.info.id); fTeam->RemoveImage(message.info.id);
return false; return false;
} }
void
TeamDebugger::_UpdateThreadState(::Thread* thread)
{
debug_nub_get_cpu_state message;
message.reply_port = fDebugContext.reply_port;
message.thread = thread->ID();
debug_nub_get_cpu_state_reply reply;
status_t error = send_debug_message(&fDebugContext,
B_DEBUG_MESSAGE_GET_CPU_STATE, &message, sizeof(message), &reply,
sizeof(reply));
uint32 newState = THREAD_STATE_UNKNOWN;
if (error == B_OK) {
if (reply.error == B_OK)
newState = THREAD_STATE_STOPPED;
else if (reply.error == B_BAD_THREAD_STATE)
newState = THREAD_STATE_RUNNING;
}
thread->SetState(newState);
}
+4
View File
@@ -15,6 +15,7 @@
class Team; class Team;
class TeamDebugModel;
class TeamDebugger : public DoublyLinkedListLinkImpl<TeamDebugger>, class TeamDebugger : public DoublyLinkedListLinkImpl<TeamDebugger>,
@@ -47,8 +48,11 @@ private:
bool _HandleImageDeleted( bool _HandleImageDeleted(
const debug_image_deleted& message); const debug_image_deleted& message);
void _UpdateThreadState(::Thread* thread);
private: private:
::Team* fTeam; ::Team* fTeam;
TeamDebugModel* fDebugModel;
team_id fTeamID; team_id fTeamID;
port_id fDebuggerPort; port_id fDebuggerPort;
port_id fNubPort; port_id fNubPort;
+11 -2
View File
@@ -6,9 +6,11 @@
#include "Thread.h" #include "Thread.h"
Thread::Thread(thread_id threadID) Thread::Thread(Team* team, thread_id threadID)
: :
fID(threadID) fTeam(team),
fID(threadID),
fState(THREAD_STATE_UNKNOWN)
{ {
} }
@@ -30,3 +32,10 @@ Thread::SetName(const BString& name)
{ {
fName = name; fName = name;
} }
void
Thread::SetState(uint32 state)
{
fState = state;
}
+17 -2
View File
@@ -12,22 +12,37 @@
#include <util/DoublyLinkedList.h> #include <util/DoublyLinkedList.h>
class Team;
enum {
THREAD_STATE_UNKNOWN,
THREAD_STATE_RUNNING,
THREAD_STATE_STOPPED
};
class Thread : public Referenceable, public DoublyLinkedListLinkImpl<Thread> { class Thread : public Referenceable, public DoublyLinkedListLinkImpl<Thread> {
public: public:
Thread(thread_id threadID); Thread(Team* team, thread_id threadID);
~Thread(); ~Thread();
status_t Init(); status_t Init();
thread_id ID() const { return fID; } Team* GetTeam() const { return fTeam; }
thread_id ID() const { return fID; }
const char* Name() const { return fName.String(); } const char* Name() const { return fName.String(); }
void SetName(const BString& name); void SetName(const BString& name);
uint32 State() const { return fState; }
void SetState(uint32 state);
private: private:
Team* fTeam;
thread_id fID; thread_id fID;
BString fName; BString fName;
uint32 fState;
}; };
@@ -204,14 +204,14 @@ ImageListView::MessageReceived(BMessage* message)
void void
ImageListView::ImageAdded(Team* team, Image* image) ImageListView::ImageAdded(const Team::ImageEvent& event)
{ {
Looper()->PostMessage(MSG_SYNC_IMAGE_LIST, this); Looper()->PostMessage(MSG_SYNC_IMAGE_LIST, this);
} }
void void
ImageListView::ImageRemoved(Team* team, Image* image) ImageListView::ImageRemoved(const Team::ImageEvent& event)
{ {
Looper()->PostMessage(MSG_SYNC_IMAGE_LIST, this); Looper()->PostMessage(MSG_SYNC_IMAGE_LIST, this);
} }
@@ -29,8 +29,8 @@ private:
private: private:
// Team::Listener // Team::Listener
virtual void ImageAdded(Team* team, Image* image); virtual void ImageAdded(const Team::ImageEvent& event);
virtual void ImageRemoved(Team* team, Image* image); virtual void ImageRemoved(const Team::ImageEvent& event);
// TableListener // TableListener
virtual void TableRowInvoked(Table* table, int32 rowIndex); virtual void TableRowInvoked(Table* table, int32 rowIndex);
+119 -16
View File
@@ -5,6 +5,9 @@
#include "TeamWindow.h" #include "TeamWindow.h"
#include <stdio.h>
#include <Button.h>
#include <LayoutBuilder.h> #include <LayoutBuilder.h>
#include <Message.h> #include <Message.h>
#include <TabView.h> #include <TabView.h>
@@ -12,23 +15,29 @@
#include <TextView.h> #include <TextView.h>
#include "ImageListView.h" #include "ImageListView.h"
#include "Team.h" #include "MessageCodes.h"
#include "ThreadListView.h" #include "TeamDebugModel.h"
// #pragma mark - TeamWindow // #pragma mark - TeamWindow
TeamWindow::TeamWindow(::Team* team, Listener* listener) TeamWindow::TeamWindow(TeamDebugModel* debugModel, Listener* listener)
: :
BWindow(BRect(100, 100, 699, 499), "Team", B_DOCUMENT_WINDOW, BWindow(BRect(100, 100, 899, 699), "Team", B_DOCUMENT_WINDOW,
B_ASYNCHRONOUS_CONTROLS), B_ASYNCHRONOUS_CONTROLS),
fTeam(team), fDebugModel(debugModel),
fActiveThread(NULL),
fListener(listener), fListener(listener),
fTabView(NULL), fTabView(NULL),
fThreadListView(NULL), fThreadListView(NULL),
fImageListView(NULL) fImageListView(NULL),
fRunButton(NULL),
fStepOverButton(NULL),
fStepIntoButton(NULL),
fStepOutButton(NULL)
{ {
::Team* team = debugModel->GetTeam();
BString name = team->Name(); BString name = team->Name();
if (team->ID() >= 0) if (team->ID() >= 0)
name << " (" << team->ID() << ")"; name << " (" << team->ID() << ")";
@@ -42,9 +51,9 @@ TeamWindow::~TeamWindow()
/*static*/ TeamWindow* /*static*/ TeamWindow*
TeamWindow::Create(::Team* team, Listener* listener) TeamWindow::Create(TeamDebugModel* debugModel, Listener* listener)
{ {
TeamWindow* self = new TeamWindow(team, listener); TeamWindow* self = new TeamWindow(debugModel, listener);
try { try {
self->_Init(); self->_Init();
@@ -61,6 +70,18 @@ void
TeamWindow::MessageReceived(BMessage* message) TeamWindow::MessageReceived(BMessage* message)
{ {
switch (message->what) { switch (message->what) {
case MSG_THREAD_RUN:
printf("MSG_THREAD_RUN\n");
break;
case MSG_THREAD_STEP_OVER:
printf("MSG_THREAD_STEP_OVER\n");
break;
case MSG_THREAD_STEP_INTO:
printf("MSG_THREAD_STEP_INTO\n");
break;
case MSG_THREAD_STEP_OUT:
printf("MSG_THREAD_STEP_OUT\n");
break;
default: default:
BWindow::MessageReceived(message); BWindow::MessageReceived(message);
break; break;
@@ -75,6 +96,13 @@ TeamWindow::QuitRequested()
} }
void
TeamWindow::ThreadSelectionChanged(::Thread* thread)
{
_SetActiveThread(thread);
}
void void
TeamWindow::_Init() TeamWindow::_Init()
{ {
@@ -84,18 +112,93 @@ TeamWindow::_Init()
BLayoutBuilder::Group<>(rootLayout) BLayoutBuilder::Group<>(rootLayout)
.AddSplit(B_VERTICAL, 3.0f) .AddSplit(B_VERTICAL, 3.0f)
.Add(fTabView = new BTabView("tab view"), 0.4f) .Add(fTabView = new BTabView("tab view"), 0.4f)
.AddSplit(B_HORIZONTAL, 3.0f) .AddGroup(B_VERTICAL, 4.0f)
.Add(fImageListView = ImageListView::Create()) .AddGroup(B_HORIZONTAL, 4.0f)
.Add(new BTextView("source view"), 2.0f) .Add(fRunButton = new BButton("Run"))
.Add(fStepOverButton = new BButton("Step Over"))
.Add(fStepIntoButton = new BButton("Step Into"))
.Add(fStepOutButton = new BButton("Step Out"))
.AddGlue()
.End()
.AddSplit(B_HORIZONTAL, 3.0f)
.Add(new BTextView("source view"), 3.0f)
.Add(new BTextView("variables view"))
.End()
.End() .End()
.End(); .End();
fTabView->AddTab(fThreadListView = ThreadListView::Create()); // add threads tab
// fTabView->AddTab(fTeamsPage = new TeamsPage(this)); BSplitView* threadGroup = new BSplitView(B_HORIZONTAL);
// fTabView->AddTab(fThreadsPage = new ThreadsPage(this)); threadGroup->SetName("Threads");
fTabView->AddTab(threadGroup);
BLayoutBuilder::Split<>(threadGroup)
.Add(fThreadListView = ThreadListView::Create(this))
.Add(new BTextView("stack frames"));
fThreadListView->SetTeam(fTeam); // add images tab
fImageListView->SetTeam(fTeam); BSplitView* imagesGroup = new BSplitView(B_HORIZONTAL);
imagesGroup->SetName("Images");
fTabView->AddTab(imagesGroup);
BLayoutBuilder::Split<>(imagesGroup)
.Add(fImageListView = ImageListView::Create())
.Add(new BTextView("source files"));
fThreadListView->SetTeam(fDebugModel->GetTeam());
fImageListView->SetTeam(fDebugModel->GetTeam());
fRunButton->SetMessage(new BMessage(MSG_THREAD_RUN));
fStepOverButton->SetMessage(new BMessage(MSG_THREAD_STEP_OVER));
fStepIntoButton->SetMessage(new BMessage(MSG_THREAD_STEP_INTO));
fStepOutButton->SetMessage(new BMessage(MSG_THREAD_STEP_OUT));
fRunButton->SetTarget(this);
fStepOverButton->SetTarget(this);
fRunButton->SetTarget(this);
fStepOutButton->SetTarget(this);
_UpdateRunButtons();
}
void
TeamWindow::_SetActiveThread(::Thread* thread)
{
if (thread == fActiveThread)
return;
fActiveThread = thread;
_UpdateRunButtons();
}
void
TeamWindow::_UpdateRunButtons()
{
uint32 threadState = fActiveThread != NULL
? fActiveThread->State() : THREAD_STATE_UNKNOWN;
switch (threadState) {
case THREAD_STATE_UNKNOWN:
fRunButton->SetEnabled(false);
fStepOverButton->SetEnabled(false);
fStepIntoButton->SetEnabled(false);
fStepOutButton->SetEnabled(false);
break;
case THREAD_STATE_RUNNING:
fRunButton->SetLabel("Stop");
fRunButton->SetEnabled(true);
fStepOverButton->SetEnabled(false);
fStepIntoButton->SetEnabled(false);
fStepOutButton->SetEnabled(false);
break;
case THREAD_STATE_STOPPED:
fRunButton->SetLabel("Run");
fRunButton->SetEnabled(true);
fStepOverButton->SetEnabled(true);
fStepIntoButton->SetEnabled(true);
fStepOutButton->SetEnabled(true);
break;
}
} }
+21 -5
View File
@@ -8,36 +8,52 @@
#include <String.h> #include <String.h>
#include <Window.h> #include <Window.h>
#include "ThreadListView.h"
class BButton;
class BTabView; class BTabView;
class ImageListView; class ImageListView;
class Team; class Team;
class ThreadListView; class TeamDebugModel;
class TeamWindow : public BWindow { class TeamWindow : public BWindow, private ThreadListView::Listener {
public: public:
class Listener; class Listener;
public: public:
TeamWindow(::Team* team, Listener* listener); TeamWindow(TeamDebugModel* debugModel,
Listener* listener);
~TeamWindow(); ~TeamWindow();
static TeamWindow* Create(::Team* team, Listener* listener); static TeamWindow* Create(TeamDebugModel* debugModel,
Listener* listener);
// throws // throws
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
virtual bool QuitRequested(); virtual bool QuitRequested();
private: private:
// ThreadListView::Listener
virtual void ThreadSelectionChanged(::Thread* thread);
void _Init(); void _Init();
void _SetActiveThread(::Thread* thread);
void _UpdateRunButtons();
private: private:
::Team* fTeam; TeamDebugModel* fDebugModel;
::Thread* fActiveThread;
Listener* fListener; Listener* fListener;
BTabView* fTabView; BTabView* fTabView;
ThreadListView* fThreadListView; ThreadListView* fThreadListView;
ImageListView* fImageListView; ImageListView* fImageListView;
BButton* fRunButton;
BButton* fStepOverButton;
BButton* fStepIntoButton;
BButton* fStepOutButton;
}; };
@@ -129,12 +129,13 @@ private:
// #pragma mark - ThreadListView // #pragma mark - ThreadListView
ThreadListView::ThreadListView() ThreadListView::ThreadListView(Listener* listener)
: :
BGroupView(B_VERTICAL), BGroupView(B_VERTICAL),
fTeam(NULL), fTeam(NULL),
fThreadsTable(NULL), fThreadsTable(NULL),
fThreadsTableModel(NULL) fThreadsTableModel(NULL),
fListener(listener)
{ {
SetName("Threads"); SetName("Threads");
} }
@@ -149,9 +150,9 @@ ThreadListView::~ThreadListView()
/*static*/ ThreadListView* /*static*/ ThreadListView*
ThreadListView::Create() ThreadListView::Create(Listener* listener)
{ {
ThreadListView* self = new ThreadListView; ThreadListView* self = new ThreadListView(listener);
try { try {
self->_Init(); self->_Init();
@@ -204,19 +205,33 @@ ThreadListView::MessageReceived(BMessage* message)
void void
ThreadListView::ThreadAdded(Team* team, Thread* thread) ThreadListView::ThreadAdded(const Team::ThreadEvent& event)
{ {
Looper()->PostMessage(MSG_SYNC_THREAD_LIST, this); Looper()->PostMessage(MSG_SYNC_THREAD_LIST, this);
} }
void void
ThreadListView::ThreadRemoved(Team* team, Thread* thread) ThreadListView::ThreadRemoved(const Team::ThreadEvent& event)
{ {
Looper()->PostMessage(MSG_SYNC_THREAD_LIST, this); Looper()->PostMessage(MSG_SYNC_THREAD_LIST, this);
} }
void
ThreadListView::TableSelectionChanged(Table* table)
{
Thread* thread = NULL;
if (fThreadsTableModel != NULL) {
TableSelectionModel* selectionModel = table->SelectionModel();
thread = fThreadsTableModel->ThreadAt(selectionModel->RowAt(0));
}
fListener->ThreadSelectionChanged(thread);
}
void void
ThreadListView::TableRowInvoked(Table* table, int32 rowIndex) ThreadListView::TableRowInvoked(Table* table, int32 rowIndex)
{ {
@@ -240,5 +255,14 @@ ThreadListView::_Init()
fThreadsTable->AddColumn(new StringTableColumn(1, "Name", 80, 40, 1000, fThreadsTable->AddColumn(new StringTableColumn(1, "Name", 80, 40, 1000,
B_TRUNCATE_END, B_ALIGN_LEFT)); B_TRUNCATE_END, B_ALIGN_LEFT));
fThreadsTable->SetSelectionMode(B_SINGLE_SELECTION_LIST);
fThreadsTable->AddTableListener(this); fThreadsTable->AddTableListener(this);
} }
// #pragma mark - Listener
ThreadListView::Listener::~Listener()
{
}
@@ -11,13 +11,19 @@
#include "Team.h" #include "Team.h"
class Thread;
class ThreadListView : public BGroupView, private Team::Listener, class ThreadListView : public BGroupView, private Team::Listener,
private TableListener { private TableListener {
public: public:
ThreadListView(); class Listener;
public:
ThreadListView(Listener* listener);
~ThreadListView(); ~ThreadListView();
static ThreadListView* Create(); static ThreadListView* Create(Listener* listener);
// throws // throws
void SetTeam(Team* team); void SetTeam(Team* team);
@@ -29,10 +35,11 @@ private:
private: private:
// Team::Listener // Team::Listener
virtual void ThreadAdded(Team* team, Thread* thread); virtual void ThreadAdded(const Team::ThreadEvent& event);
virtual void ThreadRemoved(Team* team, Thread* thread); virtual void ThreadRemoved(const Team::ThreadEvent& event);
// TableListener // TableListener
virtual void TableSelectionChanged(Table* table);
virtual void TableRowInvoked(Table* table, int32 rowIndex); virtual void TableRowInvoked(Table* table, int32 rowIndex);
void _Init(); void _Init();
@@ -41,6 +48,15 @@ private:
Team* fTeam; Team* fTeam;
Table* fThreadsTable; Table* fThreadsTable;
ThreadsTableModel* fThreadsTableModel; ThreadsTableModel* fThreadsTableModel;
Listener* fListener;
};
class ThreadListView::Listener {
public:
virtual ~Listener();
virtual void ThreadSelectionChanged(Thread* thread) = 0;
}; };