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