* 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:
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -11,18 +11,24 @@
|
||||
#include <util/DoublyLinkedList.h>
|
||||
|
||||
|
||||
class Team;
|
||||
|
||||
|
||||
class Image : public Referenceable, public DoublyLinkedListLinkImpl<Image> {
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
@@ -20,8 +20,9 @@ Application Debugger :
|
||||
ElfFile.cpp
|
||||
|
||||
Image.cpp
|
||||
TeamDebugger.cpp
|
||||
Team.cpp
|
||||
TeamDebugger.cpp
|
||||
TeamDebugModel.cpp
|
||||
Thread.cpp
|
||||
|
||||
# DebugAnalyzer:util
|
||||
|
||||
@@ -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
@@ -7,6 +7,8 @@
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <AutoLocker.h>
|
||||
|
||||
|
||||
// #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<Team> locker(this);
|
||||
fListeners.Add(listener);
|
||||
}
|
||||
|
||||
@@ -204,6 +207,7 @@ Team::AddListener(Listener* listener)
|
||||
void
|
||||
Team::RemoveListener(Listener* listener)
|
||||
{
|
||||
AutoLocker<Team> 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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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<Team::Listener> {
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
|
||||
class Team;
|
||||
class TeamDebugModel;
|
||||
|
||||
|
||||
class TeamDebugger : public DoublyLinkedListLinkImpl<TeamDebugger>,
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -12,22 +12,37 @@
|
||||
#include <util/DoublyLinkedList.h>
|
||||
|
||||
|
||||
class Team;
|
||||
|
||||
|
||||
enum {
|
||||
THREAD_STATE_UNKNOWN,
|
||||
THREAD_STATE_RUNNING,
|
||||
THREAD_STATE_STOPPED
|
||||
};
|
||||
|
||||
|
||||
class Thread : public Referenceable, public DoublyLinkedListLinkImpl<Thread> {
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
|
||||
#include "TeamWindow.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Button.h>
|
||||
#include <LayoutBuilder.h>
|
||||
#include <Message.h>
|
||||
#include <TabView.h>
|
||||
@@ -12,23 +15,29 @@
|
||||
#include <TextView.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -8,36 +8,52 @@
|
||||
#include <String.h>
|
||||
#include <Window.h>
|
||||
|
||||
#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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user