Example #1
0
void MakeCore(Resource &res)
{
	assert(res.GetName() == "core");

	res.Load();

	for (token_map::iterator i = s_token_map.begin(); i != s_token_map.end(); ++i) {
		const std::string &token = i->first;
		std::string text = res.Get(token);

		if (text.empty()) {
			Output("%s/%s: token '%s' not found\n", res.GetName().c_str(), res.GetLangCode().c_str(), token.c_str());
			text = token;
		}

		if (text.size() > size_t(STRING_RECORD_SIZE)) {
			Output("%s/%s: text for token '%s' is too long and will be truncated\n", res.GetName().c_str(), res.GetLangCode().c_str(), token.c_str());
			text.resize(STRING_RECORD_SIZE);
		}

		// const_cast so we can set the string, see above
		char *record = const_cast<char*>(i->second);
		copy_string(record, text.c_str(), text.size(), STRING_RECORD_SIZE);
	}

	s_coreResource = res;
}
Example #2
0
void BackgroundLoader::FinishBackgroundLoading(BackgroundLoadItem& item)
{
    Resource* resource = item.resource_;
    
    bool success = resource->GetAsyncLoadState() == ASYNC_SUCCESS;
    // If BeginLoad() phase was successful, call EndLoad() and get the final success/failure result
    if (success)
    {
#ifdef URHO3D_PROFILING
        String profileBlockName("Finish" + resource->GetTypeName());
        
        Profiler* profiler = owner_->GetSubsystem<Profiler>();
        if (profiler)
            profiler->BeginBlock(profileBlockName.CString());
#endif
        LOGDEBUG("Finishing background loaded resource " + resource->GetName());
        success = resource->EndLoad();
        
#ifdef URHO3D_PROFILING
        if (profiler)
            profiler->EndBlock();
#endif
    }
    resource->SetAsyncLoadState(ASYNC_DONE);
    
    if (!success && item.sendEventOnFailure_)
    {
        using namespace LoadFailed;

        VariantMap& eventData = owner_->GetEventDataMap();
        eventData[P_RESOURCENAME] = resource->GetName();
        owner_->SendEvent(E_LOADFAILED, eventData);
    }
    
    // Send event, either success or failure
    {
        using namespace ResourceBackgroundLoaded;
        
        VariantMap& eventData = owner_->GetEventDataMap();
        eventData[P_RESOURCENAME] = resource->GetName();
        eventData[P_SUCCESS] = success;
        eventData[P_RESOURCE] = resource;
        owner_->SendEvent(E_RESOURCEBACKGROUNDLOADED, eventData);
    }
    
    // Store to the cache; use same mechanism as for manual resources
    if (success || owner_->GetReturnFailedResources())
        owner_->AddManualResource(resource);
}
Example #3
0
void BackgroundLoader::ThreadFunction()
{
    while (shouldRun_)
    {
        backgroundLoadMutex_.Acquire();

        // Search for a queued resource that has not been loaded yet
        HashMap<Pair<StringHash, StringHash>, BackgroundLoadItem>::Iterator i = backgroundLoadQueue_.Begin();
        while (i != backgroundLoadQueue_.End())
        {
            if (i->second_.resource_->GetAsyncLoadState() == ASYNC_QUEUED)
                break;
            else
                ++i;
        }

        if (i == backgroundLoadQueue_.End())
        {
            // No resources to load found
            backgroundLoadMutex_.Release();
            Time::Sleep(5);
        }
        else
        {
            BackgroundLoadItem& item = i->second_;
            Resource* resource = item.resource_;
            // We can be sure that the item is not removed from the queue as long as it is in the
            // "queued" or "loading" state
            backgroundLoadMutex_.Release();

            bool success = false;
            SharedPtr<File> file = owner_->GetFile(resource->GetName(), item.sendEventOnFailure_);
            if (file)
            {
                resource->SetAsyncLoadState(ASYNC_LOADING);
                success = resource->BeginLoad(*file);
            }

            // Process dependencies now
            // Need to lock the queue again when manipulating other entries
            Pair<StringHash, StringHash> key = MakePair(resource->GetType(), resource->GetNameHash());
            backgroundLoadMutex_.Acquire();
            if (item.dependents_.Size())
            {
                for (HashSet<Pair<StringHash, StringHash> >::Iterator i = item.dependents_.Begin();
                     i != item.dependents_.End(); ++i)
                {
                    HashMap<Pair<StringHash, StringHash>, BackgroundLoadItem>::Iterator j = backgroundLoadQueue_.Find(*i);
                    if (j != backgroundLoadQueue_.End())
                        j->second_.dependencies_.Erase(key);
                }

                item.dependents_.Clear();
            }

            resource->SetAsyncLoadState(success ? ASYNC_SUCCESS : ASYNC_FAIL);
            backgroundLoadMutex_.Release();
        }
    }
}
Example #4
0
std::shared_ptr<ResourceHandle> ResourceManager::Find(const Resource &r)
{
    ResourceHandleMap::iterator it = this->resources.find(r.GetName());
    if (it == this->resources.end())
    {
        return NULL;
    }
    return it->second;
}
Example #5
0
bool ResourceManager::FileRename( Resource *res, const char *src, const char *dst )
{
    Resource *dstRes = res;

    if ( !ParseResourcePath( res, src, src ) || !ParseResourcePath( dstRes, dst, dst ) )
        return false;

    if ( res == dstRes )
        return res->FileRename( src, dst );

    return resFileRoot->Rename( res->GetName() + "/" + src, dstRes->GetName() + "/" + dst );
}
 // ////////////////////////////////////////////////////////////////////
 //
 // ////////////////////////////////////////////////////////////////////
 SoundResHandle::SoundResHandle(Resource &r, char *buffer, const U32 size, ResCache *pResCache)
     :   ResHandle(r, buffer, size, pResCache),
         m_PCMBuffer(NULL),
         m_PCMBufferSize(0),
         m_SoundType(SOUND_TYPE_UNKNOWN),
         m_SoundFile(r.GetName()),
         m_bInitialized(false),
         m_LengthMilli(0)
 {
     // don't do anything yet - timing sound Initialization is important!
     m_bFromFile = (buffer == NULL);
 }
