haiku/src/apps/debuganalyzer/model_loader/AbstractModelLoader.cpp

151 lines
2.3 KiB
C++

/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "AbstractModelLoader.h"
#include <AutoLocker.h>
#include "MessageCodes.h"
AbstractModelLoader::AbstractModelLoader(const BMessenger& target,
void* targetCookie)
:
fLock("main model loader"),
fTarget(target),
fTargetCookie(targetCookie),
fLoaderThread(-1),
fLoading(false),
fAborted(false)
{
}
AbstractModelLoader::~AbstractModelLoader()
{
}
status_t
AbstractModelLoader::StartLoading()
{
// check initialization
status_t error = fLock.InitCheck();
if (error != B_OK)
return error;
AutoLocker<BLocker> locker(fLock);
if (fLoading)
return B_BAD_VALUE;
// prepare for loading
error = PrepareForLoading();
if (error != B_OK)
return error;
// spawn the loader thread
fLoaderThread = spawn_thread(&_LoaderEntry, "model loader",
B_NORMAL_PRIORITY, this);
if (fLoaderThread < 0)
return fLoaderThread;
fLoading = true;
fAborted = false;
resume_thread(fLoaderThread);
return B_OK;
}
void
AbstractModelLoader::Abort(bool wait)
{
AutoLocker<BLocker> locker(fLock);
if (fLoaderThread < 0)
return;
thread_id thread = fLoaderThread;
if (fLoading)
fAborted = true;
locker.Unlock();
if (wait)
wait_for_thread(thread, NULL);
}
void
AbstractModelLoader::Delete()
{
Abort(true);
delete this;
}
/*! Called from StartLoading() with the lock held.
*/
status_t
AbstractModelLoader::PrepareForLoading()
{
return B_OK;
}
status_t
AbstractModelLoader::Load()
{
return B_OK;
}
/*! Called after loading Load() is done with the lock held.
*/
void
AbstractModelLoader::FinishLoading(bool success)
{
}
void
AbstractModelLoader::NotifyTarget(bool success)
{
BMessage message(success
? MSG_MODEL_LOADED_SUCCESSFULLY
: fAborted ? MSG_MODEL_LOADED_ABORTED : MSG_MODEL_LOADED_FAILED);
message.AddPointer("loader", this);
message.AddPointer("targetCookie", fTargetCookie);
fTarget.SendMessage(&message);
}
/*static*/ status_t
AbstractModelLoader::_LoaderEntry(void* data)
{
return ((AbstractModelLoader*)data)->_Loader();
}
status_t
AbstractModelLoader::_Loader()
{
bool success = Load() == B_OK;
// clean up and notify the target
AutoLocker<BLocker> locker(fLock);
FinishLoading(success);
NotifyTarget(success);
fLoading = false;
return B_OK;
}