* 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:
Ingo Weinhold 2009-12-12 12:31:24 +00:00
parent dedd14df43
commit a5852db3c2
5 changed files with 350 additions and 456 deletions

View File

@ -0,0 +1,339 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* 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

View File

@ -1,5 +1,4 @@
/*
* Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
@ -7,122 +6,9 @@
#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)
:
BGroupView(B_VERTICAL),
fParent(parent),
fWaitObjectsTable(NULL),
fWaitObjectsTableModel(NULL),
fModel(NULL)
fParent(parent)
{
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();
}
}

View File

@ -7,27 +7,19 @@
#define MAIN_WAIT_OBJECTS_PAGE_H
#include <GroupView.h>
#include "table/Table.h"
#include "AbstractWaitObjectsPage.h"
#include "Model.h"
#include "main_window/MainWindow.h"
class MainWindow::WaitObjectsPage : public BGroupView {
class MainWindow::WaitObjectsPage
: public AbstractWaitObjectsPage<Model, Model::WaitObjectGroup,
Model::WaitObject> {
public:
WaitObjectsPage(MainWindow* parent);
virtual ~WaitObjectsPage();
void SetModel(Model* model);
private:
class WaitObjectsTableModel;
MainWindow* fParent;
Table* fWaitObjectsTable;
WaitObjectsTableModel* fWaitObjectsTableModel;
Model* fModel;
};

View File

@ -6,314 +6,7 @@
#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()
:
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);
}

View File

@ -5,33 +5,17 @@
#ifndef 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"
class ThreadWindow::WaitObjectsPage : public BGroupView,
private TreeTableListener {
class ThreadWindow::WaitObjectsPage
: public AbstractWaitObjectsPage<ThreadModel, ThreadModel::WaitObjectGroup,
Model::ThreadWaitObject> {
public:
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;
};