Esempio n. 1
0
	//---------------------------------------------------------------------
    void Resource::load(bool background)
	{
		// Early-out without lock (mitigate perf cost of ensuring loaded)
		// Don't load if:
		// 1. We're already loaded
		// 2. Another thread is loading right now
		// 3. We're marked for background loading and this is not the background
		//    loading thread we're being called by

        if (mIsBackgroundLoaded && !background) return;

		// This next section is to deal with cases where 2 threads are fighting over
		// who gets to prepare / load - this will only usually happen if loading is escalated
		bool keepChecking = true;
		LoadingState old;
		while (keepChecking)
		{
			// quick check that avoids any synchronisation
			old = mLoadingState.get();

			if ( old == LOADSTATE_PREPARING )
			{
				while( mLoadingState.get() == LOADSTATE_PREPARING )
				{
					OGRE_LOCK_AUTO_MUTEX
				}
				old = mLoadingState.get();
			}

			if (old!=LOADSTATE_UNLOADED && old!=LOADSTATE_PREPARED && old!=LOADSTATE_LOADING) return;

			// atomically do slower check to make absolutely sure,
			// and set the load state to LOADING
			if (old==LOADSTATE_LOADING || !mLoadingState.cas(old,LOADSTATE_LOADING))
			{
				while( mLoadingState.get() == LOADSTATE_LOADING )
				{
					OGRE_LOCK_AUTO_MUTEX
				}

				LoadingState state = mLoadingState.get();
				if( state == LOADSTATE_PREPARED || state == LOADSTATE_PREPARING )
				{
					// another thread is preparing, loop around
					continue;
				}
				else if( state != LOADSTATE_LOADED )
				{
					OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Another thread failed in resource operation",
						"Resource::load");
				}
				return;
			}
			keepChecking = false;
		}

		// Scope lock for actual loading
        try
		{

			OGRE_LOCK_AUTO_MUTEX



			if (mIsManual)
			{
                preLoadImpl();
				// Load from manual loader
				if (mLoader)
				{
					mLoader->loadResource(this);
				}
				else
				{
					// Warn that this resource is not reloadable
					LogManager::getSingleton().stream(LML_TRIVIAL) 
						<< "WARNING: " << mCreator->getResourceType()  
						<< " instance '" << mName << "' was defined as manually "
						<< "loaded, but no manual loader was provided. This Resource "
						<< "will be lost if it has to be reloaded.";
				}
                postLoadImpl();
			}
			else
			{

                if (old==LOADSTATE_UNLOADED)
                    prepareImpl();

                preLoadImpl();

                old = LOADSTATE_PREPARED;

				if (mGroup == ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME)
				{
					// Derive resource group
					changeGroupOwnership(
						ResourceGroupManager::getSingleton()
						.findGroupContainingResource(mName));
				}

				loadImpl();

                postLoadImpl();
			}

			// Calculate resource size
			mSize = calculateSize();

		}
        catch (...)
        {
            // Reset loading in-progress flag, in case failed for some reason.
            // We reset it to UNLOADED because the only other case is when
            // old == PREPARED in which case the loadImpl should wipe out
            // any prepared data since it might be invalid.
            mLoadingState.set(LOADSTATE_UNLOADED);
            // Re-throw
            throw;
        }

        mLoadingState.set(LOADSTATE_LOADED);
        _dirtyState();

		// Notify manager
		if(mCreator)
			mCreator->_notifyResourceLoaded(this);

		// Fire (deferred) events
		if (mIsBackgroundLoaded)
			queueFireBackgroundLoadingComplete();


	}
Esempio n. 2
0
	//-----------------------------------------------------------------------
	void Resource::load(bool background)
	{
		// Early-out without lock (mitigate perf cost of ensuring loaded)
		// Don't load if:
		// 1. We're already loaded
		// 2. Another thread is loading right now
		// 3. We're marked for background loading and this is not the background
		//    loading thread we're being called by
		if (mLoadingState != LOADSTATE_UNLOADED || (mIsBackgroundLoaded && !background))
			return;

		// Scope lock over load status
		{
			OGRE_LOCK_MUTEX(mLoadingStatusMutex)
			// Check again just in case status changed (since we didn't lock above)
			if (mLoadingState != LOADSTATE_UNLOADED || (mIsBackgroundLoaded && !background))
			{
				// no loading to be done
				return;
			}
			mLoadingState = LOADSTATE_LOADING;
		}

		// Scope lock for actual loading
        try
		{

			OGRE_LOCK_AUTO_MUTEX
			preLoadImpl();

			if (mIsManual)
			{
				// Load from manual loader
				if (mLoader)
				{
					mLoader->loadResource(this);
				}
				else
				{
					// Warn that this resource is not reloadable
					LogManager::getSingleton().logMessage(
						"WARNING: " + mCreator->getResourceType() + 
						" instance '" + mName + "' was defined as manually "
						"loaded, but no manual loader was provided. This Resource "
						"will be lost if it has to be reloaded.");
				}
			}
			else
			{
				if (mGroup == ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME)
				{
					// Derive resource group
					changeGroupOwnership(
						ResourceGroupManager::getSingleton()
						.findGroupContainingResource(mName));
				}
				loadImpl();
			}
			// Calculate resource size
			mSize = calculateSize();

			postLoadImpl();
		}
        catch (...)
        {
            // Reset loading in-progress flag in case failed for some reason
            OGRE_LOCK_MUTEX(mLoadingStatusMutex)
            mLoadingState = LOADSTATE_UNLOADED;
            // Re-throw
            throw;
        }

		// Scope lock for loading progress
		{
			OGRE_LOCK_MUTEX(mLoadingStatusMutex)
		
			// Now loaded
			mLoadingState = LOADSTATE_LOADED;
		}

		// Notify manager
		if(mCreator)
			mCreator->_notifyResourceLoaded(this);

		// Fire (deferred) events
		if (mIsBackgroundLoaded)
			queueFireBackgroundLoadingComplete();


	}