//---------------------------------------------------------------------
	WorkQueue::Response* Page::handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ)
	{
		// Background thread (maybe)

		PageRequest preq = any_cast<PageRequest>(req->getData());
		// only deal with own requests; we shouldn't ever get here though
		if (preq.srcPage != this)
			return 0;

		PageResponse res;
		res.pageData = OGRE_NEW PageData();
		WorkQueue::Response* response = 0;
		try
		{
			prepareImpl(res.pageData);
			response = OGRE_NEW WorkQueue::Response(req, true, Any(res));
		}
		catch (Exception& e)
		{
			// oops
			response = OGRE_NEW WorkQueue::Response(req, false, Any(res), 
				e.getFullDescription());
		}

		return response;
	}
	//---------------------------------------------------------------------
	bool Page::prepareImpl(PageData* dataToPopulate)
	{
		// Procedural preparation
		if (mParent->_prepareProceduralPage(this))
			return true;
		else
		{
			// Background loading
			String filename = generateFilename();

			DataStreamPtr stream = Root::getSingleton().openFileStream(filename, 
				getManager()->getPageResourceGroup());
			StreamSerialiser ser(stream);
			return prepareImpl(ser, dataToPopulate);
		}


	}
Exemple #3
0
	//-----------------------------------------------------------------------
	void Resource::prepare()
	{
        // quick check that avoids any synchronisation
        LoadingState old = mLoadingState.get();
        if (old != LOADSTATE_UNLOADED && old != LOADSTATE_PREPARING) return;

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

			LoadingState state = mLoadingState.get();
			if( state != LOADSTATE_PREPARED && state != LOADSTATE_LOADING && state != LOADSTATE_LOADED )
			{
				OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Another thread failed in resource operation",
					"Resource::prepare");
			}
			return;
		}

		// Scope lock for actual loading
        try
		{

			OGRE_LOCK_AUTO_MUTEX

			if (mIsManual)
			{
                if (mLoader)
				{
					mLoader->prepareResource(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.";
				}
			}
			else
			{
				if (mGroup == ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME)
				{
					// Derive resource group
					changeGroupOwnership(
						ResourceGroupManager::getSingleton()
						.findGroupContainingResource(mName));
				}
				prepareImpl();
			}
		}
        catch (...)
        {
            mLoadingState.set(LOADSTATE_UNLOADED);
            throw;
        }

        mLoadingState.set(LOADSTATE_PREPARED);

		// Since we don't distinguish between GPU and CPU RAM, this
		// seems pointless
		//if(mCreator)
		//	mCreator->_notifyResourcePrepared(this);

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

	}
Exemple #4
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();


	}