[Haiku-commits] r31122 - haiku/trunk/src/apps/debugger/gui/team_window

bonefish at BerliOS bonefish at mail.berlios.de
Fri Jun 19 19:31:25 CEST 2009


Author: bonefish
Date: 2009-06-19 19:31:24 +0200 (Fri, 19 Jun 2009)
New Revision: 31122
ViewCVS: http://svn.berlios.de/viewcvs/haiku?rev=31122&view=rev

Added:
   haiku/trunk/src/apps/debugger/gui/team_window/RegisterView.cpp
   haiku/trunk/src/apps/debugger/gui/team_window/RegisterView.h
Modified:
   haiku/trunk/src/apps/debugger/gui/team_window/TeamWindow.cpp
   haiku/trunk/src/apps/debugger/gui/team_window/TeamWindow.h
Log:
Added view to show registers. Doesn't look particularly nice, but seems to work.


Added: haiku/trunk/src/apps/debugger/gui/team_window/RegisterView.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/gui/team_window/RegisterView.cpp	2009-06-19 17:29:39 UTC (rev 31121)
+++ haiku/trunk/src/apps/debugger/gui/team_window/RegisterView.cpp	2009-06-19 17:31:24 UTC (rev 31122)
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold at gmx.de.
+ * Distributed under the terms of the MIT License.
+ */
+
+#include "RegisterView.h"
+
+#include <stdio.h>
+
+#include <new>
+
+#include "table/TableColumns.h"
+
+#include "Architecture.h"
+#include "CpuState.h"
+#include "Register.h"
+
+
+// #pragma mark - RegisterValueColumn
+
+
+class RegisterView::RegisterValueColumn : public StringTableColumn {
+public:
+	RegisterValueColumn(int32 modelIndex, const char* title, float width,
+		float minWidth, float maxWidth, uint32 truncate = B_TRUNCATE_MIDDLE,
+		alignment align = B_ALIGN_RIGHT)
+		:
+		StringTableColumn(modelIndex, title, width, minWidth, maxWidth,
+			truncate, align)
+	{
+	}
+
+protected:
+	virtual BField* PrepareField(const Variant& value) const
+	{
+		char buffer[64];
+		return StringTableColumn::PrepareField(
+			Variant(_ToString(value, buffer, sizeof(buffer)),
+				VARIANT_DONT_COPY_DATA));
+	}
+
+	virtual int CompareValues(const Variant& a, const Variant& b)
+	{
+		// If neither value is a number, compare the strings. If only one value
+		// is a number, it is considered to be greater.
+		if (!a.IsNumber()) {
+			if (b.IsNumber())
+				return -1;
+			char bufferA[64];
+			char bufferB[64];
+			return StringTableColumn::CompareValues(
+				Variant(_ToString(a, bufferA, sizeof(bufferA)),
+					VARIANT_DONT_COPY_DATA),
+				Variant(_ToString(b, bufferB, sizeof(bufferB)),
+					VARIANT_DONT_COPY_DATA));
+		}
+
+		if (!b.IsNumber())
+			return 1;
+
+		// If either value is floating point, we compare floating point values.
+		if (a.IsFloat() || b.IsFloat()) {
+			double valueA = a.ToDouble();
+			double valueB = b.ToDouble();
+			return valueA < valueB ? -1 : (valueA == valueB ? 0 : 1);
+		}
+
+		uint64 valueA = a.ToUInt64();
+		uint64 valueB = b.ToUInt64();
+		return valueA < valueB ? -1 : (valueA == valueB ? 0 : 1);
+	}
+
+private:
+	const char* _ToString(const Variant& value, char* buffer,
+		size_t bufferSize) const
+	{
+		if (!value.IsNumber())
+			return value.ToString();
+
+		switch (value.Type()) {
+			case B_FLOAT_TYPE:
+			case B_DOUBLE_TYPE:
+				snprintf(buffer, bufferSize, "%g", value.ToDouble());
+				break;
+			case B_INT8_TYPE:
+			case B_UINT8_TYPE:
+				snprintf(buffer, bufferSize, "0x%02x", value.ToUInt8());
+				break;
+			case B_INT16_TYPE:
+			case B_UINT16_TYPE:
+				snprintf(buffer, bufferSize, "0x%04x", value.ToUInt16());
+				break;
+			case B_INT32_TYPE:
+			case B_UINT32_TYPE:
+				snprintf(buffer, bufferSize, "0x%08lx", value.ToUInt32());
+				break;
+			case B_INT64_TYPE:
+			case B_UINT64_TYPE:
+			default:
+				snprintf(buffer, bufferSize, "0x%016llx", value.ToUInt64());
+				break;
+		}
+
+		return buffer;
+	}
+};
+
+
+// #pragma mark - RegisterTableModel
+
+
+class RegisterView::RegisterTableModel : public TableModel {
+public:
+	RegisterTableModel(Architecture* architecture)
+		:
+		fArchitecture(architecture),
+		fCpuState(NULL)
+	{
+	}
+
+	~RegisterTableModel()
+	{
+	}
+
+	void SetCpuState(CpuState* cpuState)
+	{
+		fCpuState = cpuState;
+
+		NotifyRowsChanged(0, CountRows());
+	}
+
+	virtual int32 CountColumns() const
+	{
+		return 2;
+	}
+
+	virtual int32 CountRows() const
+	{
+		return fArchitecture->CountRegisters();
+	}
+
+	virtual bool GetValueAt(int32 rowIndex, int32 columnIndex, Variant& value)
+	{
+		if (rowIndex < 0 || rowIndex >= fArchitecture->CountRegisters())
+			return false;
+
+		const Register* reg = fArchitecture->Registers() + rowIndex;
+
+		switch (columnIndex) {
+			case 0:
+				value.SetTo(reg->Name(), VARIANT_DONT_COPY_DATA);
+				return true;
+			case 1:
+				if (fCpuState == NULL)
+					return false;
+				if (!fCpuState->GetRegisterValue(reg, value))
+					value.SetTo("?", VARIANT_DONT_COPY_DATA);
+				return true;
+			default:
+				return false;
+		}
+	}
+
+private:
+	Architecture*	fArchitecture;
+	CpuState*		fCpuState;
+};
+
+
+// #pragma mark - RegisterView
+
+
+RegisterView::RegisterView(Architecture* architecture)
+	:
+	BGroupView(B_VERTICAL),
+	fArchitecture(architecture),
+	fRegisterTable(NULL),
+	fRegisterTableModel(NULL)
+{
+	SetName("Registers");
+}
+
+
+RegisterView::~RegisterView()
+{
+	SetCpuState(NULL);
+	fRegisterTable->SetTableModel(NULL);
+	delete fRegisterTableModel;
+}
+
+
+/*static*/ RegisterView*
+RegisterView::Create(Architecture* architecture)
+{
+	RegisterView* self = new RegisterView(architecture);
+
+	try {
+		self->_Init();
+	} catch (...) {
+		delete self;
+		throw;
+	}
+
+	return self;
+}
+
+
+void
+RegisterView::SetCpuState(CpuState* cpuState)
+{
+	if (cpuState == fCpuState)
+		return;
+
+	if (fCpuState != NULL)
+		fCpuState->RemoveReference();
+
+	fCpuState = cpuState;
+
+	if (fCpuState != NULL)
+		fCpuState->AddReference();
+
+	fRegisterTableModel->SetCpuState(fCpuState);
+}
+
+
+void
+RegisterView::TableRowInvoked(Table* table, int32 rowIndex)
+{
+}
+
+
+void
+RegisterView::_Init()
+{
+	fRegisterTable = new Table("register list", 0);
+	AddChild(fRegisterTable->ToView());
+
+	// columns
+	fRegisterTable->AddColumn(new StringTableColumn(0, "Register", 80, 40, 1000,
+		B_TRUNCATE_END, B_ALIGN_LEFT));
+	fRegisterTable->AddColumn(new RegisterValueColumn(1, "Value", 80, 40, 1000,
+		B_TRUNCATE_END, B_ALIGN_RIGHT));
+
+	fRegisterTableModel = new RegisterTableModel(fArchitecture);
+	fRegisterTable->SetTableModel(fRegisterTableModel);
+
+	fRegisterTable->AddTableListener(this);
+}

