source: OGRE/trunk/ogrenew/OgreMain/src/OgreResourceBackgroundQueue.cpp @ 657

Revision 657, 9.1 KB checked in by mattausch, 18 years ago (diff)

added ogre dependencies and patched ogre sources

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25#include "OgreStableHeaders.h"
26#include "OgreResourceBackgroundQueue.h"
27#include "OgreLogManager.h"
28#include "OgreException.h"
29#include "OgreResourceGroupManager.h"
30#include "OgreResourceManager.h"
31
32namespace Ogre {
33
34        //------------------------------------------------------------------------
35    //-----------------------------------------------------------------------
36    template<> ResourceBackgroundQueue* Singleton<ResourceBackgroundQueue>::ms_Singleton = 0;
37    ResourceBackgroundQueue* ResourceBackgroundQueue::getSingletonPtr(void)
38    {
39        return ms_Singleton;
40    }
41    ResourceBackgroundQueue& ResourceBackgroundQueue::getSingleton(void)
42    { 
43        assert( ms_Singleton );  return ( *ms_Singleton ); 
44    }
45    //-----------------------------------------------------------------------   
46        //------------------------------------------------------------------------
47        ResourceBackgroundQueue::ResourceBackgroundQueue()
48                :mNextTicketID(0), mThread(0)
49        {
50        }
51        //------------------------------------------------------------------------
52        ResourceBackgroundQueue::~ResourceBackgroundQueue()
53        {
54                shutdown();
55        }
56        //------------------------------------------------------------------------
57        void ResourceBackgroundQueue::initialise(void)
58        {
59#if OGRE_THREAD_SUPPORT
60                OGRE_LOCK_AUTO_MUTEX
61                mThread = new boost::thread(
62                        boost::function0<void>(&ResourceBackgroundQueue::threadFunc));
63                LogManager::getSingleton().logMessage(
64                        "ResourceBackgroundQueue - threading enabled");
65#else
66                LogManager::getSingleton().logMessage(
67                        "ResourceBackgroundQueue - threading disabled");       
68#endif
69        }
70        //------------------------------------------------------------------------
71        void ResourceBackgroundQueue::shutdown(void)
72        {
73#if OGRE_THREAD_SUPPORT
74                if (mThread)
75                {
76                        // Put a shutdown request on the queue
77                        Request req;
78                        req.type = RT_SHUTDOWN;
79                        addRequest(req);
80                        // Wait for thread to finish
81                        mThread->join();
82                        delete mThread;
83                        mThread = 0;
84                        mRequestQueue.clear();
85                        mRequestTicketMap.clear();
86                }
87#endif
88        }
89        //------------------------------------------------------------------------
90        BackgroundProcessTicket ResourceBackgroundQueue::initialiseResourceGroup(
91                const String& name, ResourceBackgroundQueueListener* listener)
92        {
93#if OGRE_THREAD_SUPPORT
94                if (!mThread)
95                {
96                        OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
97                                "Thread not initialised",
98                                "ResourceBackgroundQueue::initialiseResourceGroup");
99                }
100                // queue a request
101                Request req;
102                req.type = RT_INITIALISE_GROUP;
103                req.groupName = name;
104                req.listener = listener;
105                return addRequest(req);
106#else
107                // synchronous
108                ResourceGroupManager::getSingleton().initialiseResourceGroup(name);
109                return 0;
110#endif
111        }
112        //------------------------------------------------------------------------
113        BackgroundProcessTicket
114        ResourceBackgroundQueue::initialiseAllResourceGroups(
115                ResourceBackgroundQueueListener* listener)
116        {
117#if OGRE_THREAD_SUPPORT
118                if (!mThread)
119                {
120                        OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
121                                "Thread not initialised",
122                                "ResourceBackgroundQueue::initialiseAllResourceGroups");
123                }
124                // queue a request
125                Request req;
126                req.type = RT_INITIALISE_ALL_GROUPS;
127                req.listener = listener;
128                return addRequest(req);
129#else
130                // synchronous
131                ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
132                return 0;
133#endif
134        }
135        //------------------------------------------------------------------------
136        BackgroundProcessTicket ResourceBackgroundQueue::loadResourceGroup(
137                const String& name, ResourceBackgroundQueueListener* listener)
138        {
139#if OGRE_THREAD_SUPPORT
140                if (!mThread)
141                {
142                        OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
143                                "Thread not initialised",
144                                "ResourceBackgroundQueue::loadResourceGroup");
145                }
146                // queue a request
147                Request req;
148                req.type = RT_LOAD_GROUP;
149                req.groupName = name;
150                req.listener = listener;
151                return addRequest(req);
152#else
153                // synchronous
154                ResourceGroupManager::getSingleton().loadResourceGroup(name);
155                return 0;
156#endif
157        }
158        //------------------------------------------------------------------------
159        BackgroundProcessTicket ResourceBackgroundQueue::load(
160                const String& resType, const String& name,
161                const String& group, bool isManual,
162                ManualResourceLoader* loader,
163                const NameValuePairList* loadParams,
164                ResourceBackgroundQueueListener* listener)
165        {
166#if OGRE_THREAD_SUPPORT
167                if (!mThread)
168                {
169                        OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
170                                "Thread not initialised",
171                                "ResourceBackgroundQueue::load");
172                }
173                // queue a request
174                Request req;
175                req.type = RT_LOAD_RESOURCE;
176                req.resourceType = resType;
177                req.resourceName = name;
178                req.groupName = group;
179                req.isManual = isManual;
180                req.loader = loader;
181                req.loadParams = loadParams;
182                req.listener = listener;
183                return addRequest(req);
184#else
185                // synchronous
186                ResourceManager* rm =
187                        ResourceGroupManager::getSingleton()._getResourceManager(resType);
188                rm->load(name, group, isManual, loader, loadParams);
189                return 0;
190#endif
191        }
192        //------------------------------------------------------------------------
193        bool ResourceBackgroundQueue::isProcessComplete(
194                        BackgroundProcessTicket ticket)
195        {
196                return mRequestTicketMap.find(ticket) == mRequestTicketMap.end();
197        }
198        //------------------------------------------------------------------------
199#if OGRE_THREAD_SUPPORT
200        BackgroundProcessTicket ResourceBackgroundQueue::addRequest(Request& req)
201        {
202                // Lock
203                OGRE_LOCK_AUTO_MUTEX
204
205                req.ticketID = ++mNextTicketID;
206                mRequestQueue.push_back(req);
207                Request* requestInList = &(mRequestQueue.back());
208                mRequestTicketMap[req.ticketID] = requestInList;
209
210                // Notify to wake up loading thread
211                mCondition.notify_one();
212
213                return req.ticketID;
214        }
215        //------------------------------------------------------------------------
216        void ResourceBackgroundQueue::threadFunc(void)
217        {
218                // Background thread implementation
219                // Static (since no params allowed), so get instance
220                ResourceBackgroundQueue& queueInstance =
221                        ResourceBackgroundQueue::getSingleton();
222
223                bool shuttingDown = false;
224                // Spin forever until we're told to shut down
225                while (!shuttingDown)
226                {
227                        Request* req;
228                        // Manual scope block just to define scope of lock
229                        {
230                                // Lock; note that 'mCondition.wait()' will free the lock
231                                boost::recursive_mutex::scoped_lock queueLock(
232                                        queueInstance.OGRE_AUTO_MUTEX_NAME);
233                                if (queueInstance.mRequestQueue.empty())
234                                {
235                                        // frees lock and suspends the thread
236                                        queueInstance.mCondition.wait(queueLock);
237                                }
238                                // When we get back here, it's because we've been notified
239                                // and thus the thread as been woken up. Lock has also been
240                                // re-acquired.
241
242                                // Process one request
243                                req = &(queueInstance.mRequestQueue.front());
244                        } // release lock so queueing can be done while we process one request
245                        // use of std::list means that references guarateed to remain valid
246
247                        ResourceManager* rm = 0;
248                        switch (req->type)
249                        {
250                        case RT_INITIALISE_GROUP:
251                                ResourceGroupManager::getSingleton().initialiseResourceGroup(
252                                        req->groupName);
253                                break;
254                        case RT_INITIALISE_ALL_GROUPS:
255                                ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
256                                break;
257                        case RT_LOAD_GROUP:
258                                ResourceGroupManager::getSingleton().loadResourceGroup(
259                                        req->groupName);
260                                break;
261                        case RT_LOAD_RESOURCE:
262                                rm = ResourceGroupManager::getSingleton()._getResourceManager(
263                                                req->resourceType);
264                                rm->load(req->resourceName, req->groupName, req->isManual,
265                                        req->loader, req->loadParams);
266                                break;
267                        case RT_SHUTDOWN:
268                                // That's all folks
269                                shuttingDown = true;
270                                break;
271                        };
272
273
274                        {
275                                // re-lock to consume completed request
276                                boost::recursive_mutex::scoped_lock queueLock(
277                                        queueInstance.OGRE_AUTO_MUTEX_NAME);
278
279                                // Consume the ticket
280                                queueInstance.mRequestTicketMap.erase(req->ticketID);
281                                queueInstance.mRequestQueue.pop_front();
282                        }
283
284
285                }
286
287       
288               
289        }
290#endif
291        //------------------------------------------------------------------------
292
293}
294
295
296
Note: See TracBrowser for help on using the repository browser.