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