//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
//**************** Copyright (c) 2016 Marko Pintera (marko.pintera@gmail.com). All rights reserved. **********************//
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using bs;
namespace bs.Editor
{
/** @addtogroup Library
* @{
*/
///
/// The primary location for interacting with all the resources in the current project. A complete hierarchy of
/// resources is provided which can be interacted with by importing new ones, deleting them, moving, renaming and similar.
///
public sealed class ProjectLibrary : ScriptObject
{
///
/// Root entry of the project library, referencing the top level resources folder.
///
public static DirectoryEntry Root { get { return Internal_GetRoot(); } }
///
/// Absolute path to the current project's project library resource folder.
///
public static string ResourceFolder { get { return Internal_GetResourceFolder(); } }
///
/// Triggered when a new entry is added to the project library. Provided path relative to the project library
/// resources folder.
///
public static event Action OnEntryAdded;
///
/// Triggered when an entry is removed from the project library. Provided path relative to the project library
/// resources folder.
///
public static event Action OnEntryRemoved;
///
/// Triggered when an entry is (re)imported in the project library. Provided path relative to the project library
/// resources folder.
///
public static event Action OnEntryImported;
///
/// Checks wheher an asset import is currently in progress.
///
internal static bool ImportInProgress { get { return InProgressImportCount > 0; } }
///
/// Returns the number of resources currently being imported.
///
internal static int InProgressImportCount { get { return Internal_GetInProgressImportCount(); } }
///
/// Gets the import progress of all files currently being imported. Returns 0 if no import in progress.
///
internal static float ImportProgressPercent { get; private set; }
private static int totalFilesToImport;
///
/// Checks the project library folder for any modifications and reimports the required resources.
///
/// If true this method will block until the project library has done refreshing,
/// otherwise the refresh will happen over the course of this and next frames.
public static void Refresh(bool synchronous = false)
{
totalFilesToImport += Internal_Refresh(ResourceFolder, synchronous);
if (synchronous)
totalFilesToImport = 0;
}
///
/// Checks the specified folder for any modifications and reimports the required resources.
///
/// Path to a file or folder to refresh. Relative to the project library resources folder or
/// absolute.
public static void Refresh(string path)
{
totalFilesToImport += Internal_Refresh(path, false);
}
///
/// Registers a new resource in the library.
///
/// Resource instance to add to the library. A copy of the resource will be saved at the
/// provided path.
/// Path where where to store the resource. Absolute or relative to the resources folder.
public static void Create(Resource resource, string path)
{
Internal_Create(resource, path);
}
///
/// Updates a resource that is already in the library.
///
/// Resource to save.
public static void Save(Resource resource)
{
Internal_Save(resource);
}
///
/// Loads a resource from the project library.
///
/// Type of the resource to load.
/// Path of the resource to load. Absolute or relative to the resources folder. If a
/// sub-resource within a file is needed, append the name of the subresource to the path (
/// for example mymesh.fbx/my_animation).
/// Instance of the loaded resource, or null if not found.
public static T Load(string path) where T : Resource
{
return (T)Internal_Load(path);
}
///
/// Triggers a reimport of a resource using the provided import options, if needed.
///
/// Path to the resource to reimport, absolute or relative to resources folder.
/// Optional import options to use when importing the resource. Caller must ensure the import
/// options are of the correct type for the resource in question. If null is provided default
/// import options are used.
/// Should the resource be reimported even if no changes are detected.
/// If true the import will happen synchronously on the calling thread. If false the
/// import operation will be queued for execution on a worker thread.
public static void Reimport(string path, ImportOptions options = null, bool force = false, bool synchronous = false)
{
Internal_Reimport(path, options, force, synchronous);
}
///
/// Checks how far along is the import for the specified file.
///
/// Path to the file to check, absolute or relative to the resources folder.
/// Reports 1 if the file is fully imported. Reports 0 if the import has not started or the file isn't
/// even queued for import. Reports >= 0 if the file is in process of being imported. Note that not all importers
/// support fine grained progress reporting, in which case the import progress will be reported as a binary 0 or 1.
///
public static float GetImportProgress(string path)
{
return Internal_GetImportProgress(path);
}
///
/// Cancels import for all resources currently queued for import. This method returns immediately but it may take
/// some time until imports are fully canceled.
///
public static void CancelImport()
{
Internal_CancelImport();
}
///
/// Checks does the project library contain a file or folder at the specified path.
///
/// Path to the file/folder to check, absolute or relative to resources folder.
/// True if the element exists, false otherwise.
public static bool Exists(string path)
{
return GetEntry(path) != null;
}
///
/// Attempts to locate a library entry that describes a file or a folder in the project library.
///
/// Path to the entry to retrieve, absolute or relative to resources folder.
/// Library entry if found, null otherwise. This object can become invalid on the next library refresh
/// and you are not meant to hold a permanent reference to it.
public static LibraryEntry GetEntry(string path)
{
return Internal_GetEntry(path);
}
///
/// Checks whether the provided path points to a sub-resource. Sub-resource is any resource that is not the
/// primary resource in the file.
///
/// Path to the entry, absolute or relative to resources folder.
/// True if the path is a sub-resource, false otherwise.
public static bool IsSubresource(string path)
{
return Internal_IsSubresource(path);
}
///
/// Attempts to locate meta-data for a resource at the specified path.
///
/// Path to the entry to retrieve, absolute or relative to resources folder. If a sub-resource
/// within a file is needed, append the name of the subresource to the path (for example
/// mymesh.fbx/my_animation).
/// Resource meta-data if the resource was found, null otherwise.
public static ResourceMeta GetMeta(string path)
{
return Internal_GetMeta(path);
}
///
/// Searches the library for a pattern and returns all entries matching it.
///
/// Pattern to search for. Use wildcard * to match any character(s).
/// Type of resources to search for. If null all entries will be searched.
/// A set of entries matching the pattern. These objects can become invalid on the next library refresh
/// and you are not meant to hold a permanent reference to them.
public static LibraryEntry[] Search(string pattern, ResourceType[] types = null)
{
return Internal_Search(pattern, types);
}
///
/// Returns a path to a resource stored in the project library.
///
/// Resource to find the path for.
/// Path to relative to the project library resources folder if resource was found, null otherwise.
///
public static string GetPath(Resource resource)
{
return Internal_GetPath(resource);
}
///
/// Returns a path to a resource with the specified UUID stored in the project library.
///
/// Unique identifier of the resources to retrieve the path of.
/// Path to relative to the project library resources folder if resource was found, null otherwise.
///
public static string GetPath(UUID uuid)
{
return Internal_GetPathFromUUID(ref uuid);
}
///
/// Deletes a resource in the project library.
///
/// Path to the entry to delete, absolute or relative to resources folder.
public static void Delete(string path)
{
Internal_Delete(path);
}
///
/// Creates a new folder in the library.
///
/// Path of the folder to create. Absolute or relative to the resources folder.
public static void CreateFolder(string path)
{
Internal_CreateFolder(path);
}
///
/// Renames an entry in the project library.
///
/// Path of the entry to rename, absolute or relative to resources folder.
/// New name of the entry with an extension.
/// Determines should the entry be deleted if one with the provided name already exists. If
/// this is false and an entry already exists, no rename operation will be performed.
public static void Rename(string path, string name, bool overwrite = false)
{
Internal_Rename(path, name, false);
}
///
/// Moves an entry in the project library from one path to another.
///
/// Source path of the entry, absolute or relative to resources folder.
/// Destination path of the entry, absolute or relative to resources folder.
/// Determines should the entry be deleted if one at the destination path already exists. If
/// this is false and an entry already exists, no move operation will be performed.
public static void Move(string oldPath, string newPath, bool overwrite = false)
{
Internal_Move(oldPath, newPath, overwrite);
}
///
/// Copies an entry in the project library from one path to another.
///
/// Source path of the entry, absolute or relative to resources folder.
/// Destination path of the entry, absolute or relative to resources folder.
/// Determines should the entry be deleted if one at the destination path already exists. If
/// this is false and an entry already exists, no copy operation will be performed.
public static void Copy(string source, string destination, bool overwrite = false)
{
Internal_Copy(source, destination, overwrite);
}
///
/// Controls should a resource be included an a build. All dependant resources will also be included.
///
/// Path of the resource to include, absolute or relative to resources folder.
/// True if it should be included, false otherwise.
public static void SetIncludeInBuild(string path, bool include)
{
Internal_SetIncludeInBuild(path, include);
}
///
/// Assigns a non-specific editor data object to the resource at the specified path.
///
/// Path to the resource to modify, absolute or relative to resources folder.
/// Data to assign to the resource, which can later be retrieved from the resource's
/// meta-data as needed.
public static void SetEditorData(string path, object userData)
{
Internal_SetEditorData(path, userData);
}
///
/// Triggers reimport for queued resource. Should be called once per frame.
///
internal static void Update()
{
Internal_FinalizeImports();
int inProgressImports = InProgressImportCount;
if (inProgressImports > 0)
{
int numRemaining = totalFilesToImport - inProgressImports;
float pct = 1.0f;
if (totalFilesToImport > 0)
pct = numRemaining / (float)totalFilesToImport;
ImportProgressPercent = pct;
EditorApplication.SetStatusImporting(true, pct);
}
else
{
totalFilesToImport = 0;
ImportProgressPercent = 0.0f;
EditorApplication.SetStatusImporting(false, 0.0f);
}
}
///
/// Triggered internally by the runtime when a new entry is added to the project library.
///
/// Path relative to the project library resources folder.
private static void Internal_DoOnEntryAdded(string path)
{
if (OnEntryAdded != null)
OnEntryAdded(path);
}
///
/// Triggered internally by the runtime when an entry is removed from the project library.
///
/// Path relative to the project library resources folder.
private static void Internal_DoOnEntryRemoved(string path)
{
if (OnEntryRemoved != null)
OnEntryRemoved(path);
}
///
/// Triggered internally by the runtime when an entry is (re)imported in the project library.
///
/// Path relative to the project library resources folder.
private static void Internal_DoOnEntryImported(string path)
{
if (OnEntryImported != null)
OnEntryImported(path);
}
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern int Internal_Refresh(string path, bool synchronous);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_FinalizeImports();
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern int Internal_GetInProgressImportCount();
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_Create(Resource resource, string path);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern Resource Internal_Load(string path);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_Save(Resource resource);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern DirectoryEntry Internal_GetRoot();
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern bool Internal_IsSubresource(string path);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_Reimport(string path, ImportOptions options, bool force, bool synchronous);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern float Internal_GetImportProgress(string path);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_CancelImport();
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern LibraryEntry Internal_GetEntry(string path);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern ResourceMeta Internal_GetMeta(string path);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern LibraryEntry[] Internal_Search(string path, ResourceType[] types);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string Internal_GetPath(Resource resource);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string Internal_GetPathFromUUID(ref UUID uuid);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_Delete(string path);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_CreateFolder(string path);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_Rename(string path, string name, bool overwrite);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_Move(string oldPath, string newPath, bool overwrite);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_Copy(string source, string destination, bool overwrite);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string Internal_GetResourceFolder();
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_SetIncludeInBuild(string path, bool force);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_SetEditorData(string path, object userData);
}
///
/// Type of project library entries.
///
public enum LibraryEntryType // Note: Must match the C++ enum ProjectLibrary::LibraryEntryType
{
File, Directory
}
///
/// Type of resources supported by the project library.
///
public enum ResourceType // Note: Must match the C++ enum ScriptResourceType
{
Texture, SpriteTexture, Mesh, Font, Shader, ShaderInclude, Material, Prefab, PlainText, ScriptCode, StringTable,
GUISkin, PhysicsMaterial, PhysicsMesh, AudioClip, AnimationClip, VectorField, Undefined
}
///
/// A generic project library entry that may be a file or a folder.
///
public class LibraryEntry : ScriptObject
{
///
/// Path of the library entry, relative to the project library resources folder.
///
public string Path { get { return Internal_GetPath(mCachedPtr); } }
///
/// Name of the library entry.
///
public string Name { get { return Internal_GetName(mCachedPtr); } }
///
/// Type of the library entry.
///
public LibraryEntryType Type { get { return Internal_GetType(mCachedPtr); } }
///
/// Directory entry that contains this entry. This may be null for the root entry.
///
public DirectoryEntry Parent { get { return Internal_GetParent(mCachedPtr); } }
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string Internal_GetPath(IntPtr thisPtr);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string Internal_GetName(IntPtr thisPtr);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern LibraryEntryType Internal_GetType(IntPtr thisPtr);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern DirectoryEntry Internal_GetParent(IntPtr thisPtr);
}
///
/// A project library entry representing a directory that contains other entries.
///
public class DirectoryEntry : LibraryEntry
{
///
/// A set of entries contained in this entry.
///
public LibraryEntry[] Children { get { return Internal_GetChildren(mCachedPtr); } }
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern LibraryEntry[] Internal_GetChildren(IntPtr thisPtr);
}
///
/// A library entry representing a file.
///
public class FileEntry : LibraryEntry
{
///
/// Import options used for importing the resources in the file.
///
public ImportOptions Options { get { return Internal_GetImportOptions(mCachedPtr); } }
///
/// Returns meta-data for all resources part of the file represented by this object.
///
public ResourceMeta[] ResourceMetas { get { return Internal_GetResourceMetas(mCachedPtr); } }
///
/// Determines will the resources in the file be included in the project build.
///
public bool IncludeInBuild { get { return Internal_GetIncludeInBuild(mCachedPtr); } }
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern ImportOptions Internal_GetImportOptions(IntPtr thisPtr);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern ResourceMeta[] Internal_GetResourceMetas(IntPtr thisPtr);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern bool Internal_GetIncludeInBuild(IntPtr thisPtr);
}
///
/// Contains meta-data for a resource in the ProjectLibrary.
///
public class ResourceMeta : ScriptObject
{
///
/// Unique identifier of the resource.
///
public UUID UUID
{
get
{
UUID uuid;
Internal_GetUUID(mCachedPtr, out uuid);
return uuid;
}
}
///
/// Returns a name of the subresources. Each resource within a file has a unique name.
///
public string SubresourceName { get { return Internal_GetSubresourceName(mCachedPtr); } }
///
/// Custom icons for the resource to display in the editor, if the resource has them.
///
public ProjectResourceIcons Icons
{
get
{
ProjectResourceIcons output;
Internal_GetPreviewIcons(mCachedPtr, out output);
return output;
}
}
///
/// Type of the resource referenced by this entry.
///
public ResourceType ResType { get { return Internal_GetResourceType(mCachedPtr); } }
///
/// Type information of the resource referenced by this entry.
///
public Type Type { get { return Internal_GetType(mCachedPtr); } }
///
/// Non-specific data assigned to the resource, available in editor only.
///
public object EditorData { get { return Internal_GetEditorData(mCachedPtr); } }
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_GetUUID(IntPtr thisPtr, out UUID uuid);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string Internal_GetSubresourceName(IntPtr thisPtr);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_GetPreviewIcons(IntPtr thisPtr, out ProjectResourceIcons icons);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern ResourceType Internal_GetResourceType(IntPtr thisPtr);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern Type Internal_GetType(IntPtr thisPtr);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern object Internal_GetEditorData(IntPtr thisPtr);
}
/** @} */
}