* 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"
|
#include "Image.h"
|
||||||
|
|
||||||
|
|
||||||
Image::Image(const image_info& imageInfo)
|
Image::Image(Team* team,const image_info& imageInfo)
|
||||||
:
|
:
|
||||||
|
fTeam(team),
|
||||||
fInfo(imageInfo)
|
fInfo(imageInfo)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 <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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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 "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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user