Exemplo n.º 1
0
/// Perform shutdown of the Asset system.
///
/// This releases all final references to objects and releases all allocated memory.  This should be called during
/// the shutdown process after all types have been unregistered as well as after calling AssetType::Shutdown().
///
/// @see AssetType::Shutdown()
void Asset::Shutdown()
{
	HELIUM_TRACE( TraceLevels::Info, TXT( "Shutting down Asset system.\n" ) );
	
#if !HELIUM_RELEASE
	size_t objectCountActual = sm_objects.GetUsedSize();
	if( objectCountActual != 0 )
	{
		HELIUM_TRACE(
			TraceLevels::Error,
			TXT( "%" ) PRIuSZ TXT( " asset(s) still referenced during shutdown!\n" ),
			objectCountActual );

		size_t objectCount = sm_objects.GetSize();
		for( size_t objectIndex = 0; objectIndex < objectCount; ++objectIndex )
		{
			if( !sm_objects.IsElementValid( objectIndex ) )
			{
				continue;
			}

			Asset* pObject = sm_objects[ objectIndex ];
			if( !pObject )
			{
				continue;
			}
			
#if HELIUM_ENABLE_MEMORY_TRACKING
			Helium::RefCountProxy<Reflect::Object> *pProxy = pObject->GetRefCountProxy();
			HELIUM_ASSERT(pProxy);

			HELIUM_TRACE(
					TraceLevels::Error,
					TXT( "   - 0x%p: %s (%" ) PRIu16 TXT( " strong ref(s), %" ) PRIu16 TXT( " weak ref(s))\n" ),
					 pProxy,
					( pObject ? *pObject->GetPath().ToString() : TXT( "(cleared reference)" ) ),
					pProxy->GetStrongRefCount(),
					pProxy->GetWeakRefCount() );
#else
			HELIUM_TRACE( TraceLevels::Error, TXT( "- %s\n" ), *pObject->GetPath().ToString() );
#endif
		}
	}
#endif  // !HELIUM_RELEASE

	sm_objects.Clear();
	sm_wpFirstTopLevelObject.Release();

	delete sm_pNameInstanceIndexMap;
	sm_pNameInstanceIndexMap = NULL;

	delete sm_pEmptyNameInstanceIndexMap;
	sm_pEmptyNameInstanceIndexMap = NULL;

	delete sm_pEmptyInstanceIndexSet;
	sm_pEmptyInstanceIndexSet = NULL;

	sm_serializationBuffer.Clear();
}
Exemplo n.º 2
0
unsigned int ProjectViewModel::GetChildren( const wxDataViewItem& item, wxDataViewItemArray& items ) const
{
	int count = 0;
	Asset *pAsset = NULL;

	if (!item.IsOk())
	{
		ForciblyFullyLoadedPackageManager::GetStaticInstance()->ForceFullyLoadRootPackages();
		pAsset = Asset::GetFirstTopLevelAsset();
	}
	else
	{
		Asset* pParentAsset = static_cast< Asset* >( item.GetID() );

		if ( pParentAsset->IsPackage() )
		{
			ForciblyFullyLoadedPackageManager::GetStaticInstance()->ForceFullyLoadPackage( pParentAsset->GetPath() );
		}

		pAsset = pParentAsset->GetFirstChild();
	}

	while (pAsset)
	{
		//if ( m_AssetsInTree.Insert( pAsset ).Second() )
		{
			items.Add( wxDataViewItem( pAsset ) );
			++count;
		}

		pAsset = pAsset->GetNextSibling();
	}

	return count;
}
Exemplo n.º 3
0
const FilePath *Helium::Asset::GetAssetFileSystemPath()
{
	HELIUM_ASSERT( !m_path.IsEmpty() );

	FilePath filePath;

	Asset *pSourceAsset = GetSourceAsset();
	if (pSourceAsset)
	{
		Package *pPackage = Reflect::SafeCast<Package>( pSourceAsset->GetOwner() );

		if ( pPackage )
		{
			PackageLoader *pLoader = pPackage->GetLoader();
			HELIUM_ASSERT( pLoader->HasAssetFileState() );

			if ( pLoader )
			{
				return &pLoader->GetAssetFileSystemPath( pSourceAsset->GetPath() );
			}
		}
	}

	return NULL;
}
Exemplo n.º 4
0
/// Update resource precaching for the given object load request.
///
/// @param[in] pRequest  Load request to update.
///
/// @return  True if resource precaching still requires processing, false if not.
bool AssetLoader::TickPrecache( LoadRequest* pRequest )
{
	HELIUM_ASSERT( pRequest );
	HELIUM_ASSERT( !( pRequest->stateFlags & LOAD_FLAG_LOADED ) );

	Asset* pObject = pRequest->spObject;
	if( pObject )
	{
		// TODO: SHouldn't this be in the linking phase?
		if ( !pRequest->resolver.TryFinishPrecachingDependencies() )
		{
			return false;
		}

		pRequest->resolver.Clear();

		// Perform any pre-precaching work (note that we don't precache anything for the default template object for
		// a given type).
		OnPrecacheReady( pObject, pRequest->pPackageLoader );

		if( !pObject->GetAnyFlagSet( Asset::FLAG_BROKEN ) &&
			!pObject->IsDefaultTemplate() &&
			pObject->NeedsPrecacheResourceData() )
		{
			if( !( pRequest->stateFlags & LOAD_FLAG_PRECACHE_STARTED ) )
			{
				if( !pObject->BeginPrecacheResourceData() )
				{
					HELIUM_TRACE(
						TraceLevels::Error,
						TXT( "AssetLoader: Failed to begin precaching object \"%s\".\n" ),
						*pObject->GetPath().ToString() );

					pObject->SetFlags( Asset::FLAG_PRECACHED | Asset::FLAG_BROKEN );
					AtomicOrRelease( pRequest->stateFlags, LOAD_FLAG_PRECACHED | LOAD_FLAG_ERROR );

					return true;
				}

				AtomicOrRelease( pRequest->stateFlags, LOAD_FLAG_PRECACHE_STARTED );
			}

			if( !pObject->TryFinishPrecacheResourceData() )
			{
				return false;
			}
		}

		pObject->SetFlags( Asset::FLAG_PRECACHED );
	}

	AtomicOrRelease( pRequest->stateFlags, LOAD_FLAG_PRECACHED );

	return true;
}
Exemplo n.º 5
0
bool Helium::AssetIdentifier::Identify( Reflect::Object* object, Name& identity )
{
	Asset *pAsset = Reflect::SafeCast<Asset>(object);

	if ( pAsset )
	{
		identity.Set(pAsset->GetPath().ToString());
		HELIUM_TRACE( TraceLevels::Info, TXT( "Identifying object [%s]\n" ), identity.Get() );
		return true;
	}
	else if ( object )
	{
		HELIUM_TRACE( TraceLevels::Info, TXT( "Deferring identification of object of type [%s]\n" ), object->GetMetaClass()->m_Name );
	}

	return false;
}
void AssetDatabase::HandleFileChanged(StringHash eventType, VariantMap& eventData)
{
    using namespace FileChanged;
    const String& fullPath = eventData[P_FILENAME].GetString();

    FileSystem* fs = GetSubsystem<FileSystem>();

    String pathName, fileName, ext;

    SplitPath(fullPath, pathName, fileName, ext);

    // ignore changes in the Cache resource dir
    if (fullPath == GetCachePath() || pathName.StartsWith(GetCachePath()))
        return;

    // don't care about directories and asset file changes
    if (fs->DirExists(fullPath) || ext == ".asset")
        return;

    Asset* asset = GetAssetByPath(fullPath);

    if (!asset && fs->FileExists(fullPath))
    {
        Scan();
        return;
    }

    if (asset)
    {
        if(!fs->Exists(fullPath))
        {
            DeleteAsset(asset);
        }
        else
        {
            if (asset->GetFileTimestamp() != fs->GetLastModifiedTime(asset->GetPath()))
            {
                asset->SetDirty(true);
                Scan();
            }
        }
    }
}
Exemplo n.º 7
0
uint64_t Helium::Asset::GetAssetFileTimeStamp()
{
	HELIUM_ASSERT( !m_path.IsEmpty() );
	uint64_t timestamp = 0;

	Asset *pSourceAsset = GetSourceAsset();
	if (pSourceAsset)
	{
		Package *pPackage = Reflect::SafeCast<Package>( pSourceAsset->GetOwner() );

		if ( pPackage )
		{
			PackageLoader *pLoader = pPackage->GetLoader();
			HELIUM_ASSERT( pLoader->HasAssetFileState() );

			if ( pLoader )
			{
				pLoader->GetAssetFileSystemTimestamp( pSourceAsset->GetPath() );
			}
		}
	}

	return timestamp;
}
Exemplo n.º 8
0
void ProjectViewModel::GetValue( wxVariant& variant, const wxDataViewItem& item, unsigned int column ) const
{
	if ( !item.IsOk() || ( column >= m_ColumnLookupTable.size() ) )
	{
		return;
	}

	Asset *node = static_cast< Asset* >( item.GetID() );
	if ( !node )
	{
		return;
	}

	switch( m_ColumnLookupTable.at( column ) )
	{
	default:
		break;

	case ProjectModelColumns::Name:
		{            
			uint32_t docStatus = DocumentStatus::Default; //  node->GetDocumentStatus();

			String assetString( *node->GetName() );
			

			wxString name = *assetString;
			if ( HasFlags<uint32_t>( docStatus, DocumentStatus::Changed ) )
			{
				name = wxString( TXT( '*' ) ) + name; 
			}

			wxBitmap bitmap = wxArtProvider::GetBitmap( GetArtIDFromPath( node->GetPath() ), wxART_OTHER, wxSize(16, 16) );
			if ( docStatus > 0 )
			{
				wxImage image = bitmap.ConvertToImage();
				HELIUM_ASSERT( image.Ok() );

				int overlayWidth = image.GetWidth() / 2;
				int overlayHeight = image.GetHeight() / 2;

				wxImage overlayImage;

				if ( HasFlags<uint32_t>( docStatus, DocumentStatus::Saving ) )
				{
					overlayImage = wxArtProvider::GetBitmap( ArtIDs::Status::Busy, wxART_OTHER, wxSize( overlayWidth, overlayHeight ) ).ConvertToImage();
					HELIUM_ASSERT( overlayImage.Ok() );
				}
				else if ( HasFlags<uint32_t>( docStatus, DocumentStatus::Loading ) )
				{
					overlayImage = wxArtProvider::GetBitmap( ArtIDs::Status::Busy, wxART_OTHER, wxSize( overlayWidth, overlayHeight ) ).ConvertToImage();
					HELIUM_ASSERT( overlayImage.Ok() );
				}
				else if ( HasFlags<uint32_t>( docStatus, DocumentStatus::Changed ) )
				{
					overlayImage = wxArtProvider::GetBitmap( ArtIDs::Actions::Edit, wxART_OTHER, wxSize( overlayWidth, overlayHeight ) ).ConvertToImage();
					HELIUM_ASSERT( overlayImage.Ok() );
				}

				if ( overlayImage.Ok() )
				{
					if ( overlayImage.GetWidth() != overlayWidth || overlayImage.GetHeight() != overlayHeight )
					{
						overlayImage.Rescale( overlayWidth, overlayHeight );
					}

					int x = 0;
					int y = 0;
					IconArtFile::CalculatePlacement( image, overlayImage, OverlayQuadrants::BottomRight, x, y );
					image.Paste( overlayImage, x, y );
				}

				bitmap = wxBitmap( image );
			}

			wxIcon icon;
			icon.CopyFromBitmap( bitmap );

			variant << wxDataViewIconText( name, icon );

		}
		break;

	//case ProjectModelColumns::Icon:
	//    {
	//        int32_t imageID = GlobalFileIconsTable().GetIconIDFromPath( node->GetPath() );
	//        wxVariant bitmapVariant;
	//        bitmapVariant.
	//        variant = GlobalFileIconsTable().GetSmallImageList()->GetBitmap( imageID );
	//    }
	//    break;

	case ProjectModelColumns::Details:
		{
			variant = std::string( TXT( "" ) );
		}
		break;

	case ProjectModelColumns::FileSize:
		{
			variant = std::string( TXT( "" ) );
		}
		break;
	case ProjectModelColumns::Type:
		{
			const AssetType *pType = node->GetAssetType();
			HELIUM_ASSERT( pType );
			variant = std::string( *pType->GetName() );
		}
		break;
	}
}
Exemplo n.º 9
0
/// @copydoc PackageLoader::BeginLoadObject()
size_t LoosePackageLoader::BeginLoadObject( AssetPath path, Reflect::ObjectResolver *pResolver, bool forceReload )
{	
	HELIUM_TRACE( TraceLevels::Info, TXT(" LoosePackageLoader::BeginLoadObject - Loading path %s\n"), *path.ToString() );

	HELIUM_TRACE(
		TraceLevels::Debug,
		TXT( "LoosePackageLoader::BeginLoadObject: Beginning load for path \"%s\".\n"),
		*path.ToString());

	
	HELIUM_TRACE(
		TraceLevels::Debug,
		TXT( "LoosePackageLoader::BeginLoadObject: Beginning load for path \"%s\". pResolver = %x\n"),
		*path.ToString(),
		pResolver);

	// Make sure preloading has completed.
	HELIUM_ASSERT( m_preloadedCounter != 0 );
	if( !m_preloadedCounter )
	{
		return Invalid< size_t >();
	}

	// If this package is requested, simply provide the (already loaded) package instance.
	if( path == m_packagePath )
	{
		LoadRequest* pRequest = m_loadRequestPool.Allocate();
		HELIUM_ASSERT( pRequest );

		HELIUM_ASSERT( m_spPackage );
		pRequest->spObject = m_spPackage.Ptr();

		SetInvalid( pRequest->index );
		HELIUM_ASSERT( !pRequest->spType );
		HELIUM_ASSERT( !pRequest->spTemplate );
		HELIUM_ASSERT( !pRequest->spOwner );
		SetInvalid( pRequest->templateLoadId );
		SetInvalid( pRequest->ownerLoadId );
		SetInvalid( pRequest->persistentResourceDataLoadId );
		pRequest->pCachedObjectDataBuffer = NULL;
		pRequest->cachedObjectDataBufferSize = 0;
		SetInvalid( pRequest->asyncFileLoadId );
		pRequest->pAsyncFileLoadBuffer = NULL;
		pRequest->asyncFileLoadBufferSize = 0;
		pRequest->pResolver = NULL;
		pRequest->forceReload = forceReload;

		pRequest->flags = LOAD_FLAG_PRELOADED;

		size_t requestId = m_loadRequests.Add( pRequest );

		return requestId;
	}

	size_t objectIndex = FindObjectByPath( path );
	size_t objectCount = GetObjectCount();

	if( objectIndex >= objectCount )
	{
		HELIUM_TRACE(
			TraceLevels::Error,
			TXT( "LoosePackageLoader::BeginLoadObject(): Failed to locate \"%s\" for loading. Verify the file exists.\n" ),
			*path.ToString() );

		return Invalid< size_t >();
	}

	SerializedObjectData& rObjectData = m_objects[ objectIndex ];

	// Verify that the metadata was read successfully
	if( !rObjectData.bMetadataGood )
	{
		HELIUM_TRACE(
			TraceLevels::Error,
			TXT( "LoosePackageLoader::BeginLoadObject(): Failed to read metadata for object \"%s\" during PackagePreload. Search log for parsing errors.\n" ),
			*path.ToString() );

		return Invalid< size_t >();
	}

	// Locate the type object.
	HELIUM_ASSERT( !rObjectData.typeName.IsEmpty() );
	AssetType* pType = AssetType::Find( rObjectData.typeName );
	if( !pType )
	{
		HELIUM_TRACE(
			TraceLevels::Error,
			TXT( "LoosePackageLoader::BeginLoadObject(): Failed to locate type \"%s\" for loading object \"%s\".\n" ),
			*rObjectData.typeName,
			*path.ToString() );

		HELIUM_TRACE(
			TraceLevels::Info,
			TXT( "Current registered types:\n" ) );

		for ( AssetType::ConstIterator iter = AssetType::GetTypeBegin();
			iter != AssetType::GetTypeEnd(); ++iter)
		{
			HELIUM_TRACE(
				TraceLevels::Info,
				TXT( " - %s\n" ),
				*iter->GetName() );
		}

		return Invalid< size_t >();
	}

#ifndef NDEBUG
	size_t loadRequestSize = m_loadRequests.GetSize();
	for( size_t loadRequestIndex = 0; loadRequestIndex < loadRequestSize; ++loadRequestIndex )
	{
		if( !m_loadRequests.IsElementValid( loadRequestIndex ) )
		{
			continue;
		}

		LoadRequest* pRequest = m_loadRequests[ loadRequestIndex ];
		HELIUM_ASSERT( pRequest );
		HELIUM_ASSERT( pRequest->index != objectIndex );
		if( pRequest->index == objectIndex )
		{
			return Invalid< size_t >();
		}
	}
#endif

	LoadRequest* pRequest = m_loadRequestPool.Allocate();
	HELIUM_ASSERT( pRequest );
	HELIUM_ASSERT( !pRequest->spObject );
	pRequest->index = objectIndex;
	pRequest->spType = pType;
	HELIUM_ASSERT( !pRequest->spTemplate );
	HELIUM_ASSERT( !pRequest->spOwner );
	SetInvalid( pRequest->templateLoadId );
	SetInvalid( pRequest->ownerLoadId );
	SetInvalid( pRequest->persistentResourceDataLoadId );
	pRequest->pCachedObjectDataBuffer = NULL;
	pRequest->cachedObjectDataBufferSize = 0;
	SetInvalid( pRequest->asyncFileLoadId );
	pRequest->pAsyncFileLoadBuffer = NULL;
	pRequest->asyncFileLoadBufferSize = 0;
	pRequest->pResolver = pResolver;
	pRequest->forceReload = forceReload;

	pRequest->flags = 0;

	// If a fully-loaded object already exists with the same name, do not attempt to re-load the object (just mark
	// the request as complete).

	if ( !forceReload )
	{
		pRequest->spObject = Asset::FindObject( path );
	}
	
	Asset* pObject = pRequest->spObject;
	if( pObject && pObject->IsFullyLoaded() )
	{
		pRequest->flags = LOAD_FLAG_PRELOADED;
	}
	else
	{
		HELIUM_ASSERT( !pObject || !pObject->GetAnyFlagSet( Asset::FLAG_LOADED | Asset::FLAG_LINKED ) );

		// Begin loading the template and owner objects.  Note that there isn't much reason to check for failure
		// until we tick this request, as we need to make sure any other load requests for the template/owner that
		// did succeed are properly synced anyway.
		AssetLoader* pAssetLoader = AssetLoader::GetStaticInstance();
		HELIUM_ASSERT( pAssetLoader );

		if( rObjectData.templatePath.IsEmpty() )
		{
			// Make sure the template is fully loaded.
			Asset* pTemplate = pType->GetTemplate();
			rObjectData.templatePath = pTemplate->GetPath();
			if( pTemplate->IsFullyLoaded() )
			{
				pRequest->spTemplate = pTemplate;
			}
			else
			{
				pRequest->templateLoadId = pAssetLoader->BeginLoadObject( rObjectData.templatePath );
			}
		}
		else
		{
			pRequest->templateLoadId = pAssetLoader->BeginLoadObject( rObjectData.templatePath );
		}

		AssetPath ownerPath = path.GetParent();
		if( ownerPath == m_packagePath )
		{
			// Easy check: if the owner is this package (which is likely), we don't need to load it.
			pRequest->spOwner = m_spPackage.Ptr();
		}
		else if( !ownerPath.IsEmpty() )
		{
			pRequest->ownerLoadId = pAssetLoader->BeginLoadObject( ownerPath );
		}
	}

	size_t requestId = m_loadRequests.Add( pRequest );

	return requestId;
}
Exemplo n.º 10
0
bool ModelImporter::ImportAnimations()
{
    if (!animationInfo_.Size())
    {
       if (!ImportAnimation(asset_->GetPath(), "RootAnim"))
           return false;
    }

    // embedded animations
    for (unsigned i = 0; i < animationInfo_.Size(); i++)
    {
        const SharedPtr<AnimationImportInfo>& info = animationInfo_[i];
        if (!ImportAnimation(asset_->GetPath(), info->GetName(), info->GetStartTime(), info->GetEndTime()))
            return false;
    }

    // add @ animations

    FileSystem* fs = GetSubsystem<FileSystem>();
    String pathName, fileName, ext;
    SplitPath(asset_->GetPath(), pathName, fileName, ext);

    Vector<String> results;

    fs->ScanDir(results, pathName, ext, SCAN_FILES, false);

    for (unsigned i = 0; i < results.Size(); i++)
    {
        const String& result = results[i];

        if (result.Contains("@"))
        {
            Vector<String> components = GetFileName(result).Split('@');

            if (components.Size() == 2 && components[1].Length() && components[0] == fileName)
            {
                String animationName = components[1];
                AssetDatabase* db = GetSubsystem<AssetDatabase>();
                Asset* asset = db->GetAssetByPath(pathName + result);
                assert(asset);
                assert(asset->GetImporter()->GetType() == ModelImporter::GetTypeStatic());

                ModelImporter* importer = (ModelImporter*) asset->GetImporter();

                if (!importer->animationInfo_.Size())
                {
                   if (!ImportAnimation(asset->GetPath(), animationName))
                       return false;
                }
                else
                {
                    // embedded animations
                    for (unsigned i = 0; i < importer->animationInfo_.Size(); i++)
                    {
                        const SharedPtr<AnimationImportInfo>& info = importer->animationInfo_[i];
                        if (!ImportAnimation(asset->GetPath(), info->GetName(), info->GetStartTime(), info->GetEndTime()))
                            return false;
                    }
                }


            }
        }
    }



    return true;
}
Exemplo n.º 11
0
/// @copydoc PackageLoader::TryFinishLoadObject()
bool CachePackageLoader::TryFinishLoadObject( size_t requestId, AssetPtr& rspObject )
{
	HELIUM_ASSERT( requestId < m_loadRequests.GetSize() );
	HELIUM_ASSERT( m_loadRequests.IsElementValid( requestId ) );

	LoadRequest* pRequest = m_loadRequests[ requestId ];
	HELIUM_ASSERT( pRequest );
	if( !( pRequest->flags & LOAD_FLAG_PRELOADED ) )
	{
		return false;
	}

	// Sync on template and owner dependencies.
	AssetLoader* pAssetLoader = AssetLoader::GetInstance();
	HELIUM_ASSERT( pAssetLoader );

	if( IsValid( pRequest->ownerLoadIndex ) )
	{
		size_t linkLoadId = pRequest->ownerLoadIndex;
		if( IsValid( linkLoadId ) && !pAssetLoader->TryFinishLoad( linkLoadId, pRequest->spOwner ) )
		{
			return false;
		}

		SetInvalid( pRequest->ownerLoadIndex );
	}

	rspObject = pRequest->spObject;
	Asset* pObject = rspObject;
	if( pObject && ( pRequest->flags & LOAD_FLAG_ERROR ) )
	{
		pObject->SetFlags( Asset::FLAG_BROKEN );
	}

	if ( pObject->IsPackage() )
	{
		Package *pPackage = Reflect::AssertCast<Package>( pObject );
		pPackage->SetLoader( this );
	}

	pRequest->spObject.Release();

	HELIUM_ASSERT( IsInvalid( pRequest->asyncLoadId ) );
	HELIUM_ASSERT( !pRequest->pAsyncLoadBuffer );

	//pRequest->spTemplate.Release();
	pRequest->spOwner.Release();

	HELIUM_ASSERT( IsInvalid( pRequest->ownerLoadIndex ) );
	//HELIUM_ASSERT( IsInvalid( pRequest->templateLoadIndex ) );

	HELIUM_ASSERT( pObject || pRequest->pEntry );
	HELIUM_TRACE(
		TraceLevels::Debug,
		"CachePackageLoader::TryFinishLoadObject(): Load request for \"%s\" (ID: %" PRIuSZ ") synced.\n",
		*( pObject ? pObject->GetPath() : pRequest->pEntry->path ).ToString(),
		requestId );

	m_loadRequests.Remove( requestId );
	m_loadRequestPool.Release( pRequest );

	return true;
}
Exemplo n.º 12
0
/// Modify the name, owner, or instance index of this object.
///
/// @param[in] rParameters  Object rename parameters.
///
/// @return  True if this object was renamed successfully, false if not.
///
/// @see GetName(), GetOwner(), GetInstanceIndex()
bool Asset::Rename( const RenameParameters& rParameters )
{
	Name name = rParameters.name;
	Asset* pOwner = rParameters.spOwner;
	uint32_t instanceIndex = rParameters.instanceIndex;

	HELIUM_TRACE(
		TraceLevels::Debug,
		TXT("Asset::Rename(): Renaming object \"%s\" to \"%s\" (Old Owner: \"%s\". New Owner: \"%s\".)\n"),
		*m_name,
		*rParameters.name,
		m_spOwner.ReferencesObject() ? *m_spOwner->GetPath().ToString() : TXT("[none]"),
		rParameters.spOwner.ReferencesObject() ? *rParameters.spOwner->GetPath().ToString() : TXT("[none]"));

	// Only allow setting an empty name if no owner or instance index are given and this object has no children.
	if( name.IsEmpty() )
	{
		HELIUM_ASSERT( !pOwner );
		HELIUM_ASSERT( IsInvalid( instanceIndex ) );
		if( pOwner || IsValid( instanceIndex ) )
		{
			HELIUM_TRACE(
				TraceLevels::Error,
				( TXT( "Asset::Rename(): Objects cannot have name information cleared if being assigned an " )
				  TXT( "owner or instance index.\n" ) ) );

			return false;
		}

		HELIUM_ASSERT( !m_wpFirstChild );
		if( m_wpFirstChild )
		{
			HELIUM_TRACE(
				TraceLevels::Error,
				TXT( "Asset::Rename(): Cannot clear name information for objects with children.\n" ) );

			return false;
		}
	}

	// Don't allow setting the owner to ourself.
	if( pOwner == this )
	{
		HELIUM_TRACE( TraceLevels::Error, TXT( "Asset::Rename(): Cannot set the owner of an object to itself.\n" ) );

		return false;
	}

	// Don't allow setting the owner to an object with no name information.
	if( pOwner && pOwner->m_name.IsEmpty() )
	{
		HELIUM_TRACE(
			TraceLevels::Error,
			TXT( "Asset::Rename(): Cannot set the owner of an object to an object with no path information.\n" ) );

		return false;
	}

	if( IsPackage() )
	{
		// Don't allow package objects to be children of non-package objects.
		if( pOwner && !pOwner->IsPackage() )
		{
			HELIUM_TRACE(
				TraceLevels::Error,
				TXT( "Asset::Rename(): Cannot set a non-package as the owner of a package.\n" ) );

			return false;
		}

		// Don't allow instance indexing for packages.
		if( IsValid( instanceIndex ) )
		{
			HELIUM_TRACE(
				TraceLevels::Error,
				TXT( "Asset::Rename(): Instance indexing not supported for packages.\n" ) );

			return false;
		}
	}

	// Don't need to do anything if the name, owner, and instance index are not changing.
	if( name == m_name &&
		pOwner == m_spOwner &&
		( instanceIndex == m_instanceIndex || ( instanceIndex == INSTANCE_INDEX_AUTO && IsValid( m_instanceIndex ) ) ) )
	{
		return true;
	}

	// Hold onto a reference to the current owner until we return from this function.  This is done in case this object
	// has the last strong reference to it, in which case we would encounter a deadlock if clearing its reference while
	// we still have a write lock on the object list (object destruction also requires acquiring a write lock).
	AssetPtr spOldOwner = m_spOwner;

	{
		// Acquire a write lock on the object list to prevent objects from being added and removed as well as keep
		// objects from being renamed while this object is being renamed.
		ScopeWriteLock scopeLock( sm_objectListLock );

		// Get the list of children belonging to the new owner.
		AssetWPtr& rwpOwnerFirstChild = ( pOwner ? pOwner->m_wpFirstChild : sm_wpFirstTopLevelObject );

		// Don't check for name clashes if we're clearing the object path name information.
		if( !name.IsEmpty() )
		{
			// Resolve name clashes either through the instance index lookup map (if an instance index will be assigned)
			// or through a child object search (if no instance index will be used).
			if( IsValid( instanceIndex ) )
			{
				// Get the instance index map for the requested object name.
				ChildNameInstanceIndexMap& rNameInstanceIndexMap = GetNameInstanceIndexMap();
				HELIUM_ASSERT( sm_pEmptyNameInstanceIndexMap );
				HELIUM_ASSERT( sm_pEmptyInstanceIndexSet );

				sm_pEmptyNameInstanceIndexMap->First() = ( pOwner ? pOwner->GetPath() : AssetPath( NULL_NAME ) );
				sm_pEmptyInstanceIndexSet->First() = name;

				ChildNameInstanceIndexMap::Accessor childNameMapAccessor;
				rNameInstanceIndexMap.Insert( childNameMapAccessor, *sm_pEmptyNameInstanceIndexMap );

				NameInstanceIndexMap::Accessor indexSetAccessor;
				childNameMapAccessor->Second().Insert( indexSetAccessor, *sm_pEmptyInstanceIndexSet );

				InstanceIndexSet& rIndexSet = indexSetAccessor->Second();
				InstanceIndexSet::ConstAccessor indexAccessor;

				if( instanceIndex == INSTANCE_INDEX_AUTO )
				{
					// Pick an unused instance index.
					instanceIndex = 0;
					while( !rIndexSet.Insert( indexAccessor, instanceIndex ) )
					{
						++instanceIndex;
						HELIUM_ASSERT( instanceIndex < INSTANCE_INDEX_AUTO );
					}
				}
				else
				{
					// Attempt to acquire the specified instance index.
					if( !rIndexSet.Insert( indexAccessor, instanceIndex ) )
					{
						HELIUM_TRACE(
							TraceLevels::Error,
							( TXT( "Asset::Rename(): Object already exists with the specified owner (%s), name " )
							  TXT( "(%s), and instance index (%" ) PRIu32 ").\n" ),
							( pOwner ? *pOwner->GetPath().ToString() : TXT( "none" ) ),
							*name,
							instanceIndex );

						return false;
					}
				}
			}
			else
			{
				// Check each child of the new owner for a name clash.
				for( Asset* pChild = rwpOwnerFirstChild; pChild != NULL; pChild = pChild->m_wpNextSibling )
				{
					if( pChild->m_name == name && pChild->m_instanceIndex == instanceIndex )
					{
						HELIUM_TRACE(
							TraceLevels::Error,
							( TXT( "Asset::Rename(): Object already exists with the specified owner (%s) and " )
							  TXT( "name (%s).\n" ) ),
							( pOwner ? *pOwner->GetPath().ToString() : TXT( "none" ) ),
							*name );

						return false;
					}
				}
			}
		}

		// Remove any old instance index tracking for the old path name.
		if( IsValid( m_instanceIndex ) )
		{
			AssetPath ownerPath = ( spOldOwner ? spOldOwner->GetPath() : AssetPath( NULL_NAME ) );

			ChildNameInstanceIndexMap& rNameInstanceIndexMap = GetNameInstanceIndexMap();

			ChildNameInstanceIndexMap::Accessor childMapAccessor;
			HELIUM_VERIFY( rNameInstanceIndexMap.Find( childMapAccessor, ownerPath ) );

			NameInstanceIndexMap& rNameMap = childMapAccessor->Second();
			NameInstanceIndexMap::Accessor nameMapAccessor;
			HELIUM_VERIFY( rNameMap.Find( nameMapAccessor, m_name ) );

			InstanceIndexSet& rIndexSet = nameMapAccessor->Second();
			HELIUM_VERIFY( rIndexSet.Remove( m_instanceIndex ) );

			/*
			if( rIndexSet.IsEmpty() )
			{
				HELIUM_VERIFY( rNameMap.Remove( nameMapAccessor ) );
				if( rNameMap.IsEmpty() )
				{
					HELIUM_VERIFY( rNameInstanceIndexMap.Remove( childMapAccessor ) );
				}
			}
			*/
		}

		// If the owner of this object is changing, remove this object from its old owner's list and add it to the new
		// owner.
		if( spOldOwner.Get() != pOwner || ( m_name.IsEmpty() ? !name.IsEmpty() : name.IsEmpty() ) )
		{
			// Object should not be in any child object lists if its name is empty.
			if( !m_name.IsEmpty() )
			{
				AssetWPtr& rwpOldOwnerFirstChild =
					( spOldOwner ? spOldOwner->m_wpFirstChild : sm_wpFirstTopLevelObject );

				Asset* pPreviousChild = NULL;
				Asset* pChild = rwpOldOwnerFirstChild;
				while( pChild )
				{
					if( pChild == this )
					{
						( pPreviousChild ? pPreviousChild->m_wpNextSibling : rwpOldOwnerFirstChild ) = m_wpNextSibling;
						m_wpNextSibling.Release();

						break;
					}

					pPreviousChild = pChild;
					pChild = pChild->m_wpNextSibling;
				}
			}

			// If you assert here, it's possible that sm_wpFirstTopLevelObject is null. This can happen if an asset is destroyed
			// after the asset system is shut down
			HELIUM_ASSERT( !m_wpNextSibling );

			// Only store the object in a child object list if it is being given a valid name.
			if( !name.IsEmpty() )
			{
				m_wpNextSibling = rwpOwnerFirstChild;
				rwpOwnerFirstChild = this;
			}
		}

		// Set the new path name.
		m_name = name;
		m_spOwner = pOwner;
		m_instanceIndex = instanceIndex;

		// Update path information for this object and its children.
		UpdatePath();
	}

	return true;
}
Exemplo n.º 13
0
void ProjectPanel::OnLoadForEdit( wxCommandEvent& event )
{
    wxDataViewItemArray selection;
    int numSelected = m_DataViewCtrl->GetSelections( selection );

    for (int i = 0; i < numSelected; ++i)
    {
        Asset *pAsset = static_cast<Asset *>( selection[i].GetID() );

        if (pAsset && pAsset->IsPackage())
        {
            ForciblyFullyLoadedPackageManager::GetStaticInstance()->ForceFullyLoadPackage(pAsset->GetPath());
        }
    }
}
Exemplo n.º 14
0
void SceneView3D::HandleDragEnded(StringHash eventType, VariantMap& eventData)
{
    using namespace DragEnded;

    UIDragObject* dragObject = static_cast<UIDragObject*>(eventData[P_DRAGOBJECT].GetPtr());

    if (dragNode_.NotNull())
    {
        VariantMap neventData;
        neventData[EditorActiveNodeChange::P_NODE] = dragNode_;
        SendEvent(E_EDITORACTIVENODECHANGE, neventData);
    }

    if (dragObject && dragObject->GetObject()->GetType() == ToolCore::Asset::GetTypeStatic())
    {
        Asset* asset = (ToolCore::Asset*) dragObject->GetObject();

        if (asset->GetImporterTypeName() == "MaterialImporter") {

            Material* material = GetSubsystem<ResourceCache>()->GetResource<Material>(asset->GetPath());

            if (material) {

                material = material;

                Ray camRay  = GetCameraRay();

                PODVector<RayQueryResult> result;

                RayOctreeQuery query(result, camRay, RAY_TRIANGLE, camera_->GetFarClip(), DRAWABLE_GEOMETRY, 0x7fffffff);
                octree_->RaycastSingle(query);

                if (query.result_.Size())
                {
                    const RayQueryResult& r = result[0];

                    if (r.drawable_ && (r.drawable_->GetType() == StaticModel::GetTypeStatic() || r.drawable_->GetType() == AnimatedModel::GetTypeStatic()))
                    {
                        ((StaticModel*)r.drawable_)->SetMaterial(material);

                    }
                }

            }

        }

    }

    dragAssetGUID_ = "";
    dragNode_ = 0;
}
Exemplo n.º 15
0
void SceneView3D::HandleDragEnterWidget(StringHash eventType, VariantMap& eventData)
{
    using namespace DragEnterWidget;

    UIWidget* widget = static_cast<UIWidget*>(eventData[P_WIDGET].GetPtr());

    if (widget != this)
        return;

    UIDragObject* dragObject = static_cast<UIDragObject*>(eventData[P_DRAGOBJECT].GetPtr());

    Object* object = dragObject->GetObject();

    if (!object)
        return;

    if (object->GetType() == Asset::GetTypeStatic())
    {
        Asset* asset = (Asset*) object;
        AssetImporter* importer = asset->GetImporter();

        if (!importer)
            return;

        StringHash importerType = importer->GetType();

        if (importerType == PrefabImporter::GetTypeStatic())
        {
            dragNode_ = scene_->CreateChild(asset->GetName());
            PrefabComponent* pc = dragNode_->CreateComponent<PrefabComponent>();
            pc->SetPrefabGUID(asset->GetGUID());
        }
        else if (importerType == ModelImporter::GetTypeNameStatic())
        {
            dragNode_ = scene_->CreateChild();

            SharedPtr<File> file(new File(context_, asset->GetCachePath()));
            SharedPtr<XMLFile> xml(new XMLFile(context_));

            if (!xml->Load(*file))
                return;

            dragNode_->LoadXML(xml->GetRoot());
            dragNode_->SetName(asset->GetName());
        }
        else if (importerType == SpriterImporter::GetTypeNameStatic())
        {
            AnimationSet2D* animationSet = GetSubsystem<ResourceCache>()->GetResource<AnimationSet2D>(asset->GetPath());

            String animationName;

            if (animationSet && animationSet->GetNumAnimations())
            {
                animationName = animationSet->GetAnimation(0)->GetName();
            }

            dragNode_ = scene_->CreateChild(asset->GetName());

            AnimatedSprite2D* sprite = dragNode_->CreateComponent<AnimatedSprite2D>();

            if (!animationName.Length())
                sprite->SetAnimationSet(animationSet);
            else
                sprite->SetAnimation(animationSet, animationName);

        }
        else if (importerType == TextureImporter::GetTypeNameStatic())
        {
            dragNode_ = scene_->CreateChild(asset->GetName());

            Sprite2D* spriteGraphic = GetSubsystem<ResourceCache>()->GetResource<Sprite2D>(asset->GetPath());

            StaticSprite2D* sprite = dragNode_->CreateComponent<StaticSprite2D>();

            sprite->SetSprite(spriteGraphic);
        }


        if (dragNode_.NotNull())
        {
            Input* input = GetSubsystem<Input>();
            IntVector2 pos = input->GetMousePosition();
            UpdateDragNode(pos.x_, pos.y_);
        }



        //LOGINFOF("Dropped %s : %s on SceneView3D", asset->GetPath().CString(), asset->GetGUID().CString());
    }

}