WiP:
* Added an abstraction for getting an BDataIO, DataSource and derived classes, which allows to move I/O completely out of the GUI threads. * Fleshed out application start, window creation, and file loading. We do now create a window for every command line argument and load the referenced file or, if none, create an empty window. * Some improvements in the file loader. It does now correctly load the file, but doesn't process the stored data yet. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30274 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
4d8d8c1f38
commit
c442235ebd
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "DataSource.h"
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - DataSource
|
||||||
|
|
||||||
|
|
||||||
|
DataSource::DataSource()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DataSource::~DataSource()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - FileDataSource
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
FileDataSource::CreateDataIO(BDataIO** _io)
|
||||||
|
{
|
||||||
|
BFile* file = new(std::nothrow) BFile;
|
||||||
|
if (file == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
status_t error = OpenFile(*file);
|
||||||
|
if (error != B_OK) {
|
||||||
|
delete file;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
*_io = file;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - PathDataSource
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PathDataSource::Init(const char* path)
|
||||||
|
{
|
||||||
|
return fPath.SetTo(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PathDataSource::OpenFile(BFile& file)
|
||||||
|
{
|
||||||
|
return file.SetTo(fPath.Path(), B_READ_ONLY);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - EntryRefDataSource
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
EntryRefDataSource::Init(const entry_ref* ref)
|
||||||
|
{
|
||||||
|
if (ref->name == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
fRef = *ref;
|
||||||
|
if (fRef.name == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
EntryRefDataSource::OpenFile(BFile& file)
|
||||||
|
{
|
||||||
|
return file.SetTo(&fRef, B_READ_ONLY);
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef DATA_SOURCE_H
|
||||||
|
#define DATA_SOURCE_H
|
||||||
|
|
||||||
|
#include <Entry.h>
|
||||||
|
#include <File.h>
|
||||||
|
#include <Path.h>
|
||||||
|
|
||||||
|
|
||||||
|
class DataSource {
|
||||||
|
public:
|
||||||
|
DataSource();
|
||||||
|
virtual ~DataSource();
|
||||||
|
|
||||||
|
virtual status_t CreateDataIO(BDataIO** _io) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class FileDataSource : public DataSource {
|
||||||
|
public:
|
||||||
|
virtual status_t CreateDataIO(BDataIO** _io);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual status_t OpenFile(BFile& file) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class PathDataSource : public FileDataSource {
|
||||||
|
public:
|
||||||
|
status_t Init(const char* path);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual status_t OpenFile(BFile& file);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BPath fPath;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class EntryRefDataSource : public FileDataSource {
|
||||||
|
public:
|
||||||
|
status_t Init(const entry_ref* ref);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual status_t OpenFile(BFile& file);
|
||||||
|
|
||||||
|
private:
|
||||||
|
entry_ref fRef;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // DATA_SOURCE_H
|
|
@ -3,13 +3,19 @@
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
|
|
||||||
|
#include <AutoDeleter.h>
|
||||||
|
|
||||||
|
#include "DataSource.h"
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
|
#include "MessageCodes.h"
|
||||||
|
|
||||||
|
|
||||||
static const char* const kSignature = "application/x-vnd.Haiku-DebugAnalyzer";
|
static const char* const kSignature = "application/x-vnd.Haiku-DebugAnalyzer";
|
||||||
|
@ -19,23 +25,89 @@ class DebugAnalyzer : public BApplication {
|
||||||
public:
|
public:
|
||||||
DebugAnalyzer()
|
DebugAnalyzer()
|
||||||
:
|
:
|
||||||
BApplication(kSignature)
|
BApplication(kSignature),
|
||||||
|
fWindowCount(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void ReadyToRun()
|
virtual void ReadyToRun()
|
||||||
{
|
{
|
||||||
MainWindow* window;
|
printf("ReadyToRun()\n");
|
||||||
try {
|
if (fWindowCount == 0 && _CreateWindow(NULL) != B_OK)
|
||||||
window = new MainWindow;
|
PostMessage(B_QUIT_REQUESTED);
|
||||||
} catch (std::bad_alloc) {
|
}
|
||||||
exit(1);
|
|
||||||
|
virtual void ArgvReceived(int32 argc, char** argv)
|
||||||
|
{
|
||||||
|
printf("ArgvReceived()\n");
|
||||||
|
for (int32 i = 0; i < argc; i++)
|
||||||
|
printf(" arg %ld: \"%s\"\n", i, argv[i]);
|
||||||
|
|
||||||
|
for (int32 i = 1; i < argc; i++) {
|
||||||
|
PathDataSource* dataSource = new(std::nothrow) PathDataSource;
|
||||||
|
if (dataSource == NULL) {
|
||||||
|
// no memory
|
||||||
|
fprintf(stderr, "DebugAnalyzer::ArgvReceived(): Out of "
|
||||||
|
"memory!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t error = dataSource->Init(argv[i]);
|
||||||
|
if (error != B_OK) {
|
||||||
|
fprintf(stderr, "Failed to create data source for path "
|
||||||
|
"\"%s\": %s\n", argv[i], strerror(error));
|
||||||
|
// TODO: Alert!
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
_CreateWindow(dataSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
window->Show();
|
}
|
||||||
|
|
||||||
|
virtual void RefsReceived(BMessage* message)
|
||||||
|
{
|
||||||
|
printf("RefsReceived()\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
status_t _CreateWindow(DataSource* dataSource)
|
||||||
|
{
|
||||||
|
ObjectDeleter<DataSource> dataSourceDeleter(dataSource);
|
||||||
|
|
||||||
|
MainWindow* window;
|
||||||
|
try {
|
||||||
|
window = new MainWindow(dataSource);
|
||||||
|
} catch (std::bad_alloc) {
|
||||||
|
fprintf(stderr, "DebugAnalyzer::_CreateWindow(): Out of memory!\n");
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the data source is owned by the window now
|
||||||
|
dataSourceDeleter.Detach();
|
||||||
|
|
||||||
|
window->Show();
|
||||||
|
|
||||||
|
fWindowCount++;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void MessageReceived(BMessage* message)
|
||||||
|
{
|
||||||
|
switch (message->what) {
|
||||||
|
case MSG_WINDOW_QUIT:
|
||||||
|
if (--fWindowCount == 0)
|
||||||
|
PostMessage(B_QUIT_REQUESTED);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BApplication::MessageReceived(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int32 fWindowCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ UsePrivateSystemHeaders ;
|
||||||
|
|
||||||
Application DebugAnalyzer
|
Application DebugAnalyzer
|
||||||
:
|
:
|
||||||
|
DataSource.cpp
|
||||||
DebugAnalyzer.cpp
|
DebugAnalyzer.cpp
|
||||||
MainModel.cpp
|
MainModel.cpp
|
||||||
MainModelLoader.cpp
|
MainModelLoader.cpp
|
||||||
|
|
|
@ -5,22 +5,30 @@
|
||||||
|
|
||||||
#include "MainModelLoader.h"
|
#include "MainModelLoader.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
#include <AutoDeleter.h>
|
#include <AutoDeleter.h>
|
||||||
#include <AutoLocker.h>
|
#include <AutoLocker.h>
|
||||||
#include <DebugEventStream.h>
|
#include <DebugEventStream.h>
|
||||||
|
|
||||||
|
#include <system_profiler_defs.h>
|
||||||
|
|
||||||
|
#include "DataSource.h"
|
||||||
#include "MainModel.h"
|
#include "MainModel.h"
|
||||||
#include "MessageCodes.h"
|
#include "MessageCodes.h"
|
||||||
|
|
||||||
|
|
||||||
MainModelLoader::MainModelLoader()
|
MainModelLoader::MainModelLoader(DataSource* dataSource,
|
||||||
|
const BMessenger& target, void* targetCookie)
|
||||||
:
|
:
|
||||||
fLock("main model loader"),
|
fLock("main model loader"),
|
||||||
fModel(NULL),
|
fModel(NULL),
|
||||||
fInput(NULL),
|
fDataSource(dataSource),
|
||||||
fTarget(),
|
fTarget(target),
|
||||||
|
fTargetCookie(targetCookie),
|
||||||
fLoaderThread(-1),
|
fLoaderThread(-1),
|
||||||
fLoading(false),
|
fLoading(false),
|
||||||
fAborted(false)
|
fAborted(false)
|
||||||
|
@ -35,13 +43,13 @@ MainModelLoader::~MainModelLoader()
|
||||||
wait_for_thread(fLoaderThread, NULL);
|
wait_for_thread(fLoaderThread, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete fInput;
|
delete fDataSource;
|
||||||
delete fModel;
|
delete fModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
MainModelLoader::StartLoading(BDataIO& input, const BMessenger& target)
|
MainModelLoader::StartLoading()
|
||||||
{
|
{
|
||||||
// check initialization
|
// check initialization
|
||||||
status_t error = fLock.InitCheck();
|
status_t error = fLock.InitCheck();
|
||||||
|
@ -50,7 +58,7 @@ MainModelLoader::StartLoading(BDataIO& input, const BMessenger& target)
|
||||||
|
|
||||||
AutoLocker<BLocker> locker(fLock);
|
AutoLocker<BLocker> locker(fLock);
|
||||||
|
|
||||||
if (fModel != NULL)
|
if (fModel != NULL || fLoading || fDataSource == NULL)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
// create a model
|
// create a model
|
||||||
|
@ -59,17 +67,6 @@ MainModelLoader::StartLoading(BDataIO& input, const BMessenger& target)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
ObjectDeleter<MainModel> modelDeleter(model);
|
ObjectDeleter<MainModel> modelDeleter(model);
|
||||||
|
|
||||||
// create a debug input stream
|
|
||||||
BDebugEventInputStream* inputStream
|
|
||||||
= new(std::nothrow) BDebugEventInputStream;
|
|
||||||
if (inputStream == NULL)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
ObjectDeleter<BDebugEventInputStream> inputDeleter(inputStream);
|
|
||||||
|
|
||||||
error = inputStream->SetTo(&input);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
// spawn the loader thread
|
// spawn the loader thread
|
||||||
fLoaderThread = spawn_thread(&_LoaderEntry, "main model loader",
|
fLoaderThread = spawn_thread(&_LoaderEntry, "main model loader",
|
||||||
B_NORMAL_PRIORITY, this);
|
B_NORMAL_PRIORITY, this);
|
||||||
|
@ -77,9 +74,7 @@ MainModelLoader::StartLoading(BDataIO& input, const BMessenger& target)
|
||||||
return fLoaderThread;
|
return fLoaderThread;
|
||||||
|
|
||||||
modelDeleter.Detach();
|
modelDeleter.Detach();
|
||||||
inputDeleter.Detach();
|
|
||||||
fModel = model;
|
fModel = model;
|
||||||
fInput = inputStream;
|
|
||||||
|
|
||||||
fLoading = true;
|
fLoading = true;
|
||||||
fAborted = false;
|
fAborted = false;
|
||||||
|
@ -127,64 +122,134 @@ MainModelLoader::_LoaderEntry(void* data)
|
||||||
status_t
|
status_t
|
||||||
MainModelLoader::_Loader()
|
MainModelLoader::_Loader()
|
||||||
{
|
{
|
||||||
bool success = false;
|
printf("MainModelLoader::_Loader()\n");
|
||||||
|
status_t error;
|
||||||
uint32 count = 0;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while (true) {
|
error = _Load();
|
||||||
// get next event
|
} catch(...) {
|
||||||
uint32 event;
|
printf("MainModelLoader::_Loader(): caught exception\n");
|
||||||
uint32 cpu;
|
error = B_ERROR;
|
||||||
const void* buffer;
|
|
||||||
ssize_t bufferSize = fInput->ReadNextEvent(&event, &cpu, &buffer);
|
|
||||||
if (bufferSize < 0)
|
|
||||||
break;
|
|
||||||
if (buffer == NULL) {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// process the event
|
|
||||||
status_t error = _ProcessEvent(event, cpu, buffer, bufferSize);
|
|
||||||
if (error != B_OK)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (++count % 32 == 0) {
|
|
||||||
AutoLocker<BLocker> locker(fLock);
|
|
||||||
if (fAborted)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (...) {
|
|
||||||
}
|
}
|
||||||
|
printf("MainModelLoader::_Loader(): _Load() done: %s\n", strerror(error));
|
||||||
|
|
||||||
// clean up and notify the target
|
// clean up and notify the target
|
||||||
AutoLocker<BLocker> locker(fLock);
|
AutoLocker<BLocker> locker(fLock);
|
||||||
|
|
||||||
delete fInput;
|
BMessage message;
|
||||||
fInput = NULL;
|
if (error == B_OK) {
|
||||||
|
message.what = MSG_MODEL_LOADED_SUCCESSFULLY;
|
||||||
if (success) {
|
|
||||||
fTarget.SendMessage(MSG_MODEL_LOADED_SUCCESSFULLY);
|
|
||||||
} else {
|
} else {
|
||||||
delete fModel;
|
delete fModel;
|
||||||
fModel = NULL;
|
fModel = NULL;
|
||||||
|
|
||||||
fTarget.SendMessage(
|
message.what = fAborted
|
||||||
fAborted ? MSG_MODEL_LOADED_ABORTED : MSG_MODEL_LOADED_FAILED);
|
? MSG_MODEL_LOADED_ABORTED : MSG_MODEL_LOADED_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message.AddPointer("loader", this);
|
||||||
|
message.AddPointer("targetCookie", fTargetCookie);
|
||||||
|
fTarget.SendMessage(&message);
|
||||||
|
|
||||||
fLoading = false;
|
fLoading = false;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
MainModelLoader::_Load()
|
||||||
|
{
|
||||||
|
// get a BDataIO from the data source
|
||||||
|
BDataIO* io;
|
||||||
|
status_t error = fDataSource->CreateDataIO(&io);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
ObjectDeleter<BDataIO> dataIOtDeleter(io);
|
||||||
|
|
||||||
|
// create a debug input stream
|
||||||
|
BDebugEventInputStream* input = new(std::nothrow) BDebugEventInputStream;
|
||||||
|
if (input == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
ObjectDeleter<BDebugEventInputStream> inputDeleter(input);
|
||||||
|
|
||||||
|
error = input->SetTo(io);
|
||||||
|
if (error != B_OK)
|
||||||
|
{
|
||||||
|
printf("MainModelLoader::_Load(): initializing the debug input stream failed: %s\n", strerror(error));
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// process the events
|
||||||
|
uint32 count = 0;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
// get next event
|
||||||
|
uint32 event;
|
||||||
|
uint32 cpu;
|
||||||
|
const void* buffer;
|
||||||
|
ssize_t bufferSize = input->ReadNextEvent(&event, &cpu, &buffer);
|
||||||
|
if (bufferSize < 0)
|
||||||
|
{
|
||||||
|
printf("MainModelLoader::_Load(): reading event failed: %s\n", strerror(bufferSize));
|
||||||
|
return bufferSize;
|
||||||
|
}
|
||||||
|
if (buffer == NULL)
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
// process the event
|
||||||
|
status_t error = _ProcessEvent(event, cpu, buffer, bufferSize);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
// periodically check whether we're supposed to abort
|
||||||
|
if (++count % 32 == 0) {
|
||||||
|
AutoLocker<BLocker> locker(fLock);
|
||||||
|
if (fAborted)
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
MainModelLoader::_ProcessEvent(uint32 event, uint32 cpu, const void* buffer,
|
MainModelLoader::_ProcessEvent(uint32 event, uint32 cpu, const void* buffer,
|
||||||
size_t size)
|
size_t size)
|
||||||
{
|
{
|
||||||
|
switch (event) {
|
||||||
|
case B_SYSTEM_PROFILER_TEAM_ADDED:
|
||||||
|
printf("B_SYSTEM_PROFILER_TEAM_ADDED: %lu\n", size);
|
||||||
|
break;
|
||||||
|
case B_SYSTEM_PROFILER_TEAM_REMOVED:
|
||||||
|
printf("B_SYSTEM_PROFILER_TEAM_REMOVED: %lu\n", size);
|
||||||
|
break;
|
||||||
|
case B_SYSTEM_PROFILER_TEAM_EXEC:
|
||||||
|
printf("B_SYSTEM_PROFILER_TEAM_EXEC: %lu\n", size);
|
||||||
|
break;
|
||||||
|
case B_SYSTEM_PROFILER_THREAD_ADDED:
|
||||||
|
printf("B_SYSTEM_PROFILER_THREAD_ADDED: %lu\n", size);
|
||||||
|
break;
|
||||||
|
case B_SYSTEM_PROFILER_THREAD_REMOVED:
|
||||||
|
printf("B_SYSTEM_PROFILER_THREAD_REMOVED: %lu\n", size);
|
||||||
|
break;
|
||||||
|
case B_SYSTEM_PROFILER_THREAD_SCHEDULED:
|
||||||
|
printf("B_SYSTEM_PROFILER_THREAD_SCHEDULED: %lu\n", size);
|
||||||
|
break;
|
||||||
|
case B_SYSTEM_PROFILER_THREAD_ENQUEUED_IN_RUN_QUEUE:
|
||||||
|
printf("B_SYSTEM_PROFILER_THREAD_ENQUEUED_IN_RUN_QUEUE: %lu\n", size);
|
||||||
|
break;
|
||||||
|
case B_SYSTEM_PROFILER_THREAD_REMOVED_FROM_RUN_QUEUE:
|
||||||
|
printf("B_SYSTEM_PROFILER_THREAD_REMOVED_FROM_RUN_QUEUE: %lu\n", size);
|
||||||
|
break;
|
||||||
|
case B_SYSTEM_PROFILER_WAIT_OBJECT_INFO:
|
||||||
|
printf("B_SYSTEM_PROFILER_WAIT_OBJECT_INFO: %lu\n", size);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("unsupported event type %lu, size: %lu\n", event, size);
|
||||||
|
return B_BAD_DATA;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: Implement!
|
// TODO: Implement!
|
||||||
return B_ERROR;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,17 +11,19 @@
|
||||||
|
|
||||||
class BDataIO;
|
class BDataIO;
|
||||||
class BDebugEventInputStream;
|
class BDebugEventInputStream;
|
||||||
|
class DataSource;
|
||||||
class MainModel;
|
class MainModel;
|
||||||
struct system_profiler_event_header;
|
struct system_profiler_event_header;
|
||||||
|
|
||||||
|
|
||||||
class MainModelLoader {
|
class MainModelLoader {
|
||||||
public:
|
public:
|
||||||
MainModelLoader();
|
MainModelLoader(DataSource* dataSource,
|
||||||
|
const BMessenger& target,
|
||||||
|
void* targetCookie);
|
||||||
~MainModelLoader();
|
~MainModelLoader();
|
||||||
|
|
||||||
status_t StartLoading(BDataIO& input,
|
status_t StartLoading();
|
||||||
const BMessenger& target);
|
|
||||||
void Abort();
|
void Abort();
|
||||||
|
|
||||||
MainModel* DetachModel();
|
MainModel* DetachModel();
|
||||||
|
@ -29,14 +31,16 @@ public:
|
||||||
private:
|
private:
|
||||||
static status_t _LoaderEntry(void* data);
|
static status_t _LoaderEntry(void* data);
|
||||||
status_t _Loader();
|
status_t _Loader();
|
||||||
|
status_t _Load();
|
||||||
status_t _ProcessEvent(uint32 event, uint32 cpu,
|
status_t _ProcessEvent(uint32 event, uint32 cpu,
|
||||||
const void* buffer, size_t size);
|
const void* buffer, size_t size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BLocker fLock;
|
BLocker fLock;
|
||||||
MainModel* fModel;
|
MainModel* fModel;
|
||||||
BDebugEventInputStream* fInput;
|
DataSource* fDataSource;
|
||||||
BMessenger fTarget;
|
BMessenger fTarget;
|
||||||
|
void* fTargetCookie;
|
||||||
thread_id fLoaderThread;
|
thread_id fLoaderThread;
|
||||||
bool fLoading;
|
bool fLoading;
|
||||||
bool fAborted;
|
bool fAborted;
|
||||||
|
|
|
@ -5,17 +5,28 @@
|
||||||
|
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <Application.h>
|
||||||
#include <GroupLayoutBuilder.h>
|
#include <GroupLayoutBuilder.h>
|
||||||
#include <TabView.h>
|
#include <TabView.h>
|
||||||
|
|
||||||
|
#include <AutoLocker.h>
|
||||||
|
|
||||||
|
#include "DataSource.h"
|
||||||
|
#include "MainModel.h"
|
||||||
|
#include "MainModelLoader.h"
|
||||||
|
#include "MessageCodes.h"
|
||||||
#include "ThreadsPage.h"
|
#include "ThreadsPage.h"
|
||||||
|
|
||||||
|
|
||||||
MainWindow::MainWindow()
|
MainWindow::MainWindow(DataSource* dataSource)
|
||||||
:
|
:
|
||||||
BWindow(BRect(50, 50, 599, 499), "DebugAnalyzer", B_DOCUMENT_WINDOW,
|
BWindow(BRect(50, 50, 599, 499), "DebugAnalyzer", B_DOCUMENT_WINDOW,
|
||||||
B_ASYNCHRONOUS_CONTROLS),
|
B_ASYNCHRONOUS_CONTROLS),
|
||||||
fMainTabView(NULL)
|
fMainTabView(NULL),
|
||||||
|
fModel(NULL),
|
||||||
|
fModelLoader(NULL)
|
||||||
{
|
{
|
||||||
BGroupLayout* rootLayout = new BGroupLayout(B_VERTICAL);
|
BGroupLayout* rootLayout = new BGroupLayout(B_VERTICAL);
|
||||||
SetLayout(rootLayout);
|
SetLayout(rootLayout);
|
||||||
|
@ -27,9 +38,83 @@ MainWindow::MainWindow()
|
||||||
|
|
||||||
fMainTabView->AddTab(new BView("Teams", 0));
|
fMainTabView->AddTab(new BView("Teams", 0));
|
||||||
fMainTabView->AddTab(new ThreadsPage);
|
fMainTabView->AddTab(new ThreadsPage);
|
||||||
|
|
||||||
|
// create a model loader, if we have a data source
|
||||||
|
if (dataSource != NULL)
|
||||||
|
fModelLoader = new MainModelLoader(dataSource, BMessenger(this), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MainWindow::~MainWindow()
|
MainWindow::~MainWindow()
|
||||||
{
|
{
|
||||||
|
delete fModelLoader;
|
||||||
|
delete fModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MainWindow::MessageReceived(BMessage* message)
|
||||||
|
{
|
||||||
|
switch (message->what) {
|
||||||
|
case MSG_MODEL_LOADED_SUCCESSFULLY:
|
||||||
|
{
|
||||||
|
printf("MSG_MODEL_LOADED_SUCCESSFULLY\n");
|
||||||
|
MainModel* model = fModelLoader->DetachModel();
|
||||||
|
delete fModelLoader;
|
||||||
|
fModelLoader = NULL;
|
||||||
|
|
||||||
|
_SetModel(model);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MSG_MODEL_LOADED_FAILED:
|
||||||
|
case MSG_MODEL_LOADED_ABORTED:
|
||||||
|
{
|
||||||
|
printf("MSG_MODEL_LOADED_FAILED/MSG_MODEL_LOADED_ABORTED\n");
|
||||||
|
delete fModelLoader;
|
||||||
|
fModelLoader = NULL;
|
||||||
|
// TODO: User feedback (in failed case)!
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
BWindow::MessageReceived(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MainWindow::Quit()
|
||||||
|
{
|
||||||
|
be_app->PostMessage(MSG_WINDOW_QUIT);
|
||||||
|
|
||||||
|
BWindow::Quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MainWindow::Show()
|
||||||
|
{
|
||||||
|
BWindow::Show();
|
||||||
|
|
||||||
|
AutoLocker<MainWindow> locker;
|
||||||
|
|
||||||
|
if (fModelLoader == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
status_t error = fModelLoader->StartLoading();
|
||||||
|
if (error != B_OK) {
|
||||||
|
delete fModelLoader;
|
||||||
|
fModelLoader = NULL;
|
||||||
|
// TODO: User feedback!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MainWindow::_SetModel(MainModel* model)
|
||||||
|
{
|
||||||
|
delete fModel;
|
||||||
|
fModel = model;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,15 +9,29 @@
|
||||||
|
|
||||||
|
|
||||||
class BTabView;
|
class BTabView;
|
||||||
|
class DataSource;
|
||||||
|
class MainModel;
|
||||||
|
class MainModelLoader;
|
||||||
|
|
||||||
|
|
||||||
class MainWindow : public BWindow {
|
class MainWindow : public BWindow {
|
||||||
public:
|
public:
|
||||||
MainWindow();
|
MainWindow(DataSource* dataSource);
|
||||||
virtual ~MainWindow();
|
virtual ~MainWindow();
|
||||||
|
|
||||||
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
|
||||||
|
virtual void Quit();
|
||||||
|
|
||||||
|
virtual void Show();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _SetModel(MainModel* model);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BTabView* fMainTabView;
|
BTabView* fMainTabView;
|
||||||
|
MainModel* fModel;
|
||||||
|
MainModelLoader* fModelLoader;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,11 @@
|
||||||
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MSG_MODEL_LOADED_SUCCESSFULLY = 'mlsc',
|
MSG_MODEL_LOADED_SUCCESSFULLY = 'mlsc',
|
||||||
MSG_MODEL_LOADED_FAILED = 'mlfl',
|
MSG_MODEL_LOADED_FAILED = 'mlfl',
|
||||||
MSG_MODEL_LOADED_ABORTED = 'mlab'
|
MSG_MODEL_LOADED_ABORTED = 'mlab',
|
||||||
|
|
||||||
|
MSG_WINDOW_QUIT = 'wiqt'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue