~ogre-team/testogre/soc09-samples

« back to all changes in this revision

Viewing changes to OgreMain/src/OgreResourceBackgroundQueue.cpp

  • Committer: sinbad
  • Date: 2009-09-27 15:13:33 UTC
  • Revision ID: svn-v4:8631bf8a-c64b-0410-883c-f3eb003322f7:branches/soc09-samples:9116
Merged trunk changes to r9109 into soc09-samples so that we can perform platform tests & refine
Once again a staged commit because of crappy server performance

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
    (Object-oriented Graphics Rendering Engine)
5
5
For the latest info, see http://www.ogre3d.org/
6
6
 
7
 
Copyright (c) 2000-2006 Torus Knot Software Ltd
8
 
Also see acknowledgements in Readme.html
9
 
 
10
 
This program is free software; you can redistribute it and/or modify it under
11
 
the terms of the GNU Lesser General Public License as published by the Free Software
12
 
Foundation; either version 2 of the License, or (at your option) any later
13
 
version.
14
 
 
15
 
This program is distributed in the hope that it will be useful, but WITHOUT
16
 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17
 
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
 
 
19
 
You should have received a copy of the GNU Lesser General Public License along with
20
 
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21
 
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22
 
http://www.gnu.org/copyleft/lesser.txt.
23
 
 
24
 
You may alternatively use this source under the terms of a specific version of
25
 
the OGRE Unrestricted License provided you have obtained such a license from
26
 
Torus Knot Software Ltd.
 
7
Copyright (c) 2000-2009 Torus Knot Software Ltd
 
8
 
 
9
Permission is hereby granted, free of charge, to any person obtaining a copy
 
10
of this software and associated documentation files (the "Software"), to deal
 
11
in the Software without restriction, including without limitation the rights
 
12
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
13
copies of the Software, and to permit persons to whom the Software is
 
14
furnished to do so, subject to the following conditions:
 
15
 
 
16
The above copyright notice and this permission notice shall be included in
 
17
all copies or substantial portions of the Software.
 
18
 
 
19
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
20
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
21
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
22
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
23
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
24
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
25
THE SOFTWARE.
27
26
-----------------------------------------------------------------------------
28
27
*/
29
28
#include "OgreStableHeaders.h"
37
36
 
38
37
namespace Ogre {
39
38
 
 
39
        // Note, no locks are required here anymore because all of the parallelisation
 
40
        // is now contained in WorkQueue - this class is entirely single-threaded
 
41
 
 
42
#define RESOURCE_CHANNEL Root::MAX_USER_WORKQUEUE_CHANNEL + 1
 
43
 
40
44
        //------------------------------------------------------------------------
41
45
    //-----------------------------------------------------------------------
42
46
    template<> ResourceBackgroundQueue* Singleton<ResourceBackgroundQueue>::ms_Singleton = 0;
51
55
    //-----------------------------------------------------------------------   
52
56
        //------------------------------------------------------------------------
53
57
        ResourceBackgroundQueue::ResourceBackgroundQueue()
54
 
                :mNextTicketID(0), mStartThread(true), mThread(0)
55
 
#if OGRE_THREAD_SUPPORT
56
 
        , mShuttingDown(false)
57
 
#endif
58
58
        {
59
59
        }
60
60
        //------------------------------------------------------------------------
62
62
        {
63
63
                shutdown();
64
64
        }
65
 
        //------------------------------------------------------------------------
66
 
