Add support for virtual Prefab assets created from code
This commit is contained in:
@@ -230,7 +230,8 @@ void Asset::OnDeleteObject()
|
|||||||
Content::GetRegistry()->DeleteAsset(id, nullptr);
|
Content::GetRegistry()->DeleteAsset(id, nullptr);
|
||||||
|
|
||||||
// Delete file
|
// Delete file
|
||||||
Content::deleteFileSafety(path, id);
|
if (!IsVirtual())
|
||||||
|
Content::deleteFileSafety(path, id);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -288,8 +289,13 @@ void Asset::OnScriptingDispose()
|
|||||||
|
|
||||||
void Asset::ChangeID(const Guid& newId)
|
void Asset::ChangeID(const Guid& newId)
|
||||||
{
|
{
|
||||||
// Don't allow to change asset ids
|
// Only virtual asset can change ID
|
||||||
CRASH;
|
if (!IsVirtual())
|
||||||
|
CRASH;
|
||||||
|
|
||||||
|
const Guid oldId = _id;
|
||||||
|
ManagedScriptingObject::ChangeID(newId);
|
||||||
|
Content::onAssetChangeId(this, oldId, newId);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Asset::LastLoadFailed() const
|
bool Asset::LastLoadFailed() const
|
||||||
|
|||||||
@@ -460,12 +460,16 @@ Asset* Content::LoadAsync(const StringView& path, const ScriptingTypeHandle& typ
|
|||||||
Array<Asset*> Content::GetAssets()
|
Array<Asset*> Content::GetAssets()
|
||||||
{
|
{
|
||||||
Array<Asset*> assets;
|
Array<Asset*> assets;
|
||||||
|
AssetsLocker.Lock();
|
||||||
Assets.GetValues(assets);
|
Assets.GetValues(assets);
|
||||||
|
AssetsLocker.Unlock();
|
||||||
return assets;
|
return assets;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Dictionary<Guid, Asset*>& Content::GetAssetsRaw()
|
const Dictionary<Guid, Asset*>& Content::GetAssetsRaw()
|
||||||
{
|
{
|
||||||
|
AssetsLocker.Lock();
|
||||||
|
AssetsLocker.Unlock();
|
||||||
return Assets;
|
return Assets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -862,6 +866,13 @@ void Content::onAssetUnload(Asset* asset)
|
|||||||
LoadedAssetsToInvoke.Remove(asset);
|
LoadedAssetsToInvoke.Remove(asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Content::onAssetChangeId(Asset* asset, const Guid& oldId, const Guid& newId)
|
||||||
|
{
|
||||||
|
ScopeLock locker(AssetsLocker);
|
||||||
|
Assets.Remove(oldId);
|
||||||
|
Assets.Add(newId, asset);
|
||||||
|
}
|
||||||
|
|
||||||
bool Content::IsAssetTypeIdInvalid(const ScriptingTypeHandle& type, const ScriptingTypeHandle& assetType)
|
bool Content::IsAssetTypeIdInvalid(const ScriptingTypeHandle& type, const ScriptingTypeHandle& assetType)
|
||||||
{
|
{
|
||||||
// Skip if no restrictions for the type
|
// Skip if no restrictions for the type
|
||||||
|
|||||||
@@ -358,6 +358,7 @@ private:
|
|||||||
static void tryCallOnLoaded(Asset* asset);
|
static void tryCallOnLoaded(Asset* asset);
|
||||||
static void onAssetLoaded(Asset* asset);
|
static void onAssetLoaded(Asset* asset);
|
||||||
static void onAssetUnload(Asset* asset);
|
static void onAssetUnload(Asset* asset);
|
||||||
|
static void onAssetChangeId(Asset* asset, const Guid& oldId, const Guid& newId);
|
||||||
static Asset* load(const Guid& id, const ScriptingTypeHandle& type, AssetInfo& assetInfo);
|
static Asset* load(const Guid& id, const ScriptingTypeHandle& type, AssetInfo& assetInfo);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -45,6 +45,29 @@ String JsonAssetBase::GetData() const
|
|||||||
return String((const char*)buffer.GetString(), (int32)buffer.GetSize());
|
return String((const char*)buffer.GetString(), (int32)buffer.GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool JsonAssetBase::Init(const StringView& dataTypeName, const StringAnsiView& dataJson)
|
||||||
|
{
|
||||||
|
CHECK_RETURN(IsVirtual(), true);
|
||||||
|
unload(true);
|
||||||
|
DataTypeName = dataTypeName;
|
||||||
|
DataEngineBuild = FLAXENGINE_VERSION_BUILD;
|
||||||
|
|
||||||
|
// Parse json document
|
||||||
|
{
|
||||||
|
PROFILE_CPU_NAMED("Json.Parse");
|
||||||
|
Document.Parse(dataJson.Get(), dataJson.Length());
|
||||||
|
}
|
||||||
|
if (Document.HasParseError())
|
||||||
|
{
|
||||||
|
Log::JsonParseException(Document.GetParseError(), Document.GetErrorOffset());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Data = &Document;
|
||||||
|
|
||||||
|
// Load asset-specific data
|
||||||
|
return loadAsset() != LoadResult::Ok;
|
||||||
|
}
|
||||||
|
|
||||||
const String& JsonAssetBase::GetPath() const
|
const String& JsonAssetBase::GetPath() const
|
||||||
{
|
{
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
@@ -114,6 +137,9 @@ void JsonAssetBase::GetReferences(Array<Guid>& output) const
|
|||||||
|
|
||||||
Asset::LoadResult JsonAssetBase::loadAsset()
|
Asset::LoadResult JsonAssetBase::loadAsset()
|
||||||
{
|
{
|
||||||
|
if (IsVirtual())
|
||||||
|
return LoadResult::Ok;
|
||||||
|
|
||||||
// Load data (raw json file in editor, cooked asset in build game)
|
// Load data (raw json file in editor, cooked asset in build game)
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
BytesContainer data;
|
BytesContainer data;
|
||||||
|
|||||||
@@ -50,6 +50,15 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
API_PROPERTY() String GetData() const;
|
API_PROPERTY() String GetData() const;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the virtual Json asset with custom data.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Can be used only for virtual assets created at runtime.</remarks>
|
||||||
|
/// <param name="dataTypeName">The data type name from the header. Allows to recognize the data type.</param>
|
||||||
|
/// <param name="dataJson">The Json with serialized data.</param>
|
||||||
|
/// <returns>True if failed, otherwise false.</returns>
|
||||||
|
API_FUNCTION() bool Init(const StringView& dataTypeName, const StringAnsiView& dataJson);
|
||||||
|
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Parses Json string to find any object references inside it. It can produce list of references to assets and/or scene objects. Supported only in Editor.
|
/// Parses Json string to find any object references inside it. It can produce list of references to assets and/or scene objects. Supported only in Editor.
|
||||||
|
|||||||
@@ -661,10 +661,16 @@ bool Prefab::ApplyAll(Actor* targetActor)
|
|||||||
|
|
||||||
// Assign references to the prefabs
|
// Assign references to the prefabs
|
||||||
allPrefabs.EnsureCapacity(Math::RoundUpToPowerOf2(Math::Max(30, nestedPrefabIds.Count())));
|
allPrefabs.EnsureCapacity(Math::RoundUpToPowerOf2(Math::Max(30, nestedPrefabIds.Count())));
|
||||||
|
const Dictionary<Guid, Asset*, HeapAllocation>& assetsRaw = Content::GetAssetsRaw();
|
||||||
|
for (auto& e : assetsRaw)
|
||||||
|
{
|
||||||
|
if (e.Value->GetTypeHandle() == Prefab::TypeInitializer)
|
||||||
|
nestedPrefabIds.AddUnique(e.Key);
|
||||||
|
}
|
||||||
for (int32 i = 0; i < nestedPrefabIds.Count(); i++)
|
for (int32 i = 0; i < nestedPrefabIds.Count(); i++)
|
||||||
{
|
{
|
||||||
const auto nestedPrefab = Content::LoadAsync<Prefab>(nestedPrefabIds[i]);
|
const auto nestedPrefab = Content::LoadAsync<Prefab>(nestedPrefabIds[i]);
|
||||||
if (nestedPrefab && nestedPrefab != this)
|
if (nestedPrefab && nestedPrefab != this && (nestedPrefab->Flags & ObjectFlags::WasMarkedToDelete) == 0)
|
||||||
{
|
{
|
||||||
allPrefabs.Add(nestedPrefab);
|
allPrefabs.Add(nestedPrefab);
|
||||||
}
|
}
|
||||||
@@ -1079,6 +1085,10 @@ bool Prefab::UpdateInternal(const Array<SceneObject*>& defaultInstanceObjects, r
|
|||||||
LOG(Info, "Updating prefab data");
|
LOG(Info, "Updating prefab data");
|
||||||
|
|
||||||
// Reload prefab data
|
// Reload prefab data
|
||||||
|
if (IsVirtual())
|
||||||
|
{
|
||||||
|
return Init(TypeName, StringAnsiView(tmpBuffer.GetString(), (int32)tmpBuffer.GetSize()));
|
||||||
|
}
|
||||||
#if 1 // Set to 0 to use memory-only reload that does not modifies the source file - useful for testing and debugging prefabs apply
|
#if 1 // Set to 0 to use memory-only reload that does not modifies the source file - useful for testing and debugging prefabs apply
|
||||||
#if COMPILE_WITH_ASSETS_IMPORTER
|
#if COMPILE_WITH_ASSETS_IMPORTER
|
||||||
Locker.Unlock();
|
Locker.Unlock();
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
#include "Engine/Scripting/Scripting.h"
|
#include "Engine/Scripting/Scripting.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
REGISTER_JSON_ASSET(Prefab, "FlaxEngine.Prefab", false);
|
REGISTER_JSON_ASSET(Prefab, "FlaxEngine.Prefab", true);
|
||||||
|
|
||||||
Prefab::Prefab(const SpawnParams& params, const AssetInfo* info)
|
Prefab::Prefab(const SpawnParams& params, const AssetInfo* info)
|
||||||
: JsonAssetBase(params, info)
|
: JsonAssetBase(params, info)
|
||||||
|
|||||||
Reference in New Issue
Block a user