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 13 AbstractModelLoader::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 26 AbstractModelLoader::~AbstractModelLoader() 27 { 28 } 29 30 31 status_t 32 AbstractModelLoader::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 64 void 65 AbstractModelLoader::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 84 void 85 AbstractModelLoader::Delete() 86 { 87 Abort(true); 88 delete this; 89 } 90 91 92 /*! Called from StartLoading() with the lock held. 93 */ 94 status_t 95 AbstractModelLoader::PrepareForLoading() 96 { 97 return B_OK; 98 } 99 100 101 status_t 102 AbstractModelLoader::Load() 103 { 104 return B_OK; 105 } 106 107 108 /*! Called after loading Load() is done with the lock held. 109 */ 110 void 111 AbstractModelLoader::FinishLoading(bool success) 112 { 113 } 114 115 116 void 117 AbstractModelLoader::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 130 AbstractModelLoader::_LoaderEntry(void* data) 131 { 132 return ((AbstractModelLoader*)data)->_Loader(); 133 } 134 135 136 status_t 137 AbstractModelLoader::_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