diff --git a/src/apps/debugger/Image.cpp b/src/apps/debugger/Image.cpp index 2528212a8b..525360b91d 100644 --- a/src/apps/debugger/Image.cpp +++ b/src/apps/debugger/Image.cpp @@ -6,8 +6,9 @@ #include "Image.h" -Image::Image(const image_info& imageInfo) +Image::Image(Team* team,const image_info& imageInfo) : + fTeam(team), fInfo(imageInfo) { } diff --git a/src/apps/debugger/Image.h b/src/apps/debugger/Image.h index 5ee17ef72d..19c39c2dbc 100644 --- a/src/apps/debugger/Image.h +++ b/src/apps/debugger/Image.h @@ -11,18 +11,24 @@ #include +class Team; + + class Image : public Referenceable, public DoublyLinkedListLinkImpl { public: - Image(const image_info& imageInfo); + Image(Team* team, const image_info& imageInfo); ~Image(); status_t Init(); + + Team* GetTeam() const { return fTeam; } image_id ID() const { return fInfo.id; } const char* Name() const { return fInfo.name; } const image_info& Info() const { return fInfo; } private: + Team* fTeam; image_info fInfo; }; diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index 569ed2803d..325f634948 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -20,8 +20,9 @@ Application Debugger : ElfFile.cpp Image.cpp - TeamDebugger.cpp Team.cpp + TeamDebugger.cpp + TeamDebugModel.cpp Thread.cpp # DebugAnalyzer:util diff --git a/src/apps/debugger/MessageCodes.h b/src/apps/debugger/MessageCodes.h new file mode 100644 index 0000000000..b0b0ce74c9 --- /dev/null +++ b/src/apps/debugger/MessageCodes.h @@ -0,0 +1,17 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * 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 diff --git a/src/apps/debugger/Team.cpp b/src/apps/debugger/Team.cpp index 7e48b9cf96..60f8605160 100644 --- a/src/apps/debugger/Team.cpp +++ b/src/apps/debugger/Team.cpp @@ -7,6 +7,8 @@ #include +#include + // #pragma mark - Team @@ -53,7 +55,7 @@ Team::AddThread(Thread* thread) status_t 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) return B_NO_MEMORY; @@ -134,7 +136,7 @@ Team::AddImage(Image* image) status_t 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) return B_NO_MEMORY; @@ -197,6 +199,7 @@ Team::Images() const void Team::AddListener(Listener* listener) { + AutoLocker locker(this); fListeners.Add(listener); } @@ -204,6 +207,7 @@ Team::AddListener(Listener* listener) void Team::RemoveListener(Listener* listener) { + AutoLocker locker(this); fListeners.Remove(listener); } @@ -213,7 +217,7 @@ Team::_NotifyThreadAdded(Thread* thread) { for (ListenerList::Iterator it = fListeners.GetIterator(); 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(); 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(); 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(); 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 + Team::Listener::~Listener() { } void -Team::Listener::ThreadAdded(Team* team, Thread* thread) +Team::Listener::ThreadAdded(const Team::ThreadEvent& event) { } void -Team::Listener::ThreadRemoved(Team* team, Thread* thread) +Team::Listener::ThreadRemoved(const Team::ThreadEvent& event) { } void -Team::Listener::ImageAdded(Team* team, Image* image) +Team::Listener::ImageAdded(const Team::ImageEvent& event) { } void -Team::Listener::ImageRemoved(Team* team, Image* image) +Team::Listener::ImageRemoved(const Team::ImageEvent& event) { } diff --git a/src/apps/debugger/Team.h b/src/apps/debugger/Team.h index 5cc7afed41..0b74998d61 100644 --- a/src/apps/debugger/Team.h +++ b/src/apps/debugger/Team.h @@ -11,8 +11,20 @@ #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 { public: + class Event; + class ThreadEvent; + class ImageEvent; class Listener; 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 { public: virtual ~Listener(); - virtual void ThreadAdded(Team* team, Thread* thread); - virtual void ThreadRemoved(Team* team, Thread* thread); + virtual void ThreadAdded(const Team::ThreadEvent& event); + virtual void ThreadRemoved(const Team::ThreadEvent& event); - virtual void ImageAdded(Team* team, Image* image); - virtual void ImageRemoved(Team* team, Image* image); + virtual void ImageAdded(const Team::ImageEvent& event); + virtual void ImageRemoved(const Team::ImageEvent& event); }; diff --git a/src/apps/debugger/TeamDebugModel.cpp b/src/apps/debugger/TeamDebugModel.cpp new file mode 100644 index 0000000000..9ae4a2a034 --- /dev/null +++ b/src/apps/debugger/TeamDebugModel.cpp @@ -0,0 +1,67 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + +#include "TeamDebugModel.h" + +#include + +#include + + +// #pragma mark - TeamDebugModel + + +TeamDebugModel::TeamDebugModel(Team* team) + : + fTeam(team) +{ +} + + +TeamDebugModel::~TeamDebugModel() +{ +} + + +status_t +TeamDebugModel::Init() +{ + return B_OK; +} + + +void +TeamDebugModel::AddListener(Listener* listener) +{ + AutoLocker locker(this); + fListeners.Add(listener); +} + + +void +TeamDebugModel::RemoveListener(Listener* listener) +{ + AutoLocker 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() +{ +} diff --git a/src/apps/debugger/TeamDebugModel.h b/src/apps/debugger/TeamDebugModel.h new file mode 100644 index 0000000000..dfb5f728e4 --- /dev/null +++ b/src/apps/debugger/TeamDebugModel.h @@ -0,0 +1,68 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * 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 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 { +public: + virtual ~Listener(); + +// virtual void ThreadAdded(const Team::ThreadEvent& event); +}; + + +#endif // TEAM_DEBUG_MODEL_H diff --git a/src/apps/debugger/TeamDebugger.cpp b/src/apps/debugger/TeamDebugger.cpp index bedb850400..8f33a76cb9 100644 --- a/src/apps/debugger/TeamDebugger.cpp +++ b/src/apps/debugger/TeamDebugger.cpp @@ -16,12 +16,14 @@ #include "debug_utils.h" #include "Team.h" +#include "TeamDebugModel.h" TeamDebugger::TeamDebugger() : BLooper("team debugger"), fTeam(NULL), + fDebugModel(NULL), fTeamID(-1), fDebuggerPort(-1), fNubPort(-1), @@ -29,6 +31,7 @@ TeamDebugger::TeamDebugger() fTeamWindow(NULL), fTerminating(false) { + fDebugContext.reply_port = -1; } @@ -46,6 +49,9 @@ TeamDebugger::~TeamDebugger() if (fDebugEventListener >= 0) wait_for_thread(fDebugEventListener, NULL); + destroy_debug_context(&fDebugContext); + + delete fDebugModel; delete fTeam; } @@ -72,6 +78,15 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain) fTeam->SetName(teamInfo.args); // 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 char buffer[128]; 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; int32 cookie = 0; 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) return error; + + _UpdateThreadState(thread); } image_info imageInfo; @@ -128,7 +146,7 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain) // create the team window try { - fTeamWindow = TeamWindow::Create(fTeam, this); + fTeamWindow = TeamWindow::Create(fDebugModel, this); } catch (...) { // TODO: Notify the user! 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); 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); +} diff --git a/src/apps/debugger/TeamDebugger.h b/src/apps/debugger/TeamDebugger.h index 962acb0eee..3abe214c61 100644 --- a/src/apps/debugger/TeamDebugger.h +++ b/src/apps/debugger/TeamDebugger.h @@ -15,6 +15,7 @@ class Team; +class TeamDebugModel; class TeamDebugger : public DoublyLinkedListLinkImpl, @@ -47,8 +48,11 @@ private: bool _HandleImageDeleted( const debug_image_deleted& message); + void _UpdateThreadState(::Thread* thread); + private: ::Team* fTeam; + TeamDebugModel* fDebugModel; team_id fTeamID; port_id fDebuggerPort; port_id fNubPort; diff --git a/src/apps/debugger/Thread.cpp b/src/apps/debugger/Thread.cpp index c1a112ef9e..b3c83a8140 100644 --- a/src/apps/debugger/Thread.cpp +++ b/src/apps/debugger/Thread.cpp @@ -6,9 +6,11 @@ #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; } + + +void +Thread::SetState(uint32 state) +{ + fState = state; +} diff --git a/src/apps/debugger/Thread.h b/src/apps/debugger/Thread.h index 37b1bd4fff..b0d4f9ab6a 100644 --- a/src/apps/debugger/Thread.h +++ b/src/apps/debugger/Thread.h @@ -12,22 +12,37 @@ #include +class Team; + + +enum { + THREAD_STATE_UNKNOWN, + THREAD_STATE_RUNNING, + THREAD_STATE_STOPPED +}; + + class Thread : public Referenceable, public DoublyLinkedListLinkImpl { public: - Thread(thread_id threadID); + Thread(Team* team, thread_id threadID); ~Thread(); 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(); } void SetName(const BString& name); + uint32 State() const { return fState; } + void SetState(uint32 state); private: + Team* fTeam; thread_id fID; BString fName; + uint32 fState; }; diff --git a/src/apps/debugger/gui/team_window/ImageListView.cpp b/src/apps/debugger/gui/team_window/ImageListView.cpp index 7ccd1a8af7..dc41b427d2 100644 --- a/src/apps/debugger/gui/team_window/ImageListView.cpp +++ b/src/apps/debugger/gui/team_window/ImageListView.cpp @@ -204,14 +204,14 @@ ImageListView::MessageReceived(BMessage* message) void -ImageListView::ImageAdded(Team* team, Image* image) +ImageListView::ImageAdded(const Team::ImageEvent& event) { Looper()->PostMessage(MSG_SYNC_IMAGE_LIST, this); } void -ImageListView::ImageRemoved(Team* team, Image* image) +ImageListView::ImageRemoved(const Team::ImageEvent& event) { Looper()->PostMessage(MSG_SYNC_IMAGE_LIST, this); } diff --git a/src/apps/debugger/gui/team_window/ImageListView.h b/src/apps/debugger/gui/team_window/ImageListView.h index 5b24d2a34c..341c4e03cd 100644 --- a/src/apps/debugger/gui/team_window/ImageListView.h +++ b/src/apps/debugger/gui/team_window/ImageListView.h @@ -29,8 +29,8 @@ private: private: // Team::Listener - virtual void ImageAdded(Team* team, Image* image); - virtual void ImageRemoved(Team* team, Image* image); + virtual void ImageAdded(const Team::ImageEvent& event); + virtual void ImageRemoved(const Team::ImageEvent& event); // TableListener virtual void TableRowInvoked(Table* table, int32 rowIndex); diff --git a/src/apps/debugger/gui/team_window/TeamWindow.cpp b/src/apps/debugger/gui/team_window/TeamWindow.cpp index a55f5250ae..f7574b9a79 100644 --- a/src/apps/debugger/gui/team_window/TeamWindow.cpp +++ b/src/apps/debugger/gui/team_window/TeamWindow.cpp @@ -5,6 +5,9 @@ #include "TeamWindow.h" +#include + +#include #include #include #include @@ -12,23 +15,29 @@ #include #include "ImageListView.h" -#include "Team.h" -#include "ThreadListView.h" +#include "MessageCodes.h" +#include "TeamDebugModel.h" // #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), - fTeam(team), + fDebugModel(debugModel), + fActiveThread(NULL), fListener(listener), fTabView(NULL), fThreadListView(NULL), - fImageListView(NULL) + fImageListView(NULL), + fRunButton(NULL), + fStepOverButton(NULL), + fStepIntoButton(NULL), + fStepOutButton(NULL) { + ::Team* team = debugModel->GetTeam(); BString name = team->Name(); if (team->ID() >= 0) name << " (" << team->ID() << ")"; @@ -42,9 +51,9 @@ TeamWindow::~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 { self->_Init(); @@ -61,6 +70,18 @@ void TeamWindow::MessageReceived(BMessage* message) { 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: BWindow::MessageReceived(message); break; @@ -75,6 +96,13 @@ TeamWindow::QuitRequested() } +void +TeamWindow::ThreadSelectionChanged(::Thread* thread) +{ + _SetActiveThread(thread); +} + + void TeamWindow::_Init() { @@ -84,18 +112,93 @@ TeamWindow::_Init() BLayoutBuilder::Group<>(rootLayout) .AddSplit(B_VERTICAL, 3.0f) .Add(fTabView = new BTabView("tab view"), 0.4f) - .AddSplit(B_HORIZONTAL, 3.0f) - .Add(fImageListView = ImageListView::Create()) - .Add(new BTextView("source view"), 2.0f) + .AddGroup(B_VERTICAL, 4.0f) + .AddGroup(B_HORIZONTAL, 4.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(); - - fTabView->AddTab(fThreadListView = ThreadListView::Create()); -// fTabView->AddTab(fTeamsPage = new TeamsPage(this)); -// fTabView->AddTab(fThreadsPage = new ThreadsPage(this)); - fThreadListView->SetTeam(fTeam); - fImageListView->SetTeam(fTeam); + // add threads tab + BSplitView* threadGroup = new BSplitView(B_HORIZONTAL); + threadGroup->SetName("Threads"); + fTabView->AddTab(threadGroup); + BLayoutBuilder::Split<>(threadGroup) + .Add(fThreadListView = ThreadListView::Create(this)) + .Add(new BTextView("stack frames")); + + // add images tab + 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; + } } diff --git a/src/apps/debugger/gui/team_window/TeamWindow.h b/src/apps/debugger/gui/team_window/TeamWindow.h index 2f59f928a0..265bbca9ee 100644 --- a/src/apps/debugger/gui/team_window/TeamWindow.h +++ b/src/apps/debugger/gui/team_window/TeamWindow.h @@ -8,36 +8,52 @@ #include #include +#include "ThreadListView.h" + +class BButton; class BTabView; class ImageListView; class Team; -class ThreadListView; +class TeamDebugModel; -class TeamWindow : public BWindow { +class TeamWindow : public BWindow, private ThreadListView::Listener { public: class Listener; public: - TeamWindow(::Team* team, Listener* listener); + TeamWindow(TeamDebugModel* debugModel, + Listener* listener); ~TeamWindow(); - static TeamWindow* Create(::Team* team, Listener* listener); + static TeamWindow* Create(TeamDebugModel* debugModel, + Listener* listener); // throws virtual void MessageReceived(BMessage* message); virtual bool QuitRequested(); private: + // ThreadListView::Listener + virtual void ThreadSelectionChanged(::Thread* thread); + void _Init(); + void _SetActiveThread(::Thread* thread); + void _UpdateRunButtons(); + private: - ::Team* fTeam; + TeamDebugModel* fDebugModel; + ::Thread* fActiveThread; Listener* fListener; BTabView* fTabView; ThreadListView* fThreadListView; ImageListView* fImageListView; + BButton* fRunButton; + BButton* fStepOverButton; + BButton* fStepIntoButton; + BButton* fStepOutButton; }; diff --git a/src/apps/debugger/gui/team_window/ThreadListView.cpp b/src/apps/debugger/gui/team_window/ThreadListView.cpp index 6785940118..1fce41000a 100644 --- a/src/apps/debugger/gui/team_window/ThreadListView.cpp +++ b/src/apps/debugger/gui/team_window/ThreadListView.cpp @@ -129,12 +129,13 @@ private: // #pragma mark - ThreadListView -ThreadListView::ThreadListView() +ThreadListView::ThreadListView(Listener* listener) : BGroupView(B_VERTICAL), fTeam(NULL), fThreadsTable(NULL), - fThreadsTableModel(NULL) + fThreadsTableModel(NULL), + fListener(listener) { SetName("Threads"); } @@ -149,9 +150,9 @@ ThreadListView::~ThreadListView() /*static*/ ThreadListView* -ThreadListView::Create() +ThreadListView::Create(Listener* listener) { - ThreadListView* self = new ThreadListView; + ThreadListView* self = new ThreadListView(listener); try { self->_Init(); @@ -204,19 +205,33 @@ ThreadListView::MessageReceived(BMessage* message) void -ThreadListView::ThreadAdded(Team* team, Thread* thread) +ThreadListView::ThreadAdded(const Team::ThreadEvent& event) { Looper()->PostMessage(MSG_SYNC_THREAD_LIST, this); } void -ThreadListView::ThreadRemoved(Team* team, Thread* thread) +ThreadListView::ThreadRemoved(const Team::ThreadEvent& event) { 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 ThreadListView::TableRowInvoked(Table* table, int32 rowIndex) { @@ -233,12 +248,21 @@ ThreadListView::_Init() { fThreadsTable = new Table("threads list", 0); AddChild(fThreadsTable->ToView()); - + // columns fThreadsTable->AddColumn(new Int32TableColumn(0, "ID", 40, 20, 1000, B_TRUNCATE_MIDDLE, B_ALIGN_RIGHT)); fThreadsTable->AddColumn(new StringTableColumn(1, "Name", 80, 40, 1000, B_TRUNCATE_END, B_ALIGN_LEFT)); - + + fThreadsTable->SetSelectionMode(B_SINGLE_SELECTION_LIST); fThreadsTable->AddTableListener(this); } + + +// #pragma mark - Listener + + +ThreadListView::Listener::~Listener() +{ +} diff --git a/src/apps/debugger/gui/team_window/ThreadListView.h b/src/apps/debugger/gui/team_window/ThreadListView.h index 8f3b7952b4..3d4f319006 100644 --- a/src/apps/debugger/gui/team_window/ThreadListView.h +++ b/src/apps/debugger/gui/team_window/ThreadListView.h @@ -11,13 +11,19 @@ #include "Team.h" +class Thread; + + class ThreadListView : public BGroupView, private Team::Listener, private TableListener { public: - ThreadListView(); + class Listener; + +public: + ThreadListView(Listener* listener); ~ThreadListView(); - static ThreadListView* Create(); + static ThreadListView* Create(Listener* listener); // throws void SetTeam(Team* team); @@ -29,10 +35,11 @@ private: private: // Team::Listener - virtual void ThreadAdded(Team* team, Thread* thread); - virtual void ThreadRemoved(Team* team, Thread* thread); + virtual void ThreadAdded(const Team::ThreadEvent& event); + virtual void ThreadRemoved(const Team::ThreadEvent& event); // TableListener + virtual void TableSelectionChanged(Table* table); virtual void TableRowInvoked(Table* table, int32 rowIndex); void _Init(); @@ -41,6 +48,15 @@ private: Team* fTeam; Table* fThreadsTable; ThreadsTableModel* fThreadsTableModel; + Listener* fListener; +}; + + +class ThreadListView::Listener { +public: + virtual ~Listener(); + + virtual void ThreadSelectionChanged(Thread* thread) = 0; };