        void ResourceBackgroundQueue::initialise(void)
 
65
        //---------------------------------------------------------------------
 
66
        void ResourceBackgroundQueue::initialise()
67
67
        {
68
 
#if OGRE_THREAD_SUPPORT
69
 
                if (mStartThread)
70
 
                {
71
 
                        {
72
 
                                OGRE_LOCK_AUTO_MUTEX
73
 
                                mShuttingDown = false;
74
 
                        }
75
 
 
76
 
#if OGRE_THREAD_SUPPORT == 1
77
 
                        RenderSystem* rs = Root::getSingleton().getRenderSystem();
78
 
#endif
79
 
 
80
 
                        LogManager::getSingleton().logMessage(
81
 
                                "ResourceBackgroundQueue - threading enabled, starting own thread");
82
 
                        {
83
 
                                OGRE_LOCK_MUTEX_NAMED(initMutex, initLock)
84
 
 
85
 
#if OGRE_THREAD_SUPPORT == 1
86
 
                                // Call thread creation pre-hook
87
 
                                rs->preExtraThreadsStarted();
88
 
#endif
89
 
 
90
 
                                mThread = OGRE_NEW_T(boost::thread, MEMCATEGORY_RESOURCE)(
91
 
                                        boost::function0<void>(&ResourceBackgroundQueue::threadFunc));
92
 
                                // Wait for init to finish before allowing main thread to continue
93
 
                                // this releases the initMutex until notified
94
 
                                OGRE_THREAD_WAIT(initSync, initLock)
95
 
 
96
 
#if OGRE_THREAD_SUPPORT == 1
97
 
                                // Call thread creation post-hook
98
 
                                rs->postExtraThreadsStarted();
99
 
#endif
100
 
                        }
101
 
 
102
 
                }
103
 
                else
104
 
                {
105
 
                        LogManager::getSingleton().logMessage(
106
 
                                "ResourceBackgroundQueue - threading enabled, user thread");
107
 
                }
108
 
#else
109
 
                LogManager::getSingleton().logMessage(
110
 
                        "ResourceBackgroundQueue - threading disabled");        
111
 
#endif
 
68
                Root::getSingleton().getWorkQueue()->addResponseHandler(RESOURCE_CHANNEL, this);
 
69
                Root::getSingleton().getWorkQueue()->addRequestHandler(RESOURCE_CHANNEL, this);
112
70
        }
113
 
        //------------------------------------------------------------------------
114
 
        void ResourceBackgroundQueue::shutdown(void)
 
71
        //---------------------------------------------------------------------
 
72
        void ResourceBackgroundQueue::shutdown()
115
73
        {
116
 
#if OGRE_THREAD_SUPPORT
117
 
                if (mThread)
118
 
                {
119
 
                        // Put a shutdown request on the queue
120
 
                        Request req;
121
 
                        req.type = RT_SHUTDOWN;
122
 
                        addRequest(req);
123
 
                        // Wait for thread to finish
124
 
                        mThread->join();
125
 
                        OGRE_DELETE_T(mThread, thread, MEMCATEGORY_RESOURCE);
126
 
                        mThread = 0;
127
 
                        mRequestQueue.clear();
128
 
                        mRequestTicketMap.clear();
129
 
                }
130
 
#endif
 
74
                Root::getSingleton().getWorkQueue()->removeRequestHandler(RESOURCE_CHANNEL, this);
 
75
                Root::getSingleton().getWorkQueue()->removeResponseHandler(RESOURCE_CHANNEL, this);
131
76
        }
132
77
        //------------------------------------------------------------------------
133
78
        BackgroundProcessTicket ResourceBackgroundQueue::initialiseResourceGroup(
134
79
                const String& name, ResourceBackgroundQueue::Listener* listener)
135
80
        {
136
81
#if OGRE_THREAD_SUPPORT
137
 
                if (!mThread && mStartThread)
138
 
                {
139
 
                        OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
140
 
                                "Thread not initialised",
141
 
                                "ResourceBackgroundQueue::initialiseResourceGroup");
142
 
                }
143
82
                // queue a request
144
 
                Request req;
 
83
                ResourceRequest req;
145
84
                req.type = RT_INITIALISE_GROUP;
146
85
                req.groupName = name;
147
86
                req.listener = listener;
158
97
                ResourceBackgroundQueue::Listener* listener)
159
98
        {
160
99
#if OGRE_THREAD_SUPPORT
161
 
                if (!mThread && mStartThread)
162
 
                {
163
 
                        OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
164
 
                                "Thread not initialised",
165
 
                                "ResourceBackgroundQueue::initialiseAllResourceGroups");
166
 
                }
