1/* 2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6#include "AbstractModelLoader.h" 7 8#include <AutoLocker.h> 9 10#include "MessageCodes.h" 11 12 13AbstractModelLoader::AbstractModelLoader(const BMessenger& target, 14 void* targetCookie) 15 : 16 fLock("main model loader"), 17 fTarget(target), 18 fTargetCookie(targetCookie), 19 fLoaderThread(-1), 20 fLoading(false), 21 fAborted(false) 22{ 23} 24 25 26AbstractModelLoader::~AbstractModelLoader() 27{ 28} 29 30 31status_t 32AbstractModelLoader::StartLoading() 33{ 34 // check initialization 35 status_t error = fLock.InitCheck(); 36 if (error != B_OK) 37 return error; 38 39 AutoLocker<BLocker> locker(fLock); 40 41 if (fLoading) 42 return B_BAD_VALUE; 43 44 // prepare for loading 45 error = PrepareForLoading(); 46 if (error != B_OK) 47 return error; 48 49 // spawn the loader thread 50 fLoaderThread = spawn_thread(&_LoaderEntry, "model loader", 51 B_NORMAL_PRIORITY, this); 52 if (fLoaderThread < 0) 53 return fLoaderThread; 54 55 fLoading = true; 56 fAborted = false; 57 58 resume_thread(fLoaderThread); 59 60 return B_OK; 61} 62 63 64void 65AbstractModelLoader::Abort(bool wait) 66{ 67 AutoLocker<BLocker> locker(fLock); 68 69 if (fLoaderThread < 0) 70 return; 71 72 thread_id thread = fLoaderThread; 73 74 if (fLoading) 75 fAborted = true; 76 77 locker.Unlock(); 78 79 if (wait) 80 wait_for_thread(thread, NULL); 81} 82 83 84void 85AbstractModelLoader::Delete() 86{ 87 Abort(true); 88 delete this; 89} 90 91 92/*! Called from StartLoading() with the lock held. 93*/ 94status_t 95AbstractModelLoader::PrepareForLoading() 96{ 97 return B_OK; 98} 99 100 101status_t 102AbstractModelLoader::Load() 103{ 104 return B_OK; 105} 106 107 108/*! Called after loading Load() is done with the lock held. 109*/ 110void 111AbstractModelLoader::FinishLoading(bool success) 112{ 113} 114 115 116void 117AbstractModelLoader::NotifyTarget(bool success) 118{ 119 BMessage message(success 120 ? MSG_MODEL_LOADED_SUCCESSFULLY 121 : fAborted ? MSG_MODEL_LOADED_ABORTED : MSG_MODEL_LOADED_FAILED); 122 123 message.AddPointer("loader", this); 124 message.AddPointer("targetCookie", fTargetCookie); 125 fTarget.SendMessage(&message); 126} 127 128 129/*static*/ status_t 130AbstractModelLoader::_LoaderEntry(void* data) 131{ 132 return ((AbstractModelLoader*)data)->_Loader(); 133} 134 135 136status_t 137AbstractModelLoader::_Loader() 138{ 139 bool success = Load() == B_OK; 140 141 // clean up and notify the target 142 AutoLocker<BLocker> locker(fLock); 143 144 FinishLoading(success); 145 NotifyTarget(success); 146 fLoading = false; 147 148 return B_OK; 149 150} 151