Debugger: Refactor TeamsWindow to use TargetHostInterface.

TeamsWindow:
- On startup, instantiate a LocalTargetHostInterface, and pass it
  to the TeamsListView.

TeamsListView:
- Refactor building and updating the teams list to work via TargetHost
  and its respective listener interface rather than the previous combination
  of be_roster and manual polling.
- Style fixes.
This commit is contained in:
Rene Gollent 2016-04-04 22:03:43 -04:00
parent 475ea59b5f
commit 8c7bdb72ae
4 changed files with 134 additions and 151 deletions

View File

@ -4,6 +4,8 @@
* Distributed under the terms of the MIT License.
*/
#include "TeamsListView.h"
#include <algorithm>
#include <new>
@ -21,11 +23,15 @@
#include <Roster.h>
#include <String.h>
#include "TeamsListView.h"
#include <AutoLocker.h>
#include "TargetHostInterface.h"
enum {
MSG_UPDATE_TEAMS_LIST = 'uptl'
MSG_TEAM_ADDED = 'tead',
MSG_TEAM_REMOVED = 'tere',
MSG_TEAM_RENAMED = 'tern'
};
@ -186,35 +192,24 @@ TeamsColumn::InitTextMargin(BView* parent)
enum {
kNameColumn,
kIDColumn,
kThreadCountColumn,
kIDColumn
};
TeamRow::TeamRow(team_info& info)
TeamRow::TeamRow(TeamInfo* info)
: BRow(std::max(20.0f, ceilf(be_plain_font->Size() * 1.4)))
{
_SetTo(info);
}
TeamRow::TeamRow(team_id team)
: BRow(std::max(20.0f, ceilf(be_plain_font->Size() * 1.4)))
{
team_info info;
get_team_info(team, &info);
_SetTo(info);
}
bool
TeamRow::NeedsUpdate(team_info& info)
TeamRow::NeedsUpdate(TeamInfo* info)
{
// Check if we need to rebuilt the row's fields because the team critical
// info (basically, app image running under that team ID) has changed
if (info.argc != fTeamInfo.argc
|| strncmp(info.args, fTeamInfo.args, sizeof(fTeamInfo.args)) != 0) {
if (info->Arguments() != fTeamInfo.Arguments()) {
_SetTo(info);
return true;
}
@ -224,22 +219,17 @@ TeamRow::NeedsUpdate(team_info& info)
status_t
TeamRow::_SetTo(team_info& info)
TeamRow::_SetTo(TeamInfo* info)
{
team_info teamInfo = fTeamInfo = info;
// strip any trailing space(s)...
for (int len = strlen(teamInfo.args) - 1;
len >= 0 && teamInfo.args[len] == ' '; len--) {
teamInfo.args[len] = 0;
}
fTeamInfo = *info;
app_info appInfo;
status_t status = be_roster->GetRunningAppInfo(teamInfo.team, &appInfo);
status_t status = be_roster->GetRunningAppInfo(fTeamInfo.TeamID(),
&appInfo);
if (status != B_OK) {
// Not an application known to be_roster
if (teamInfo.team == B_SYSTEM_TEAM) {
if (fTeamInfo.TeamID() == B_SYSTEM_TEAM) {
// Get icon and name from kernel image
system_info systemInfo;
get_system_info(&systemInfo);
@ -251,10 +241,11 @@ TeamRow::_SetTo(team_info& info)
get_ref_for_path(kernelPath.Path(), &appInfo.ref);
} else
BPrivate::get_app_ref(teamInfo.team, &appInfo.ref);
BPrivate::get_app_ref(fTeamInfo.TeamID(), &appInfo.ref);
}
BBitmap* icon = new BBitmap(BRect(0, 0, B_MINI_ICON - 1, B_MINI_ICON - 1), B_RGBA32);
BBitmap* icon = new BBitmap(BRect(0, 0, B_MINI_ICON - 1, B_MINI_ICON - 1),
B_RGBA32);
status = BNodeInfo::GetTrackerIcon(&appInfo.ref, icon, B_MINI_ICON);
if (status != B_OK) {
@ -268,16 +259,11 @@ TeamRow::_SetTo(team_info& info)
}
BString tmp;
tmp << teamInfo.team;
tmp << fTeamInfo.TeamID();
SetField(new BBitmapStringField(icon, teamInfo.args), kNameColumn);
SetField(new BBitmapStringField(icon, fTeamInfo.Arguments()), kNameColumn);
SetField(new BStringField(tmp), kIDColumn);
tmp = "";
tmp << teamInfo.thread_count;
SetField(new BStringField(tmp), kThreadCountColumn);
return status;
}
@ -285,34 +271,26 @@ TeamRow::_SetTo(team_info& info)
// #pragma mark - TeamsListView
TeamsListView::TeamsListView(const char* name, team_id currentTeam)
TeamsListView::TeamsListView(const char* name, team_id currentTeam,
TargetHostInterface* interface)
:
Inherited(name, B_NAVIGABLE, B_PLAIN_BORDER),
fUpdateRunner(NULL),
fCurrentTeam(currentTeam)
TargetHost::Listener(),
fCurrentTeam(currentTeam),
fInterface(interface)
{
fInterface->AcquireReference();
AddColumn(new TeamsColumn("Name", 400, 100, 600,
B_TRUNCATE_BEGINNING), kNameColumn);
AddColumn(new TeamsColumn("ID", 80, 40, 100,
B_TRUNCATE_MIDDLE, B_ALIGN_RIGHT), kIDColumn);
/*
AddColumn(new TeamsColumn("Thread count", 100, 50, 500,
B_TRUNCATE_MIDDLE, B_ALIGN_RIGHT), kThreadCountColumn);
*/
SetSortingEnabled(false);
/*
#ifdef __HAIKU__
SetFlags(Flags() | B_SUBPIXEL_PRECISE);
#endif
*/
}
TeamsListView::~TeamsListView()
{
delete fUpdateRunner;
fInterface->ReleaseReference();
}
@ -322,12 +300,9 @@ TeamsListView::AttachedToWindow()
Inherited::AttachedToWindow();
TeamsColumn::InitTextMargin(ScrollView());
fInterface->GetTargetHost()->AddListener(this);
_InitList();
be_roster->StartWatching(this, B_REQUEST_LAUNCHED | B_REQUEST_QUIT);
BMessage msg(MSG_UPDATE_TEAMS_LIST);
fUpdateRunner = new BMessageRunner(this, &msg, 100000L); // 10Hz
}
@ -336,12 +311,9 @@ TeamsListView::DetachedFromWindow()
{
Inherited::DetachedFromWindow();
be_roster->StopWatching(this);
fInterface->GetTargetHost()->RemoveListener(this);
delete fUpdateRunner;
fUpdateRunner = NULL;
Clear(); // MakeEmpty();
Clear();
}
@ -349,30 +321,28 @@ void
TeamsListView::MessageReceived(BMessage* message)
{
switch (message->what) {
case MSG_UPDATE_TEAMS_LIST:
_UpdateList();
break;
case B_SOME_APP_LAUNCHED:
case MSG_TEAM_ADDED:
{
team_id team;
if (message->FindInt32("be:team", &team) != B_OK)
TeamInfo* info;
team_id team;
if (message->FindInt32("team", &team) != B_OK)
break;
TeamRow* row = new(std::nothrow) TeamRow(team);
if (row != NULL) {
AddRow(row);
/*else
SortItems(&TeamListItem::Compare);
*/
}
TargetHost* host = fInterface->GetTargetHost();
AutoLocker<TargetHost> hostLocker(host);
info = host->TeamInfoByID(team);
if (info == NULL)
break;
TeamRow* row = new TeamRow(info);
AddRow(row);
break;
}
case B_SOME_APP_QUIT:
case MSG_TEAM_REMOVED:
{
team_id team;
if (message->FindInt32("be:team", &team) != B_OK)
team_id team;
if (message->FindInt32("team", &team) != B_OK)
break;
TeamRow* row = FindTeamRow(team);
@ -383,6 +353,26 @@ TeamsListView::MessageReceived(BMessage* message)
break;
}
case MSG_TEAM_RENAMED:
{
TeamInfo* info;
team_id team;
if (message->FindInt32("team", &team) != B_OK)
break;
TargetHost* host = fInterface->GetTargetHost();
AutoLocker<TargetHost> hostLocker(host);
info = host->TeamInfoByID(team);
if (info == NULL)
break;
TeamRow* row = FindTeamRow(info->TeamID());
if (row != NULL && row->NeedsUpdate(info))
UpdateRow(row);
break;
}
default:
Inherited::MessageReceived(message);
}
@ -406,69 +396,40 @@ TeamsListView::FindTeamRow(team_id teamId)
void
TeamsListView::_InitList()
TeamsListView::TeamAdded(TeamInfo* info)
{
int32 tmi_cookie = 0;
team_info tmi;
while (get_next_team_info(&tmi_cookie, &tmi) == B_OK) {
TeamRow* row = new(std::nothrow) TeamRow(tmi);
if (row == NULL) {
// Memory issue. Bail out.
break;
}
if (tmi.team == B_SYSTEM_TEAM ||
tmi.team == fCurrentTeam) {
// We don't support debugging kernel and... ourself!
row->SetEnabled(false);
}
AddRow(row);
}
BMessage message(MSG_TEAM_ADDED);
message.AddInt32("team", info->TeamID());
BMessenger(this).SendMessage(&message);
}
void
TeamsListView::_UpdateList()
TeamsListView::TeamRemoved(team_id team)
{
int32 tmi_cookie = 0;
team_info tmi;
TeamRow* row;
int32 index = 0;
BMessage message(MSG_TEAM_REMOVED);
message.AddInt32("team", team);
BMessenger(this).SendMessage(&message);
}
// NOTA: assuming get_next_team_info() returns teams ordered by team ID...
while (get_next_team_info(&tmi_cookie, &tmi) == B_OK) {
row = dynamic_cast<TeamRow*>(RowAt(index));
while (row && tmi.team > row->TeamID()) {
RemoveRow(row);
delete row;
row = dynamic_cast<TeamRow*>(RowAt(index));
}
void
TeamsListView::TeamRenamed(TeamInfo* info)
{
BMessage message(MSG_TEAM_RENAMED);
message.AddInt32("team", info->TeamID());
BMessenger(this).SendMessage(&message);
}
if (row != NULL && tmi.team == row->TeamID()
&& row->NeedsUpdate(tmi)) {
// The team image app could have change due after an exec*() call,
UpdateRow(row);
} else if (row == NULL || tmi.team != row->TeamID()) {
// Team not found in previously known teams list: insert a new row
TeamRow* newRow = new(std::nothrow) TeamRow(tmi);
if (newRow != NULL) {
if (row == NULL) {
// No row found with bigger team id: append at list end
AddRow(newRow);
} else
AddRow(newRow, index);
}
}
index++; // Move list sync head.
}
// Remove tail list rows, if we don't walk list thru the end
while ((row = dynamic_cast<TeamRow*>(RowAt(index))) != NULL) {
RemoveRow(row);
delete row;
row = dynamic_cast<TeamRow*>(RowAt(++index));
void
TeamsListView::_InitList()
{
TargetHost* host = fInterface->GetTargetHost();
AutoLocker<TargetHost> hostLocker(host);
for (int32 i = 0; i < host->CountTeams(); i++) {
TeamInfo* info = host->TeamInfoAt(i);
BRow* row = new TeamRow(info);
AddRow(row);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2009-2013 Haiku Inc. All rights reserved.
* Copyright 2009-2016, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT license.
*
* Authors:
@ -9,13 +9,16 @@
#ifndef TEAMS_LIST_ITEM_H
#define TEAMS_LIST_ITEM_H
#include <ColumnListView.h>
#include <ColumnTypes.h>
#include <OS.h>
#include "TargetHost.h"
#include "TeamInfo.h"
class BBitmap;
class BMessageRunner;
class TargetHostInterface;
// A field type displaying both a bitmap and a string so that the
@ -64,35 +67,43 @@ private:
class TeamRow : public BRow {
typedef BRow Inherited;
public:
TeamRow(team_info& teamInfo);
TeamRow(team_id teamId);
TeamRow(TeamInfo* teamInfo);
public:
team_id TeamID() const { return fTeamInfo.team; }
team_id TeamID() const
{ return fTeamInfo.TeamID(); }
bool NeedsUpdate(team_info& info);
bool NeedsUpdate(TeamInfo* info);
virtual void SetEnabled(bool enabled) { fEnabled = enabled; }
bool IsEnabled() const { return fEnabled; }
virtual void SetEnabled(bool enabled)
{ fEnabled = enabled; }
bool IsEnabled() const
{ return fEnabled; }
private:
status_t _SetTo(team_info& info);
status_t _SetTo(TeamInfo* info);
private:
bool fEnabled;
team_info fTeamInfo;
TeamInfo fTeamInfo;
};
class TeamsListView : public BColumnListView {
class TeamsListView : public BColumnListView, public TargetHost::Listener {
typedef BColumnListView Inherited;
public:
TeamsListView(const char* name,
team_id currentTeam);
team_id currentTeam,
TargetHostInterface* interface);
virtual ~TeamsListView();
TeamRow* FindTeamRow(team_id teamId);
// TargetHost::Listener
virtual void TeamAdded(TeamInfo* info);
virtual void TeamRemoved(team_id team);
virtual void TeamRenamed(TeamInfo* info);
protected:
virtual void AttachedToWindow();
virtual void DetachedFromWindow();
@ -101,11 +112,10 @@ protected:
private:
void _InitList();
void _UpdateList();
private:
BMessageRunner* fUpdateRunner;
team_id fCurrentTeam;
TargetHostInterface* fInterface;
};

View File

@ -1,8 +1,9 @@
/*
* Copyright 2009-2010, Philippe Houdoin, phoudoin@haiku-os.org. All rights reserved.
* Copyright 2013, Rene Gollent, rene@gollent.com.
* Copyright 2013-2016, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#include "TeamsWindow.h"
#include <new>
@ -23,7 +24,7 @@
#include "MessageCodes.h"
#include "SettingsManager.h"
#include "TeamsWindow.h"
#include "LocalTargetHostInterface.h"
#include "TeamsListView.h"
@ -36,6 +37,7 @@ TeamsWindow::TeamsWindow(SettingsManager* settingsManager)
:
BWindow(BRect(100, 100, 500, 250), "Teams", B_DOCUMENT_WINDOW,
B_ASYNCHRONOUS_CONTROLS),
fTargetHostInterface(NULL),
fTeamsListView(NULL),
fAttachTeamButton(NULL),
fCreateTeamButton(NULL),
@ -49,6 +51,8 @@ TeamsWindow::TeamsWindow(SettingsManager* settingsManager)
TeamsWindow::~TeamsWindow()
{
if (fTargetHostInterface != NULL)
fTargetHostInterface->ReleaseReference();
}
@ -142,6 +146,11 @@ TeamsWindow::_Init()
BMessage settings;
_LoadSettings(settings);
fTargetHostInterface = new LocalTargetHostInterface();
if (fTargetHostInterface->Init() != B_OK)
throw std::bad_alloc();
BRect frame;
if (settings.FindRect("teams window frame", &frame) == B_OK) {
MoveTo(frame.LeftTop());
@ -149,7 +158,8 @@ TeamsWindow::_Init()
}
BLayoutBuilder::Group<>(this, B_VERTICAL)
.Add(fTeamsListView = new TeamsListView("TeamsList", fCurrentTeam))
.Add(fTeamsListView = new TeamsListView("TeamsList", fCurrentTeam,
fTargetHostInterface))
.SetInsets(1.0f, 1.0f, 1.0f, 1.0f)
.AddGroup(B_HORIZONTAL)
.SetInsets(B_USE_DEFAULT_SPACING)

View File

@ -1,6 +1,6 @@
/*
* Copyright 2009-2010, Philippe Houdoin, phoudoin@haiku-os.org. All rights reserved.
* Copyright 2013, Rene Gollent, rene@gollent.com.
* Copyright 2016, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#ifndef TEAMS_WINDOW_H
@ -14,6 +14,7 @@ class BListView;
class BFile;
class BMessage;
class SettingsManager;
class TargetHostInterface;
class TeamsListView;
class TeamsWindow : public BWindow {
@ -36,6 +37,7 @@ private:
private:
team_id fCurrentTeam;
TargetHostInterface* fTargetHostInterface;
TeamsListView* fTeamsListView;
BButton* fAttachTeamButton;
BButton* fCreateTeamButton;