Added: haiku/trunk/src/apps/debugger/gui/team_window/RegisterView.h
===================================================================
--- haiku/trunk/src/apps/debugger/gui/team_window/RegisterView.h	2009-06-19 17:29:39 UTC (rev 31121)
+++ haiku/trunk/src/apps/debugger/gui/team_window/RegisterView.h	2009-06-19 17:31:24 UTC (rev 31122)
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold at gmx.de.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef REGISTER_VIEW_H
+#define REGISTER_VIEW_H
+
+#include <GroupView.h>
+
+#include "table/Table.h"
+#include "Team.h"
+
+
+class Architecture;
+
+
+class RegisterView : public BGroupView, private TableListener {
+public:
+								RegisterView(Architecture* architecture);
+								~RegisterView();
+
+	static	RegisterView*		Create(Architecture* architecture);
+									// throws
+
+			void				SetCpuState(CpuState* cpuState);
+
+private:
+			class RegisterValueColumn;
+			class RegisterTableModel;
+
+private:
+	// TableListener
+	virtual	void				TableRowInvoked(Table* table, int32 rowIndex);
+
+			void				_Init();
+
+private:
+			Architecture*		fArchitecture;
+			CpuState*			fCpuState;
+			Table*				fRegisterTable;
+			RegisterTableModel*	fRegisterTableModel;
+};
+
+
+#endif	// REGISTER_VIEW_H

