Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/src/OgreResource.cpp @ 3

Last change on this file since 3 was 3, checked in by anonymous, 17 years ago

=update

File size: 6.9 KB
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-2006 Torus Knot Software Ltd
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
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29// Ogre includes
30#include "OgreStableHeaders.h"
31
32#include "OgreResource.h"
33#include "OgreResourceManager.h"
34#include "OgreResourceBackgroundQueue.h"
35#include "OgreLogManager.h"
36#include "OgreException.h"
37
38namespace Ogre
39{
40        //-----------------------------------------------------------------------
41        Resource::Resource(ResourceManager* creator, const String& name, ResourceHandle handle,
42                const String& group, bool isManual, ManualResourceLoader* loader)
43                : mCreator(creator), mName(name), mGroup(group), mHandle(handle), 
44                mLoadingState(LOADSTATE_UNLOADED), mIsBackgroundLoaded(false),
45                mSize(0), mIsManual(isManual), mLoader(loader)
46        {
47        }
48        //-----------------------------------------------------------------------
49        Resource::~Resource() 
50        { 
51        }
52        //-----------------------------------------------------------------------
53        void Resource::escalateLoading()
54        {
55                // Just call load as if this is the background thread, locking on
56                // load status will prevent race conditions
57                load(true);
58        }
59        //-----------------------------------------------------------------------
60        void Resource::load(bool background)
61        {
62                // Early-out without lock (mitigate perf cost of ensuring loaded)
63                // Don't load if:
64                // 1. We're already loaded
65                // 2. Another thread is loading right now
66                // 3. We're marked for background loading and this is not the background
67                //    loading thread we're being called by
68                if (mLoadingState != LOADSTATE_UNLOADED || (mIsBackgroundLoaded && !background))
69                        return;
70
71                // Scope lock over load status
72                {
73                        OGRE_LOCK_MUTEX(mLoadingStatusMutex)
74                        // Check again just in case status changed (since we didn't lock above)
75                        if (mLoadingState != LOADSTATE_UNLOADED || (mIsBackgroundLoaded && !background))
76                        {
77                                // no loading to be done
78                                return;
79                        }
80                        mLoadingState = LOADSTATE_LOADING;
81                }
82
83                // Scope lock for actual loading
84        try
85                {
86
87                        OGRE_LOCK_AUTO_MUTEX
88                        preLoadImpl();
89
90                        if (mIsManual)
91                        {
92                                // Load from manual loader
93                                if (mLoader)
94                                {
95                                        mLoader->loadResource(this);
96                                }
97                                else
98                                {
99                                        // Warn that this resource is not reloadable
100                                        LogManager::getSingleton().logMessage(
101                                                "WARNING: " + mCreator->getResourceType() + 
102                                                " instance '" + mName + "' was defined as manually "
103                                                "loaded, but no manual loader was provided. This Resource "
104                                                "will be lost if it has to be reloaded.");
105                                }
106                        }
107                        else
108                        {
109                                if (mGroup == ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME)
110                                {
111                                        // Derive resource group
112                                        changeGroupOwnership(
113                                                ResourceGroupManager::getSingleton()
114                                                .findGroupContainingResource(mName));
115                                }
116                                loadImpl();
117                        }
118                        // Calculate resource size
119                        mSize = calculateSize();
120
121                        postLoadImpl();
122                }
123        catch (...)
124        {
125            // Reset loading in-progress flag in case failed for some reason
126            OGRE_LOCK_MUTEX(mLoadingStatusMutex)
127            mLoadingState = LOADSTATE_UNLOADED;
128            // Re-throw
129            throw;
130        }
131
132                // Scope lock for loading progress
133                {
134                        OGRE_LOCK_MUTEX(mLoadingStatusMutex)
135               
136                        // Now loaded
137                        mLoadingState = LOADSTATE_LOADED;
138                }
139
140                // Notify manager
141                if(mCreator)
142                        mCreator->_notifyResourceLoaded(this);
143
144                // Fire (deferred) events
145                if (mIsBackgroundLoaded)
146                        queueFireBackgroundLoadingComplete();
147
148
149        }
150        //-----------------------------------------------------------------------
151        void Resource::changeGroupOwnership(const String& newGroup)
152        {
153                if (mGroup != newGroup)
154                {
155                        String oldGroup = mGroup;
156                        mGroup = newGroup;
157                        ResourceGroupManager::getSingleton()
158                                ._notifyResourceGroupChanged(oldGroup, this);
159                }
160        }
161        //-----------------------------------------------------------------------
162        void Resource::unload(void) 
163        { 
164                // Early-out without lock (mitigate perf cost of ensuring unloaded)
165                if (mLoadingState != LOADSTATE_LOADED)
166                        return;
167
168                // Scope lock for loading status
169                {
170                        OGRE_LOCK_MUTEX(mLoadingStatusMutex)
171                        if (mLoadingState == LOADSTATE_LOADING)
172                        {
173                                OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
174                                        "Cannot unload resource " + mName + " whilst loading is in progress!", 
175                                        "Resource::unload");
176                        }
177                        if (mLoadingState != LOADSTATE_LOADED)
178                                return; // nothing to do
179
180                        mLoadingState = LOADSTATE_UNLOADING;
181                }
182
183                // Scope lock for actual unload
184                {
185                        OGRE_LOCK_AUTO_MUTEX
186                        preUnloadImpl();
187                        unloadImpl();
188                        postUnloadImpl();
189                }
190
191                // Scope lock for loading status
192                {
193                        OGRE_LOCK_MUTEX(mLoadingStatusMutex)
194                        mLoadingState = LOADSTATE_UNLOADED;
195                }
196
197                // Notify manager
198                if(mCreator)
199                        mCreator->_notifyResourceUnloaded(this);
200
201        }
202        //-----------------------------------------------------------------------
203        void Resource::reload(void) 
204        { 
205                OGRE_LOCK_AUTO_MUTEX
206                if (mLoadingState == LOADSTATE_LOADED)
207                {
208                        unload();
209                        load();
210                }
211        }
212        //-----------------------------------------------------------------------
213        void Resource::touch(void) 
214        {
215                OGRE_LOCK_AUTO_MUTEX
216        // make sure loaded
217        load();
218
219                if(mCreator)
220                        mCreator->_notifyResourceTouched(this);
221        }
222        //-----------------------------------------------------------------------
223        void Resource::addListener(Resource::Listener* lis)
224        {
225                mListenerList.push_back(lis);
226        }
227        //-----------------------------------------------------------------------
228        void Resource::removeListener(Resource::Listener* lis)
229        {
230                // O(n) but not called very often
231                mListenerList.remove(lis);
232        }
233        //-----------------------------------------------------------------------
234        void Resource::queueFireBackgroundLoadingComplete(void)
235        {
236                ResourceBackgroundQueue& rbq = ResourceBackgroundQueue::getSingleton();
237                for (ListenerList::iterator i = mListenerList.begin();
238                        i != mListenerList.end(); ++i)
239                {
240                        rbq._queueFireBackgroundLoadingComplete(*i, this);
241                }
242        }
243
244
245}
Note: See TracBrowser for help on using the repository browser.