Example #7
0
void BackgroundLoader::FinishBackgroundLoading(BackgroundLoadItem& item)
{
    Resource* resource = item.resource_;

    bool success = resource->GetAsyncLoadState() == ASYNC_SUCCESS;
    // If BeginLoad() phase was successful, call EndLoad() and get the final success/failure result
    if (success)
    {
        URHO3D_PROFILE(ea::string("Finish" + resource->GetTypeName()).c_str());
        URHO3D_LOGDEBUG("Finishing background loaded resource " + resource->GetName());
        success = resource->EndLoad();
    }
    resource->SetAsyncLoadState(ASYNC_DONE);

    if (!success && item.sendEventOnFailure_)
    {
        using namespace LoadFailed;

        VariantMap& eventData = owner_->GetEventDataMap();
        eventData[P_RESOURCENAME] = resource->GetName();
        owner_->SendEvent(E_LOADFAILED, eventData);
    }

    // Store to the cache just before sending the event; use same mechanism as for manual resources
    if (success || owner_->GetReturnFailedResources())
        owner_->AddManualResource(resource);

    // Send event, either success or failure
    {
        using namespace ResourceBackgroundLoaded;

        VariantMap& eventData = owner_->GetEventDataMap();
        eventData[P_RESOURCENAME] = resource->GetName();
        eventData[P_SUCCESS] = success;
        eventData[P_RESOURCE] = resource;
        owner_->SendEvent(E_RESOURCEBACKGROUNDLOADED, eventData);
    }
}
Example #8
0
void BackgroundLoader::WaitForResource(StringHash type, StringHash nameHash)
{
    backgroundLoadMutex_.Acquire();

    // Check if the resource in question is being background loaded
    ea::pair<StringHash, StringHash> key = ea::make_pair(type, nameHash);
    auto i = backgroundLoadQueue_.find(
        key);
    if (i != backgroundLoadQueue_.end())
    {
        backgroundLoadMutex_.Release();

        {
            Resource* resource = i->second.resource_;
            HiresTimer waitTimer;
            bool didWait = false;

            for (;;)
            {
                unsigned numDeps = i->second.dependencies_.size();
                AsyncLoadState state = resource->GetAsyncLoadState();
                if (numDeps > 0 || state == ASYNC_QUEUED || state == ASYNC_LOADING)
                {
                    didWait = true;
                    Time::Sleep(1);
                }
                else
                    break;
            }

            if (didWait)
                URHO3D_LOGDEBUG("Waited " + ea::to_string(waitTimer.GetUSec(false) / 1000) + " ms for background loaded resource " +
                         resource->GetName());
        }

        // This may take a long time and may potentially wait on other resources, so it is important we do not hold the mutex during this
        FinishBackgroundLoading(i->second);

        backgroundLoadMutex_.Acquire();
        backgroundLoadQueue_.erase(i);
        backgroundLoadMutex_.Release();
    }
    else
        backgroundLoadMutex_.Release();
}
Example #9
0
std::shared_ptr<ResourceHandle> ResourceManager::GetHandle(const Resource &r)
{
    std::shared_ptr<ResourceHandle> handle(Find(r));

    if (!handle)
    {
        handle = Load(r);
        if (!handle)
        {
            LogWarning("ResourceHandle for file %s couldn't be loaded.", r.GetName().c_str());
        }
    }
    else
    {
        Update(handle);
    }

    return handle;
}
Example #10
0
    void ResourceManager::Destroy()
    {
        ProcessRequests();

#if defined( CARBON_DEBUG )
        if ( resourceTable.Count() )
        {
            Array< Resource *, FrameAllocator > unreleased;
            resourceTable.Dump( unreleased );

            Char res_msg[512];

            CARBON_TRACE( "====================================================\n" );
            CARBON_TRACE( "# Some resources are leaking\n\n" );

            Array< Resource * >::Iterator it = unreleased.Begin();
            Array< Resource * >::ConstIterator end = unreleased.End();
            for ( ; it != end; ++it )
            {
                Resource * res = *it;

                StringUtils::FormatString( res_msg, sizeof(res_msg), "# %s | ref count : %d\n", res->GetName(), res->GetRefCount() );
                CARBON_TRACE( res_msg );
            }

            CARBON_TRACE( "\n====================================================\n" );
        }
#endif
        CARBON_ASSERT( resourceTable.Count() == 0 );
    }