167
100
                // queue a request
168
 
                Request req;
 
101
                ResourceRequest req;
169
102
                req.type = RT_INITIALISE_ALL_GROUPS;
170
103
                req.listener = listener;
171
104
                return addRequest(req);
180
113
                const String& name, ResourceBackgroundQueue::Listener* listener)
181
114
        {
182
115
#if OGRE_THREAD_SUPPORT
183
 
                if (!mThread && mStartThread)
184
 
                {
185
 
                        OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
186
 
                                "Thread not initialised",
187
 
                                "ResourceBackgroundQueue::prepareResourceGroup");
188
 
                }
189
116
                // queue a request
190
 
                Request req;
 
117
                ResourceRequest req;
191
118
                req.type = RT_PREPARE_GROUP;
192
119
                req.groupName = name;
193
120
                req.listener = listener;
203
130
                const String& name, ResourceBackgroundQueue::Listener* listener)
204
131
        {
205
132
#if OGRE_THREAD_SUPPORT
206
 
                if (!mThread && mStartThread)
207
 
                {
208
 
                        OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
209
 
                                "Thread not initialised",
210
 
                                "ResourceBackgroundQueue::loadResourceGroup");
211
 
                }
212
133
                // queue a request
213
 
                Request req;
 
134
                ResourceRequest req;
214
135
                req.type = RT_LOAD_GROUP;
215
136
                req.groupName = name;
216
137
                req.listener = listener;
230
151
                ResourceBackgroundQueue::Listener* listener)
231
152
        {
232
153
#if OGRE_THREAD_SUPPORT
233
 
                if (!mThread && mStartThread)
234
 
                {
235
 
                        OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
236
 
                                "Thread not initialised",
237
 
                                "ResourceBackgroundQueue::prepare");
238
 
                }
239
154
                // queue a request
240
 
                Request req;
 
155
                ResourceRequest req;
241
156
                req.type = RT_PREPARE_RESOURCE;
242
157
                req.resourceType = resType;
243
158
                req.resourceName = name;
264
179
                ResourceBackgroundQueue::Listener* listener)
265
180
        {
266
181
#if OGRE_THREAD_SUPPORT
267
 
                if (!mThread && mStartThread)
268
 
                {
269
 
                        OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
270
 
                                "Thread not initialised",
271
 
                                "ResourceBackgroundQueue::load");
272
 
                }
273
182
                // queue a request
274
 
                Request req;
 
183
                ResourceRequest req;
275
184
                req.type = RT_LOAD_RESOURCE;
276
185
                req.resourceType = resType;
277
186
                req.resourceName = name;
294
203
                const String& resType, const String& name, Listener* listener)
295
204
        {
296
205
#if OGRE_THREAD_SUPPORT
297
 
                if (!mThread && mStartThread)
298
 
                {
299
 
                        OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
300
 
                                "Thread not initialised",
301
 
                                "ResourceBackgroundQueue::unload");
302
 
                }
303
206
                // queue a request
304
 
                Request req;
 
207
                ResourceRequest req;
305
208
                req.type = RT_UNLOAD_RESOURCE;
306
209
                req.resourceType = resType;
307
210
                req.resourceName = name;
321
224
                const String& resType, ResourceHandle handle, Listener* listener)
322
225
        {
323
226
#if OGRE_THREAD_SUPPORT
324
 
                if (!mThread && mStartThread)
325
 
                {
326
 
                        OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
327
 
                                "Thread not initialised",
328
 
                                "ResourceBackgroundQueue::unload");
329
 
                }
330
227
                // queue a request
331
 
                Request req;
 
228
                ResourceRequest req;
332
229
                req.type = RT_UNLOAD_RESOURCE;
333
230
                req.resourceType = resType;
334
231
                req.resourceHandle = handle;
348
245
                const String& name, Listener* listener)
349
246
        {
350
247
#if OGRE_THREAD_SUPPORT
351
 
                if (!mThread && mStartThread)
352
 
                {
353
 
                        OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
354
 
                                "Thread not initialised",
355
 
                                "ResourceBackgroundQueue::unloadResourceGroup");
356
 
                }