Modified: haiku/trunk/src/apps/debugger/gui/team_window/TeamWindow.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/gui/team_window/TeamWindow.cpp	2009-06-19 17:29:39 UTC (rev 31121)
+++ haiku/trunk/src/apps/debugger/gui/team_window/TeamWindow.cpp	2009-06-19 17:31:24 UTC (rev 31122)
@@ -16,8 +16,10 @@
 
 #include <AutoLocker.h>
 
+#include "CpuState.h"
 #include "ImageListView.h"
 #include "MessageCodes.h"
+#include "RegisterView.h"
 #include "TeamDebugModel.h"
 
 
@@ -32,8 +34,10 @@
 	fActiveThread(NULL),
 	fListener(listener),
 	fTabView(NULL),
+	fLocalsTabView(NULL),
 	fThreadListView(NULL),
 	fImageListView(NULL),
+	fRegisterView(NULL),
 	fRunButton(NULL),
 	fStepOverButton(NULL),
 	fStepIntoButton(NULL),
@@ -95,7 +99,16 @@
 			_HandleThreadStateChanged(threadID);
 			break;
 		}
-//		case MSG_THREAD_CPU_STATE_CHANGED:
+		case MSG_THREAD_CPU_STATE_CHANGED:
+		{
+			int32 threadID;
+			if (message->FindInt32("thread", &threadID) != B_OK)
+				break;
+
+			_HandleCpuStateChanged(threadID);
+			break;
+		}
+
 //		case MSG_THREAD_STACK_TRACE_CHANGED:
 
 		default:
