xref: /haiku/src/apps/debuganalyzer/model_loader/AbstractModelLoader.cpp (revision 64d5660eab5c2e8e4b7f3c8287b6c7a1c07ef968)
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 
AbstractModelLoader(const BMessenger & target,void * targetCookie)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 
~AbstractModelLoader()26 AbstractModelLoader::~AbstractModelLoader()
27 {
28 }
29 
30 
31 status_t
StartLoading()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
Abort(bool wait)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
Delete()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
PrepareForLoading()95 AbstractModelLoader::PrepareForLoading()
96 {
97 	return B_OK;
98 }
99 
100 
101 status_t
Load()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
FinishLoading(bool success)111 AbstractModelLoader::FinishLoading(bool success)
112 {
113 }
114 
115 
116 void
NotifyTarget(bool success)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
_LoaderEntry(void * data)130 AbstractModelLoader::_LoaderEntry(void* data)
131 {
132 	return ((AbstractModelLoader*)data)->_Loader();
133 }
134 
135 
136 status_t
_Loader()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