357
248
                // queue a request
358
 
                Request req;
 
249
                ResourceRequest req;
359
250
                req.type = RT_UNLOAD_GROUP;
360
251
                req.groupName = name;
361
252
                req.listener = listener;
371
262
        bool ResourceBackgroundQueue::isProcessComplete(
372
263
                        BackgroundProcessTicket ticket)
373
264
        {
374
 
                // Lock
375
 
                OGRE_LOCK_AUTO_MUTEX
376
 
 
377
 
                return mRequestTicketMap.find(ticket) == mRequestTicketMap.end();
378
 
        }
379
 
        //------------------------------------------------------------------------
380
 
#if OGRE_THREAD_SUPPORT
381
 
        BackgroundProcessTicket ResourceBackgroundQueue::addRequest(Request& req)
382
 
        {
383
 
                // Lock
384
 
                OGRE_LOCK_AUTO_MUTEX
385
 
 
386
 
                req.ticketID = ++mNextTicketID;
387
 
                mRequestQueue.push_back(req);
388
 
                Request* requestInList = &(mRequestQueue.back());
389
 
                mRequestTicketMap[req.ticketID] = requestInList;
390
 
 
391
 
                // Notify to wake up loading thread
392
 
                OGRE_THREAD_NOTIFY_ONE(mCondition)
393
 
 
394
 
                return req.ticketID;
395
 
        }
396
 
        //------------------------------------------------------------------------
397
 
        void ResourceBackgroundQueue::threadFunc(void)
398
 
        {
399
 
                // Background thread implementation 
400
 
                // Static (since no params allowed), so get instance
401
 
                ResourceBackgroundQueue& queueInstance = 
402
 
                        ResourceBackgroundQueue::getSingleton();
403
 
 
404
 
                LogManager::getSingleton().logMessage("ResourceBackgroundQueue - thread starting.");
405
 
 
406
 
                // Initialise the thread
407
 
                queueInstance._initThread();
408
 
 
409
 
                // Spin forever until we're told to shut down
410
 
                while (!queueInstance.mShuttingDown)
411
 
                {
412
 
                        // Our thread will just wait when there is nothing on the queue
413
 
                        // _doNextQueuedBackgroundProcess won't do this since the thread
414
 
                        // may be shared
415
 
 
416
 
            // Manual scope block just to define scope of lock
417
 
            {
418
 
                // Lock; note that 'mCondition.wait()' will free the lock
419
 
                boost::recursive_mutex::scoped_lock queueLock(
420
 
                    queueInstance.OGRE_AUTO_MUTEX_NAME);
421
 
                if (queueInstance.mRequestQueue.empty())
422
 
                {
423
 
                    // frees lock and suspends the thread
424
 
                    queueInstance.mCondition.wait(queueLock);
425
 
                }
426
 
                // When we get back here, it's because we've been notified 
427
 
                // and thus the thread as been woken up. Lock has also been
428
 
                // re-acquired.
429
 
            } // release lock so queueing can be done while we process one request
430
 
 
431
 
                        queueInstance._doNextQueuedBackgroundProcess();
432
 
 
433
 
 
434
 
                }
435
 
 
436
 
                LogManager::getSingleton().logMessage("ResourceBackgroundQueue - thread stopped.");
437
 
 
438
 
        
 
265
                return mOutstandingRequestSet.find(ticket) == mOutstandingRequestSet.end();
 
266
        }
 
267
        //------------------------------------------------------------------------
 
268
        BackgroundProcessTicket ResourceBackgroundQueue::addRequest(ResourceRequest& req)
 
269
        {
 
270
                WorkQueue* queue = Root::getSingleton().getWorkQueue();
 
271
 
 
272
                Any data(req);
 
273
 
 
274
                WorkQueue::RequestID requestID = 
 
275
                        queue->addRequest(RESOURCE_CHANNEL, (uint16)req.type, data);
 
276
 
 
277
 
 
278
                mOutstandingRequestSet.insert(requestID);
 
279
 
 
280
                return requestID;
 
281
        }
 