@@ -131,18 +144,18 @@
 void
 TeamWindow::ThreadCpuStateChanged(const Team::ThreadEvent& event)
 {
-//	BMessage message(MSG_THREAD_CPU_STATE_CHANGED);
-//	message.AddInt32("thread", event.GetThread()->ID());
-//	PostMessage(&message);
+	BMessage message(MSG_THREAD_CPU_STATE_CHANGED);
+	message.AddInt32("thread", event.GetThread()->ID());
+	PostMessage(&message);
 }
 
 
 void
 TeamWindow::ThreadStackTraceChanged(const Team::ThreadEvent& event)
 {
-//	BMessage message(MSG_THREAD_STACK_TRACE_CHANGED);
-//	message.AddInt32("thread", event.GetThread()->ID());
-//	PostMessage(&message);
+	BMessage message(MSG_THREAD_STACK_TRACE_CHANGED);
+	message.AddInt32("thread", event.GetThread()->ID());
+	PostMessage(&message);
 }
 
 
@@ -162,7 +175,7 @@
 				.End()
 				.AddSplit(B_HORIZONTAL, 3.0f)
 					.Add(new BTextView("source view"), 3.0f)
-					.Add(new BTextView("variables view"))
+					.Add(fLocalsTabView = new BTabView("locals view"))
 				.End()
 			.End()
 		.End();
@@ -183,6 +196,14 @@
 		.Add(fImageListView = ImageListView::Create())
 		.Add(new BTextView("source files"));
 
+	// add local variables tab
+	BView* tab = new BTextView("Variables");
+	fLocalsTabView->AddTab(tab);
+
+	// add registers tab
+	tab = fRegisterView = RegisterView::Create(fDebugModel->GetArchitecture());
+	fLocalsTabView->AddTab(tab);
+
 	fThreadListView->SetTeam(fDebugModel->GetTeam());
 	fImageListView->SetTeam(fDebugModel->GetTeam());
 
@@ -210,6 +231,15 @@
 
 	AutoLocker<TeamDebugModel> locker(fDebugModel);
 	_UpdateRunButtons();
+
+	CpuState* cpuState = fActiveThread != NULL
+		? fActiveThread->GetCpuState() : NULL;
+	Reference<CpuState> reference(cpuState);
+		// hold a reference until the register view has one
+
+	locker.Unlock();
+
+	fRegisterView->SetCpuState(cpuState);
 }
 
 
@@ -258,6 +288,26 @@
 }
 
 
+void
+TeamWindow::_HandleCpuStateChanged(thread_id threadID)
+{
+	// We're only interested in the currently selected thread
+	if (fActiveThread == NULL || threadID != fActiveThread->ID())
+		return;
+
+	AutoLocker<TeamDebugModel> locker(fDebugModel);
+
+	CpuState* cpuState = fActiveThread != NULL
+		? fActiveThread->GetCpuState() : NULL;
+	Reference<CpuState> reference(cpuState);
+		// hold a reference until the register view has one
+
+	locker.Unlock();
+
+	fRegisterView->SetCpuState(cpuState);
+}
+
+
 // #pragma mark - Listener
 
 

Modified: haiku/trunk/src/apps/debugger/gui/team_window/TeamWindow.h
===================================================================
--- haiku/trunk/src/apps/debugger/gui/team_window/TeamWindow.h	2009-06-19 17:29:39 UTC (rev 31121)
+++ haiku/trunk/src/apps/debugger/gui/team_window/TeamWindow.h	2009-06-19 17:31:24 UTC (rev 31122)
@@ -15,6 +15,7 @@
 class BButton;
 class BTabView;
 class ImageListView;
+class RegisterView;
 class TeamDebugModel;
 
 
@@ -53,14 +54,17 @@
 			void				_UpdateRunButtons();
 
 			void				_HandleThreadStateChanged(thread_id threadID);
+			void				_HandleCpuStateChanged(thread_id threadID);
 
 private:
 			TeamDebugModel*		fDebugModel;
 			::Thread*			fActiveThread;
 			Listener*			fListener;
 			BTabView*			fTabView;
+			BTabView*			fLocalsTabView;
 			ThreadListView*		fThreadListView;
 			ImageListView*		fImageListView;
+			RegisterView*		fRegisterView;
 			BButton*			fRunButton;
 			BButton*			fStepOverButton;
 			BButton*			fStepIntoButton;




More information about the Haiku-commits mailing list