Example #11
0
std::shared_ptr<ResourceHandle> ResourceManager::Load(const Resource &r)
{
    std::shared_ptr<IResourceLoader>    loader = NULL;
    std::shared_ptr<ResourceHandle>     handle = NULL;

    for (ResourceLoaders::iterator it = this->resourceLoaders.begin(); it != this->resourceLoaders.end(); ++it)
    {
        std::shared_ptr<IResourceLoader> l = *it;

        if (StringUtilities::WildcardMatch(l->GetPattern(), r.GetName()))
        {
            loader = l;
            break;
        }
    }

    if (!loader)
    {
        LogWarning("loader for file '" + r.GetName() + "' not found");
        return handle;
    }

    int rawSize = this->file->GetRawResourceSize(r);
    if (rawSize < 0)
    {
        LogWarning("Resource not found: " + r.GetName());
        return handle;
    }

    int allocSize = rawSize + (loader->AddNullZero() ? 1 : 0);
    char *rawBuffer = (loader->UseRawFile() ? Allocate(allocSize) : TG_NEW char[allocSize]);
    memset(rawBuffer, 0, allocSize);

    if (!rawBuffer || !this->file->GetRawResource(r, rawBuffer))
    {
        return handle;
    }

    char *buffer = NULL;
    unsigned int size = 0;
    
    if (loader->UseRawFile())
    {
        buffer = rawBuffer;
        handle = std::shared_ptr<ResourceHandle>(TG_NEW ResourceHandle(r, buffer, rawSize, this));
    }
    else
    {
        size = loader->GetLoadedResourceSize(rawBuffer, rawSize);
        buffer = Allocate(size);

        if (!rawBuffer || !buffer)
        {
            LogError("Resource manager cache is out of memory.");
            return handle;
        }

        handle = std::shared_ptr<ResourceHandle>(TG_NEW ResourceHandle(r, buffer, size, this));
        bool success = loader->LoadResource(rawBuffer, rawSize, handle);

        if (loader->DiscardRawBufferAfterLoad())
        {
            SAFE_DELETE_ARRAY(rawBuffer);
        }

        if (!success)
        {
            return NULL;
        }
    }

    if (handle)
    {
        this->lru.push_front(handle);
        this->resources[r.GetName()] = handle;
    }

    return handle;
}