282
        //-----------------------------------------------------------------------
 
283
        WorkQueue::Response* ResourceBackgroundQueue::handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ)
 
284
        {
 
285
 
 
286
                ResourceRequest resreq = any_cast<ResourceRequest>(req->getData());
439
287
                
440
 
        }
441
 
#endif
442
 
        //-----------------------------------------------------------------------
443
 
        void ResourceBackgroundQueue::_initThread()
444
 
        {
445
 
                // Register the calling thread with RenderSystem
446
 
                // Note how we assume only one thread is processing the queue
447
 
#if OGRE_THREAD_SUPPORT == 1
448
 
                Root::getSingleton().getRenderSystem()->registerThread();
449
 
#endif
450
 
                {
451
 
                        // notify waiting thread(s)
452
 
                        OGRE_LOCK_MUTEX(initMutex)
453
 
                        OGRE_THREAD_NOTIFY_ALL(initSync)
454
 
                }
455
 
 
456
 
        }
457
 
        //-----------------------------------------------------------------------
458
 
        bool ResourceBackgroundQueue::_doNextQueuedBackgroundProcess()
459
 
        {
460
 
 
461
 
                Request* req;
462
 
 
463
 
                // Manual scope block just to define scope of lock
464
 
                {
465
 
                        OGRE_LOCK_AUTO_MUTEX
466
 
                        // return false if nothing in the queue
467
 
                        if (mRequestQueue.empty())
468
 
                                return false;
469
 
 
470
 
                        // Process one request
471
 
                        req = &(mRequestQueue.front());
472
 
                } // release lock so queueing can be done while we process one request
473
 
                // use of std::list means that references guarateed to remain valid
474
 
                // we only allow one background thread
475
 
 
476
288
                ResourceManager* rm = 0;
 
289
                Resource* resource = 0;
477
290
                try
478
291
                {
479
292
 
480
 
                        switch (req->type)
 
293
                        switch (resreq.type)
481
294
                        {
482
295
                        case RT_INITIALISE_GROUP:
483
296
                                ResourceGroupManager::getSingleton().initialiseResourceGroup(
484
 
                                        req->groupName);
 
297
                                        resreq.groupName);
485
298
                                break;
486
299
                        case RT_INITIALISE_ALL_GROUPS:
487
300
                                ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
488
301
                                break;
489
302
                        case RT_PREPARE_GROUP:
490
303
                                ResourceGroupManager::getSingleton().prepareResourceGroup(
491
 
                                        req->groupName);
 
304
                                        resreq.groupName);
492
305
                                break;
493
306
                        case RT_LOAD_GROUP:
494
307
        #if OGRE_THREAD_SUPPORT == 2
495
308
                                ResourceGroupManager::getSingleton().prepareResourceGroup(
496
 
                                        req->groupName);
 
309
                                        resreq.groupName);
497
310
        #else
498
311
                                ResourceGroupManager::getSingleton().loadResourceGroup(
499
 
                                        req->groupName);
 
312
                                        resreq.groupName);
500
313
        #endif
501
314
                                break;
502
315
                        case RT_UNLOAD_GROUP:
503
316
                                ResourceGroupManager::getSingleton().unloadResourceGroup(
504
 
                                        req->groupName);
 
317
                                        resreq.groupName);
505
318
                                break;
506
319
                        case RT_PREPARE_RESOURCE:
507
320
                                rm = ResourceGroupManager::getSingleton()._getResourceManager(
508
 
                                        req->resourceType);
509
 
                                rm->prepare(req->resourceName, req->groupName, req->isManual, 
510
 
                                        req->loader, req->loadParams);
 
321
                                        resreq.resourceType);
 
322
                                resource = rm->prepare(resreq.resourceName, resreq.groupName, resreq.isManual, 
 
323
                                        resreq.loader, resreq.loadParams).get();
511
324
                                break;
512
325
                        case RT_LOAD_RESOURCE:
