* Moved the ThreadWindow::WaitObjectPage implementation to new class
AbstractWaitObjectsPage and templatized it over model, wait object group, and wait object type. * Replaced the previous MainWindow::WaitObjectPage implementation using AbstractWaitObjectsPage. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34640 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,339 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef ABSTRACT_WAIT_OBJECTS_PAGE_H
|
||||||
|
#define ABSTRACT_WAIT_OBJECTS_PAGE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
#include <GroupView.h>
|
||||||
|
|
||||||
|
#include "table/TableColumns.h"
|
||||||
|
#include "table/TreeTable.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define ABSTRACT_WAIT_OBJECTS_PAGE_TEMPLATE \
|
||||||
|
template<typename ModelType, typename WaitObjectGroupType, \
|
||||||
|
typename WaitObjectType>
|
||||||
|
#define ABSTRACT_WAIT_OBJECTS_PAGE_CLASS \
|
||||||
|
AbstractWaitObjectsPage<ModelType, WaitObjectGroupType, WaitObjectType>
|
||||||
|
|
||||||
|
|
||||||
|
ABSTRACT_WAIT_OBJECTS_PAGE_TEMPLATE
|
||||||
|
class AbstractWaitObjectsPage : public BGroupView, protected TreeTableListener {
|
||||||
|
public:
|
||||||
|
AbstractWaitObjectsPage();
|
||||||
|
virtual ~AbstractWaitObjectsPage();
|
||||||
|
|
||||||
|
void SetModel(ModelType* model);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
class WaitObjectsTreeModel;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
TreeTable* fWaitObjectsTree;
|
||||||
|
WaitObjectsTreeModel* fWaitObjectsTreeModel;
|
||||||
|
ModelType* fModel;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - WaitObjectsTreeModel
|
||||||
|
|
||||||
|
|
||||||
|
ABSTRACT_WAIT_OBJECTS_PAGE_TEMPLATE
|
||||||
|
class ABSTRACT_WAIT_OBJECTS_PAGE_CLASS::WaitObjectsTreeModel
|
||||||
|
: public TreeTableModel {
|
||||||
|
public:
|
||||||
|
WaitObjectsTreeModel(ModelType* model)
|
||||||
|
:
|
||||||
|
fModel(model),
|
||||||
|
fRootNode(NULL)
|
||||||
|
{
|
||||||
|
fRootNode = new RootNode(fModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
~WaitObjectsTreeModel()
|
||||||
|
{
|
||||||
|
delete fRootNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void* Root() const
|
||||||
|
{
|
||||||
|
return fRootNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int32 CountChildren(void* parent) const
|
||||||
|
{
|
||||||
|
return ((Node*)parent)->CountChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void* ChildAt(void* parent, int32 index) const
|
||||||
|
{
|
||||||
|
return ((Node*)parent)->ChildAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int32 CountColumns() const
|
||||||
|
{
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool GetValueAt(void* object, int32 columnIndex, BVariant& value)
|
||||||
|
{
|
||||||
|
return ((Node*)object)->GetValueAt(columnIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Node {
|
||||||
|
virtual ~Node() {}
|
||||||
|
|
||||||
|
virtual int32 CountChildren() const = 0;
|
||||||
|
virtual void* ChildAt(int32 index) const = 0;
|
||||||
|
virtual bool GetValueAt(int32 columnIndex, BVariant& value) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ObjectNode : Node {
|
||||||
|
WaitObjectType* object;
|
||||||
|
|
||||||
|
ObjectNode(WaitObjectType* object)
|
||||||
|
:
|
||||||
|
object(object)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int32 CountChildren() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void* ChildAt(int32 index) const
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool GetValueAt(int32 columnIndex, BVariant& value)
|
||||||
|
{
|
||||||
|
return _GetWaitObjectValueAt(object, columnIndex, value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// For GCC 2
|
||||||
|
friend struct ObjectNode;
|
||||||
|
|
||||||
|
struct GroupNode : Node {
|
||||||
|
WaitObjectGroupType* group;
|
||||||
|
BObjectList<ObjectNode> objectNodes;
|
||||||
|
|
||||||
|
GroupNode(WaitObjectGroupType* group)
|
||||||
|
:
|
||||||
|
group(group)
|
||||||
|
{
|
||||||
|
int32 count = group->CountWaitObjects();
|
||||||
|
for (int32 i = 0; i < count; i++) {
|
||||||
|
WaitObjectType* waitObject = group->WaitObjectAt(i);
|
||||||
|
if (!objectNodes.AddItem(new ObjectNode(waitObject)))
|
||||||
|
throw std::bad_alloc();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int32 CountChildren() const
|
||||||
|
{
|
||||||
|
return objectNodes.CountItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void* ChildAt(int32 index) const
|
||||||
|
{
|
||||||
|
return objectNodes.ItemAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool GetValueAt(int32 columnIndex, BVariant& value)
|
||||||
|
{
|
||||||
|
if (columnIndex <= 2) {
|
||||||
|
return _GetWaitObjectValueAt(group->WaitObjectAt(0),
|
||||||
|
columnIndex, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (columnIndex) {
|
||||||
|
case 4:
|
||||||
|
value.SetTo(group->Waits());
|
||||||
|
return true;
|
||||||
|
case 5:
|
||||||
|
value.SetTo(group->TotalWaitTime());
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// For GCC 2
|
||||||
|
friend struct GroupNode;
|
||||||
|
|
||||||
|
struct RootNode : Node {
|
||||||
|
ModelType* model;
|
||||||
|
BObjectList<Node> groupNodes;
|
||||||
|
|
||||||
|
RootNode(ModelType* model)
|
||||||
|
:
|
||||||
|
model(model),
|
||||||
|
groupNodes(20, true)
|
||||||
|
{
|
||||||
|
int32 count = model->CountWaitObjectGroups();
|
||||||
|
for (int32 i = 0; i < count; i++) {
|
||||||
|
WaitObjectGroupType* group = model->WaitObjectGroupAt(i);
|
||||||
|
if (!groupNodes.AddItem(_CreateGroupNode(group)))
|
||||||
|
throw std::bad_alloc();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int32 CountChildren() const
|
||||||
|
{
|
||||||
|
return groupNodes.CountItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void* ChildAt(int32 index) const
|
||||||
|
{
|
||||||
|
return groupNodes.ItemAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool GetValueAt(int32 columnIndex, BVariant& value)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Node* _CreateGroupNode(WaitObjectGroupType* group)
|
||||||
|
{
|
||||||
|
// If the group has only one object, just create an object node.
|
||||||
|
if (group->CountWaitObjects() == 1)
|
||||||
|
return new ObjectNode(group->WaitObjectAt(0));
|
||||||
|
|
||||||
|
return new GroupNode(group);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _GetWaitObjectValueAt(WaitObjectType* waitObject,
|
||||||
|
int32 columnIndex, BVariant& value)
|
||||||
|
{
|
||||||
|
switch (columnIndex) {
|
||||||
|
case 0:
|
||||||
|
value.SetTo(wait_object_type_name(waitObject->Type()),
|
||||||
|
B_VARIANT_DONT_COPY_DATA);
|
||||||
|
return true;
|
||||||
|
case 1:
|
||||||
|
value.SetTo(waitObject->Name(), B_VARIANT_DONT_COPY_DATA);
|
||||||
|
return true;
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
if (waitObject->Object() == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
char buffer[16];
|
||||||
|
snprintf(buffer, sizeof(buffer), "%#lx",
|
||||||
|
waitObject->Object());
|
||||||
|
value.SetTo(buffer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
if (waitObject->ReferencedObject() == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
char buffer[16];
|
||||||
|
snprintf(buffer, sizeof(buffer), "%#lx",
|
||||||
|
waitObject->ReferencedObject());
|
||||||
|
value.SetTo(buffer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
value.SetTo(waitObject->Waits());
|
||||||
|
return true;
|
||||||
|
case 5:
|
||||||
|
value.SetTo(waitObject->TotalWaitTime());
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ModelType* fModel;
|
||||||
|
RootNode* fRootNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - WaitObjectsPage
|
||||||
|
|
||||||
|
|
||||||
|
ABSTRACT_WAIT_OBJECTS_PAGE_TEMPLATE
|
||||||
|
ABSTRACT_WAIT_OBJECTS_PAGE_CLASS::AbstractWaitObjectsPage()
|
||||||
|
:
|
||||||
|
BGroupView(B_VERTICAL),
|
||||||
|
fWaitObjectsTree(NULL),
|
||||||
|
fWaitObjectsTreeModel(NULL),
|
||||||
|
fModel(NULL)
|
||||||
|
|
||||||
|
{
|
||||||
|
SetName("Wait Objects");
|
||||||
|
|
||||||
|
fWaitObjectsTree = new TreeTable("wait object list", 0);
|
||||||
|
AddChild(fWaitObjectsTree->ToView());
|
||||||
|
|
||||||
|
fWaitObjectsTree->AddColumn(new StringTableColumn(0, "Type", 80, 40, 1000,
|
||||||
|
B_TRUNCATE_END, B_ALIGN_LEFT));
|
||||||
|
fWaitObjectsTree->AddColumn(new StringTableColumn(1, "Name", 80, 40, 1000,
|
||||||
|
B_TRUNCATE_END, B_ALIGN_LEFT));
|
||||||
|
fWaitObjectsTree->AddColumn(new StringTableColumn(2, "Object", 80, 40, 1000,
|
||||||
|
B_TRUNCATE_END, B_ALIGN_LEFT));
|
||||||
|
fWaitObjectsTree->AddColumn(new StringTableColumn(3, "Referenced", 80, 40,
|
||||||
|
1000, B_TRUNCATE_END, B_ALIGN_LEFT));
|
||||||
|
fWaitObjectsTree->AddColumn(new Int64TableColumn(4, "Waits", 80, 20,
|
||||||
|
1000, B_TRUNCATE_END, B_ALIGN_RIGHT));
|
||||||
|
fWaitObjectsTree->AddColumn(new NanotimeTableColumn(5, "Wait Time", 80,
|
||||||
|
20, 1000, false, B_TRUNCATE_END, B_ALIGN_RIGHT));
|
||||||
|
|
||||||
|
fWaitObjectsTree->AddTreeTableListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ABSTRACT_WAIT_OBJECTS_PAGE_TEMPLATE
|
||||||
|
ABSTRACT_WAIT_OBJECTS_PAGE_CLASS::~AbstractWaitObjectsPage()
|
||||||
|
{
|
||||||
|
fWaitObjectsTree->SetTreeTableModel(NULL);
|
||||||
|
delete fWaitObjectsTreeModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ABSTRACT_WAIT_OBJECTS_PAGE_TEMPLATE
|
||||||
|
void
|
||||||
|
ABSTRACT_WAIT_OBJECTS_PAGE_CLASS::SetModel(ModelType* model)
|
||||||
|
{
|
||||||
|
if (model == fModel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fModel != NULL) {
|
||||||
|
fWaitObjectsTree->SetTreeTableModel(NULL);
|
||||||
|
delete fWaitObjectsTreeModel;
|
||||||
|
fWaitObjectsTreeModel = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fModel = model;
|
||||||
|
|
||||||
|
if (fModel != NULL) {
|
||||||
|
try {
|
||||||
|
fWaitObjectsTreeModel = new WaitObjectsTreeModel(fModel);
|
||||||
|
} catch (std::bad_alloc) {
|
||||||
|
// TODO: Report error!
|
||||||
|
}
|
||||||
|
fWaitObjectsTree->SetTreeTableModel(fWaitObjectsTreeModel);
|
||||||
|
fWaitObjectsTree->ResizeAllColumnsToPreferred();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // ABSTRACT_WAIT_OBJECTS_PAGE_H
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009, Axel Dörfler, [email protected].
|
|
||||||
* Copyright 2009, Ingo Weinhold, [email protected].
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
@@ -7,122 +6,9 @@
|
|||||||
|
|
||||||
#include "main_window/WaitObjectsPage.h"
|
#include "main_window/WaitObjectsPage.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#include <thread_defs.h>
|
|
||||||
|
|
||||||
#include "table/TableColumns.h"
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - WaitObjectsTableModel
|
|
||||||
|
|
||||||
|
|
||||||
class MainWindow::WaitObjectsPage::WaitObjectsTableModel : public TableModel {
|
|
||||||
public:
|
|
||||||
WaitObjectsTableModel(Model* model)
|
|
||||||
:
|
|
||||||
fModel(model)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual int32 CountColumns() const
|
|
||||||
{
|
|
||||||
return 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual int32 CountRows() const
|
|
||||||
{
|
|
||||||
return fModel->CountWaitObjectGroups();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool GetValueAt(int32 rowIndex, int32 columnIndex, BVariant& value)
|
|
||||||
{
|
|
||||||
Model::WaitObjectGroup* group = fModel->WaitObjectGroupAt(rowIndex);
|
|
||||||
if (group == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
switch (columnIndex) {
|
|
||||||
case 0:
|
|
||||||
value.SetTo(wait_object_type_name(group->Type()),
|
|
||||||
B_VARIANT_DONT_COPY_DATA);
|
|
||||||
return true;
|
|
||||||
case 1:
|
|
||||||
value.SetTo(group->Name(), B_VARIANT_DONT_COPY_DATA);
|
|
||||||
return true;
|
|
||||||
case 4:
|
|
||||||
value.SetTo(group->Waits());
|
|
||||||
return true;
|
|
||||||
case 5:
|
|
||||||
value.SetTo(group->TotalWaitTime());
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Model* fModel;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - WaitObjectsPage
|
|
||||||
|
|
||||||
|
|
||||||
MainWindow::WaitObjectsPage::WaitObjectsPage(MainWindow* parent)
|
MainWindow::WaitObjectsPage::WaitObjectsPage(MainWindow* parent)
|
||||||
:
|
:
|
||||||
BGroupView(B_VERTICAL),
|
fParent(parent)
|
||||||
fParent(parent),
|
|
||||||
fWaitObjectsTable(NULL),
|
|
||||||
fWaitObjectsTableModel(NULL),
|
|
||||||
fModel(NULL)
|
|
||||||
{
|
{
|
||||||
SetName("WaitObjects");
|
|
||||||
|
|
||||||
fWaitObjectsTable = new Table("waiting objects list", 0);
|
|
||||||
AddChild(fWaitObjectsTable->ToView());
|
|
||||||
|
|
||||||
fWaitObjectsTable->AddColumn(new StringTableColumn(0, "Type", 80, 40, 1000,
|
|
||||||
B_TRUNCATE_END, B_ALIGN_LEFT));
|
|
||||||
fWaitObjectsTable->AddColumn(new StringTableColumn(1, "Name", 80, 40, 1000,
|
|
||||||
B_TRUNCATE_END, B_ALIGN_LEFT));
|
|
||||||
// fWaitObjectsTable->AddColumn(new StringTableColumn(2, "Object", 80, 40, 1000,
|
|
||||||
// B_TRUNCATE_END, B_ALIGN_LEFT));
|
|
||||||
// fWaitObjectsTable->AddColumn(new StringTableColumn(3, "Referenced", 80, 40,
|
|
||||||
// 1000, B_TRUNCATE_END, B_ALIGN_LEFT));
|
|
||||||
fWaitObjectsTable->AddColumn(new Int64TableColumn(4, "Waits", 80, 40,
|
|
||||||
1000, B_TRUNCATE_END, B_ALIGN_RIGHT));
|
|
||||||
fWaitObjectsTable->AddColumn(new NanotimeTableColumn(5, "Wait Time", 80,
|
|
||||||
40, 1000, false, B_TRUNCATE_END, B_ALIGN_RIGHT));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MainWindow::WaitObjectsPage::~WaitObjectsPage()
|
|
||||||
{
|
|
||||||
fWaitObjectsTable->SetTableModel(NULL);
|
|
||||||
delete fWaitObjectsTableModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
MainWindow::WaitObjectsPage::SetModel(Model* model)
|
|
||||||
{
|
|
||||||
if (model == fModel)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (fModel != NULL) {
|
|
||||||
fWaitObjectsTable->SetTableModel(NULL);
|
|
||||||
delete fWaitObjectsTableModel;
|
|
||||||
fWaitObjectsTableModel = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
fModel = model;
|
|
||||||
|
|
||||||
if (fModel != NULL) {
|
|
||||||
fWaitObjectsTableModel
|
|
||||||
= new(std::nothrow) WaitObjectsTableModel(fModel);
|
|
||||||
fWaitObjectsTable->SetTableModel(fWaitObjectsTableModel);
|
|
||||||
fWaitObjectsTable->ResizeAllColumnsToPreferred();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,27 +7,19 @@
|
|||||||
#define MAIN_WAIT_OBJECTS_PAGE_H
|
#define MAIN_WAIT_OBJECTS_PAGE_H
|
||||||
|
|
||||||
|
|
||||||
#include <GroupView.h>
|
#include "AbstractWaitObjectsPage.h"
|
||||||
|
#include "Model.h"
|
||||||
#include "table/Table.h"
|
|
||||||
|
|
||||||
#include "main_window/MainWindow.h"
|
#include "main_window/MainWindow.h"
|
||||||
|
|
||||||
|
|
||||||
class MainWindow::WaitObjectsPage : public BGroupView {
|
class MainWindow::WaitObjectsPage
|
||||||
|
: public AbstractWaitObjectsPage<Model, Model::WaitObjectGroup,
|
||||||
|
Model::WaitObject> {
|
||||||
public:
|
public:
|
||||||
WaitObjectsPage(MainWindow* parent);
|
WaitObjectsPage(MainWindow* parent);
|
||||||
virtual ~WaitObjectsPage();
|
|
||||||
|
|
||||||
void SetModel(Model* model);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class WaitObjectsTableModel;
|
|
||||||
|
|
||||||
MainWindow* fParent;
|
MainWindow* fParent;
|
||||||
Table* fWaitObjectsTable;
|
|
||||||
WaitObjectsTableModel* fWaitObjectsTableModel;
|
|
||||||
Model* fModel;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,314 +6,7 @@
|
|||||||
|
|
||||||
#include "thread_window/WaitObjectsPage.h"
|
#include "thread_window/WaitObjectsPage.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#include <thread_defs.h>
|
|
||||||
|
|
||||||
#include "ThreadModel.h"
|
|
||||||
|
|
||||||
#include "table/TableColumns.h"
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - WaitObjectsTreeModel
|
|
||||||
|
|
||||||
|
|
||||||
class ThreadWindow::WaitObjectsPage::WaitObjectsTreeModel
|
|
||||||
: public TreeTableModel {
|
|
||||||
public:
|
|
||||||
WaitObjectsTreeModel(ThreadModel* model)
|
|
||||||
:
|
|
||||||
fThreadModel(model),
|
|
||||||
fRootNode(NULL)
|
|
||||||
{
|
|
||||||
fRootNode = new RootNode(fThreadModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
~WaitObjectsTreeModel()
|
|
||||||
{
|
|
||||||
delete fRootNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void* Root() const
|
|
||||||
{
|
|
||||||
return fRootNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual int32 CountChildren(void* parent) const
|
|
||||||
{
|
|
||||||
return ((Node*)parent)->CountChildren();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void* ChildAt(void* parent, int32 index) const
|
|
||||||
{
|
|
||||||
return ((Node*)parent)->ChildAt(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual int32 CountColumns() const
|
|
||||||
{
|
|
||||||
return 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool GetValueAt(void* object, int32 columnIndex, BVariant& value)
|
|
||||||
{
|
|
||||||
return ((Node*)object)->GetValueAt(columnIndex, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct Node {
|
|
||||||
virtual ~Node() {}
|
|
||||||
|
|
||||||
virtual int32 CountChildren() const = 0;
|
|
||||||
virtual void* ChildAt(int32 index) const = 0;
|
|
||||||
virtual bool GetValueAt(int32 columnIndex, BVariant& value) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ObjectNode : Node {
|
|
||||||
Model::ThreadWaitObject* object;
|
|
||||||
|
|
||||||
ObjectNode(Model::ThreadWaitObject* object)
|
|
||||||
:
|
|
||||||
object(object)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual int32 CountChildren() const
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void* ChildAt(int32 index) const
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool GetValueAt(int32 columnIndex, BVariant& value)
|
|
||||||
{
|
|
||||||
return _GetWaitObjectValueAt(object, columnIndex, value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// For GCC 2
|
|
||||||
friend struct ObjectNode;
|
|
||||||
|
|
||||||
struct GroupNode : Node {
|
|
||||||
ThreadModel::WaitObjectGroup* group;
|
|
||||||
BObjectList<ObjectNode> objectNodes;
|
|
||||||
|
|
||||||
GroupNode(ThreadModel::WaitObjectGroup* group)
|
|
||||||
:
|
|
||||||
group(group)
|
|
||||||
{
|
|
||||||
int32 count = group->CountWaitObjects();
|
|
||||||
for (int32 i = 0; i < count; i++) {
|
|
||||||
Model::ThreadWaitObject* waitObject = group->WaitObjectAt(i);
|
|
||||||
if (!objectNodes.AddItem(new ObjectNode(waitObject)))
|
|
||||||
throw std::bad_alloc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual int32 CountChildren() const
|
|
||||||
{
|
|
||||||
return objectNodes.CountItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void* ChildAt(int32 index) const
|
|
||||||
{
|
|
||||||
return objectNodes.ItemAt(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool GetValueAt(int32 columnIndex, BVariant& value)
|
|
||||||
{
|
|
||||||
if (columnIndex <= 2) {
|
|
||||||
return _GetWaitObjectValueAt(group->WaitObjectAt(0),
|
|
||||||
columnIndex, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (columnIndex) {
|
|
||||||
case 4:
|
|
||||||
value.SetTo(group->Waits());
|
|
||||||
return true;
|
|
||||||
case 5:
|
|
||||||
value.SetTo(group->TotalWaitTime());
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// For GCC 2
|
|
||||||
friend struct GroupNode;
|
|
||||||
|
|
||||||
struct RootNode : Node {
|
|
||||||
ThreadModel* threadModel;
|
|
||||||
BObjectList<Node> groupNodes;
|
|
||||||
|
|
||||||
RootNode(ThreadModel* model)
|
|
||||||
:
|
|
||||||
threadModel(model),
|
|
||||||
groupNodes(20, true)
|
|
||||||
{
|
|
||||||
int32 count = threadModel->CountWaitObjectGroups();
|
|
||||||
for (int32 i = 0; i < count; i++) {
|
|
||||||
ThreadModel::WaitObjectGroup* group
|
|
||||||
= threadModel->WaitObjectGroupAt(i);
|
|
||||||
if (!groupNodes.AddItem(_CreateGroupNode(group)))
|
|
||||||
throw std::bad_alloc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual int32 CountChildren() const
|
|
||||||
{
|
|
||||||
return groupNodes.CountItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void* ChildAt(int32 index) const
|
|
||||||
{
|
|
||||||
return groupNodes.ItemAt(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool GetValueAt(int32 columnIndex, BVariant& value)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static Node* _CreateGroupNode(ThreadModel::WaitObjectGroup* group)
|
|
||||||
{
|
|
||||||
// If the group has only one object, just create an object node.
|
|
||||||
if (group->CountWaitObjects() == 1)
|
|
||||||
return new ObjectNode(group->WaitObjectAt(0));
|
|
||||||
|
|
||||||
return new GroupNode(group);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
static bool _GetWaitObjectValueAt(Model::ThreadWaitObject* waitObject,
|
|
||||||
int32 columnIndex, BVariant& value)
|
|
||||||
{
|
|
||||||
switch (columnIndex) {
|
|
||||||
case 0:
|
|
||||||
value.SetTo(wait_object_type_name(waitObject->Type()),
|
|
||||||
B_VARIANT_DONT_COPY_DATA);
|
|
||||||
return true;
|
|
||||||
case 1:
|
|
||||||
value.SetTo(waitObject->Name(), B_VARIANT_DONT_COPY_DATA);
|
|
||||||
return true;
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
if (waitObject->Object() == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
char buffer[16];
|
|
||||||
snprintf(buffer, sizeof(buffer), "%#lx",
|
|
||||||
waitObject->Object());
|
|
||||||
value.SetTo(buffer);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case 3:
|
|
||||||
{
|
|
||||||
if (waitObject->ReferencedObject() == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
char buffer[16];
|
|
||||||
snprintf(buffer, sizeof(buffer), "%#lx",
|
|
||||||
waitObject->ReferencedObject());
|
|
||||||
value.SetTo(buffer);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case 4:
|
|
||||||
value.SetTo(waitObject->Waits());
|
|
||||||
return true;
|
|
||||||
case 5:
|
|
||||||
value.SetTo(waitObject->TotalWaitTime());
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
ThreadModel* fThreadModel;
|
|
||||||
RootNode* fRootNode;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - WaitObjectsPage
|
|
||||||
|
|
||||||
|
|
||||||
ThreadWindow::WaitObjectsPage::WaitObjectsPage()
|
ThreadWindow::WaitObjectsPage::WaitObjectsPage()
|
||||||
:
|
|
||||||
BGroupView(B_VERTICAL),
|
|
||||||
fWaitObjectsTree(NULL),
|
|
||||||
fWaitObjectsTreeModel(NULL),
|
|
||||||
fThreadModel(NULL)
|
|
||||||
|
|
||||||
{
|
{
|
||||||
SetName("Wait Objects");
|
|
||||||
|
|
||||||
fWaitObjectsTree = new TreeTable("wait object list", 0);
|
|
||||||
AddChild(fWaitObjectsTree->ToView());
|
|
||||||
|
|
||||||
fWaitObjectsTree->AddColumn(new StringTableColumn(0, "Type", 80, 40, 1000,
|
|
||||||
B_TRUNCATE_END, B_ALIGN_LEFT));
|
|
||||||
fWaitObjectsTree->AddColumn(new StringTableColumn(1, "Name", 80, 40, 1000,
|
|
||||||
B_TRUNCATE_END, B_ALIGN_LEFT));
|
|
||||||
fWaitObjectsTree->AddColumn(new StringTableColumn(2, "Object", 80, 40, 1000,
|
|
||||||
B_TRUNCATE_END, B_ALIGN_LEFT));
|
|
||||||
fWaitObjectsTree->AddColumn(new StringTableColumn(3, "Referenced", 80, 40,
|
|
||||||
1000, B_TRUNCATE_END, B_ALIGN_LEFT));
|
|
||||||
fWaitObjectsTree->AddColumn(new Int64TableColumn(4, "Waits", 80, 20,
|
|
||||||
1000, B_TRUNCATE_END, B_ALIGN_RIGHT));
|
|
||||||
fWaitObjectsTree->AddColumn(new NanotimeTableColumn(5, "Wait Time", 80,
|
|
||||||
20, 1000, false, B_TRUNCATE_END, B_ALIGN_RIGHT));
|
|
||||||
|
|
||||||
fWaitObjectsTree->AddTreeTableListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ThreadWindow::WaitObjectsPage::~WaitObjectsPage()
|
|
||||||
{
|
|
||||||
fWaitObjectsTree->SetTreeTableModel(NULL);
|
|
||||||
delete fWaitObjectsTreeModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
ThreadWindow::WaitObjectsPage::SetModel(ThreadModel* model)
|
|
||||||
{
|
|
||||||
if (model == fThreadModel)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (fThreadModel != NULL) {
|
|
||||||
fWaitObjectsTree->SetTreeTableModel(NULL);
|
|
||||||
delete fWaitObjectsTreeModel;
|
|
||||||
fWaitObjectsTreeModel = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
fThreadModel = model;
|
|
||||||
|
|
||||||
if (fThreadModel != NULL) {
|
|
||||||
try {
|
|
||||||
fWaitObjectsTreeModel = new WaitObjectsTreeModel(fThreadModel);
|
|
||||||
} catch (std::bad_alloc) {
|
|
||||||
// TODO: Report error!
|
|
||||||
}
|
|
||||||
fWaitObjectsTree->SetTreeTableModel(fWaitObjectsTreeModel);
|
|
||||||
fWaitObjectsTree->ResizeAllColumnsToPreferred();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
ThreadWindow::WaitObjectsPage::TreeTableNodeInvoked(TreeTable* table,
|
|
||||||
const TreeTablePath& path)
|
|
||||||
{
|
|
||||||
// Model::Thread* thread = fModel->ThreadAt(rowIndex);
|
|
||||||
// if (thread != NULL)
|
|
||||||
// fParent->OpenThreadWindow(thread);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,33 +5,17 @@
|
|||||||
#ifndef THREAD_WAIT_OBJECTS_PAGE_H
|
#ifndef THREAD_WAIT_OBJECTS_PAGE_H
|
||||||
#define THREAD_WAIT_OBJECTS_PAGE_H
|
#define THREAD_WAIT_OBJECTS_PAGE_H
|
||||||
|
|
||||||
#include <GroupView.h>
|
|
||||||
|
|
||||||
#include "table/TreeTable.h"
|
|
||||||
|
|
||||||
|
#include "AbstractWaitObjectsPage.h"
|
||||||
|
#include "ThreadModel.h"
|
||||||
#include "thread_window/ThreadWindow.h"
|
#include "thread_window/ThreadWindow.h"
|
||||||
|
|
||||||
|
|
||||||
class ThreadWindow::WaitObjectsPage : public BGroupView,
|
class ThreadWindow::WaitObjectsPage
|
||||||
private TreeTableListener {
|
: public AbstractWaitObjectsPage<ThreadModel, ThreadModel::WaitObjectGroup,
|
||||||
|
Model::ThreadWaitObject> {
|
||||||
public:
|
public:
|
||||||
WaitObjectsPage();
|
WaitObjectsPage();
|
||||||
virtual ~WaitObjectsPage();
|
|
||||||
|
|
||||||
void SetModel(ThreadModel* model);
|
|
||||||
|
|
||||||
private:
|
|
||||||
class WaitObjectsTreeModel;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// TreeTableListener
|
|
||||||
virtual void TreeTableNodeInvoked(TreeTable* table,
|
|
||||||
const TreeTablePath& path);
|
|
||||||
|
|
||||||
private:
|
|
||||||
TreeTable* fWaitObjectsTree;
|
|
||||||
WaitObjectsTreeModel* fWaitObjectsTreeModel;
|
|
||||||
ThreadModel* fThreadModel;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user