Example #1
0
bool IAsset::LoadFromCache()
{
    // If asset did not have dependencies, this causes Loaded() to be emitted
    bool success = LoadFromFile(DiskSource());
    if (!success)
        return false;

    AssetPtr thisAsset = shared_from_this();

    if (assetAPI->HasPendingDependencies(thisAsset))
        assetAPI->RequestAssetDependencies(thisAsset);

    return success;
}
Example #2
0
bool IAsset::LoadFromCache()
{
    bool success = LoadFromFile(DiskSource());
    if (!success)
        return false;

    AssetPtr thisAsset = shared_from_this();

    if (assetAPI->NumPendingDependencies(thisAsset) == 0)
        emit Loaded(thisAsset);
    else
        assetAPI->RequestAssetDependencies(thisAsset);

    return success;
}
Example #3
0
bool IAsset::SaveCachedCopyToFile(const QString &filename)
{
    return CopyAssetFile(DiskSource(), filename);
}
bool ZipAssetBundle::DeserializeFromDiskSource()
{
    if (!assetAPI_->Cache())
    {
        LogError("ZipAssetBundle::DeserializeFromDiskSource: Cannot process archive, AssetAPI cache is null.");
        return false;
    }
    else if (DiskSource().Empty())
    {
        LogError("ZipAssetBundle::DeserializeFromDiskSource: Cannot process archive, no disk source for " + Name());
        return false;
    }

    /* We want to detect if the extracted files are already up to date to save time.
       If the last modified date for the sub asset is the same as the parent zip file, 
       we don't extract it. If the zip is re-downloaded from source everything will get unpacked even
       if only one file would have changed inside it. We could do uncompressed size comparisons
       but that is not a absolute guarantee that the file has not changed. We'll be on the safe side
       to unpack the whole zip file. Zip files are meant for deploying the scene and should be touched
       rather rarely. Note that local:// refs are unpacked to cache but the zips disk source is not in the
       cache. Meaning that local:// zip files will always be extracted fully even if the disk source
       was not changed, we don't have a mechanism to get the last modified date properly except from
       the asset cache. For local scenes this should be fine as there is no real need to
       zip the scene up as you already have the disk sources right there in the storage.
       The last modified query will fail if the file is open with zziplib, do it first. */
    uint zipLastModified = assetAPI_->Cache()->LastModified(Name());

    const String diskSourceInternal = Urho3D::GetInternalPath(DiskSource());

    zzip_error_t error = ZZIP_NO_ERROR;
    archive_ = zzip_dir_open(diskSourceInternal.CString(), &error);
    if (CheckAndLogZzipError(error) || CheckAndLogArchiveError(archive_) || !archive_)
    {
        archive_ = 0;
        return false;
    }
    
    int uncompressing = 0;
    
    ZZIP_DIRENT archiveEntry;
    while(zzip_dir_read(archive_, &archiveEntry))
    {
        String relativePath = Urho3D::GetInternalPath(archiveEntry.d_name);
        if (!relativePath.EndsWith("/"))
        {
            String subAssetRef = GetFullAssetReference(relativePath);
            
            ZipArchiveFile file;
            file.relativePath = relativePath;
            file.cachePath = Urho3D::GetInternalPath(assetAPI_->Cache()->DiskSourceByRef(subAssetRef));
            file.lastModified = assetAPI_->Cache()->LastModified(subAssetRef);
            file.compressedSize = archiveEntry.d_csize;
            file.uncompressedSize = archiveEntry.st_size;
            
            /* Mark this file for extraction. If both cache files have valid dates
               and they differ extract. If they have the same date stamp skip extraction.
               Note that file.lastModified will be non-valid for non cached files so we 
               will cover also missing files. */
            file.doExtract = (zipLastModified > 0 && file.lastModified > 0) ? (zipLastModified != file.lastModified) : true;
            if (file.doExtract)
                uncompressing++;

            files_.Push(file);
            fileCount_++;
        }
    }
    
    // Close the zzip directory ptr
    Close();
    
    // If the zip file was empty we don't want IsLoaded to fail on the files_ check.
    // The bundle loaded fine but there was no content, log a warning.
    if (files_.Empty())
    {
        LogWarning("ZipAssetBundle: Bundle loaded but does not contain any files " + Name());
        files_.Push(ZipArchiveFile());
        Loaded.Emit(this);
        return true;
    }
    
    // Don't spin the worker if all sub assets are up to date in cache.
    if (uncompressing > 0)
    {   
        // Now that the file info has been read, continue in a worker thread.
        LogDebug("ZipAssetBundle: File information read for " + Name() + ". File count: " + String(files_.Size()) + ". Starting worker thread to uncompress " + String(uncompressing) + " files.");
        
        // ZipWorker is a QRunnable we can pass to QThreadPool, it will handle scheduling it and deletes it when done.
        worker_ = new ZipWorker(this, zipLastModified, diskSourceInternal, files_);   
        if (!worker_->Run())
        {
            LogError("ZipAssetBundle: Failed to start worker thread for " + Name());
            files_.Clear();
            return false;
        }

        assetAPI_->GetFramework()->Frame()->Updated.Connect(this, &ZipAssetBundle::CheckDone);
    }
    else
        Loaded.Emit(this);
        
    return true;
}
Example #5
0
bool IAsset::SaveCachedCopyToFile(const QString &filename)
{
    return CopyAssetFile(DiskSource().toStdString().c_str(), filename.toStdString().c_str());
}