513
326
                                rm = ResourceGroupManager::getSingleton()._getResourceManager(
514
 
                                        req->resourceType);
 
327
                                        resreq.resourceType);
515
328
        #if OGRE_THREAD_SUPPORT == 2
516
 
                                rm->prepare(req->resourceName, req->groupName, req->isManual, 
517
 
                                        req->loader, req->loadParams);
 
329
                                resource = rm->prepare(resreq.resourceName, resreq.groupName, resreq.isManual, 
 
330
                                        resreq.loader, resreq.loadParams).get();
518
331
        #else
519
 
                                rm->load(req->resourceName, req->groupName, req->isManual, 
520
 
                                        req->loader, req->loadParams);
 
332
                                resource = rm->load(resreq.resourceName, resreq.groupName, resreq.isManual, 
 
333
                                        resreq.loader, resreq.loadParams).get();
521
334
        #endif
522
335
                                break;
523
336
                        case RT_UNLOAD_RESOURCE:
524
337
                                rm = ResourceGroupManager::getSingleton()._getResourceManager(
525
 
                                        req->resourceType);
526
 
                                if (req->resourceName.empty())
527
 
                                        rm->unload(req->resourceHandle);
 
338
                                        resreq.resourceType);
 
339
                                if (resreq.resourceName.empty())
 
340
                                        rm->unload(resreq.resourceHandle);
528
341
                                else
529
 
                                        rm->unload(req->resourceName);
530
 
                                break;
531
 
                        case RT_SHUTDOWN:
532
 
                                // That's all folks
533
 
        #if OGRE_THREAD_SUPPORT
534
 
                                mShuttingDown = true;
535
 
        #if OGRE_THREAD_SUPPORT == 1
536
 
                                Root::getSingleton().getRenderSystem()->unregisterThread();
537
 
        #endif
538
 
        #endif
 
342
                                        rm->unload(resreq.resourceName);
539
343
                                break;
540
344
                        };
541
345
                }
542
346
                catch (Exception& e)
543
347
                {
544
 
                        req->result.error = true;
545
 
                        req->result.message = e.getFullDescription();
546
 
                }
547
 
 
548
 
                // Queue notification (don't do shutdown since not needed & listeners 
549
 
                // might be being destroyed too
550
 
                if (req->listener && req->type != RT_SHUTDOWN)
551
 
                {
552
 
                        // Fire in-thread notification first
553
 
                        req->listener->operationCompletedInThread(req->ticketID, req->result);
554
 
                        // Then queue main thread notification
555
 
                        queueFireBackgroundOperationComplete(req);
556
 
                }
557
 
 
558
 
 
559
 
                {
560
 
                        // re-lock to consume completed request
561
 
                        OGRE_LOCK_AUTO_MUTEX
562
 
 
563
 
                        // Consume the ticket
564
 
                        mRequestTicketMap.erase(req->ticketID);
565
 
                        mRequestQueue.pop_front();
566
 
                }
567
 
 
568
 
                return true;
569
 
 
570
 
        }
571
 
        //-----------------------------------------------------------------------
572
 
        void ResourceBackgroundQueue::_queueFireBackgroundLoadingComplete(Resource* res)
573
 
        {
574
 
                OGRE_LOCK_MUTEX(mNotificationQueueMutex);
575
 
                mNotificationQueue.push_back(QueuedNotification(res,true));
576
 
 
577
 
        }
578
 
        //-----------------------------------------------------------------------
579
 
        void ResourceBackgroundQueue::_queueFireBackgroundPreparingComplete(Resource* res)
580
 
        {
581
 
                OGRE_LOCK_MUTEX(mNotificationQueueMutex);
582
 
                mNotificationQueue.push_back(QueuedNotification(res,false));
583
 
 
584
 
        }
585
 
        //-----------------------------------------------------------------------
586
 
        void ResourceBackgroundQueue::queueFireBackgroundOperationComplete(
587
 
                ResourceBackgroundQueue::Request* req)
588
 
        {
589
 
                OGRE_LOCK_MUTEX(mNotificationQueueMutex);
590
 
                mNotificationQueue.push_back(QueuedNotification(*req));
 
348
                        resreq.result.error = true;
 
349
                        resreq.result.message = e.getFullDescription();
 
350
 
 
351
                        // return error response
 
352
                        ResourceResponse resresp(resource, resreq);
 
353
                        return OGRE_NEW WorkQueue::Response(req, false, Any(resresp), e.getFullDescription());
 
354
                }
 
355
 
 
356
 
 
357
                // success
 
358
                resreq.result.error = false;
 
359
                ResourceResponse resresp(resource, resreq);
 
360
                return OGRE_NEW WorkQueue::Response(req, true, Any(resresp));
 
361
 
591
362
        }
592
363
        //------------------------------------------------------------------------
593
 
        void ResourceBackgroundQueue::_fireOnFrameCallbacks()
 
364
        void ResourceBackgroundQueue::handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ)
594
365
        {
595
 
                OGRE_LOCK_MUTEX(mNotificationQueueMutex);
596
 
                for (NotificationQueue::iterator i = mNotificationQueue.begin();
597
 
                        i != mNotificationQueue.end(); ++i)
 
366
                if (res->succeeded())
598
367
                {
599
 
                        if (i->resource) {
600
 
                if (i->load) {
601
 
                    i->resource->_fireLoadingComplete();
602
 
                } else {
603
 
                    i->resource->_firePreparingComplete();
604
 
                }
605
 
                        } else {
606
 
                const ResourceBackgroundQueue::Request &r = i->req;
 
368
                        ResourceResponse resresp = any_cast<ResourceResponse>(res->getData());
 
369
 
 
370
                        // Complete full loading in main thread if semithreading
 
371
                        const ResourceRequest& req = resresp.request;
607
372
#if OGRE_THREAD_SUPPORT == 2
608
 
                if (r.type==RT_LOAD_RESOURCE) {
609
 
                    ResourceManager *rm = ResourceGroupManager::getSingleton()
610
 
                                            ._getResourceManager(r.resourceType);
611
 
                    rm->load(r.resourceName, r.groupName, r.isManual, r.loader, r.loadParams);
612
 
                } else if (r.type==RT_LOAD_GROUP) {
613
 
                    ResourceGroupManager::getSingleton().loadResourceGroup(r.groupName);
614
 
                }
 
373
                        // These load commands would have been downgraded to prepare() for the background
 
374
                        if (req.type == RT_LOAD_RESOURCE)
 
375
                        {
 
376
                                ResourceManager *rm = ResourceGroupManager::getSingleton()
 
377
                                        ._getResourceManager(req.resourceType);
 
378
                                rm->load(req.resourceName, req.groupName, req.isManual, req.loader, req.loadParams);
 
379
                        } 
 
380
                        else if (req.type == RT_LOAD_GROUP) 
 
381
                        {
 
382
                                ResourceGroupManager::getSingleton().loadResourceGroup(req.groupName);
 
383
                        }
615
384
#endif
616
 
                r.listener->operationCompleted(r.ticketID, r.result);
617
 
            }
 
385
                        mOutstandingRequestSet.erase(res->getRequest()->getID());
 
386
 
 
387
                        // Call resource listener
 
388
                        if (resresp.resource) 
 
389
                        {
 
390
 
 
391
                                if (req.type == RT_LOAD_RESOURCE) 
 
392
                                {
 
393
                                        resresp.resource->_fireLoadingComplete();
 
394
                                } 
 
395
                                else 
 
396
                                {
 
397
                                        resresp.resource->_firePreparingComplete();
 
398
                                }
 
399
                        } 
 
400
 
 
401
                        // Call queue listener
 
402
                        if (req.listener)
 
403
                                req.listener->operationCompleted(res->getRequest()->getID(), req.result);
 
404
 
618
405
                }
619
 
                mNotificationQueue.clear();
620
 
 
621
406
        }
622
407
        //------------------------------------------------------------------------
623
408