Add content deprecation system that auto-saves assets in Editor that use old data format
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include "FlaxEngine.Gen.h"
|
||||
#if USE_EDITOR
|
||||
#include "Engine/Level/Level.h"
|
||||
#include "Engine/Serialization/MemoryWriteStream.h"
|
||||
#endif
|
||||
|
||||
REGISTER_BINARY_ASSET(BehaviorTree, "FlaxEngine.BehaviorTree", false);
|
||||
@@ -164,7 +165,7 @@ BehaviorTreeNode* BehaviorTree::GetNodeInstance(uint32 id)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BytesContainer BehaviorTree::LoadSurface()
|
||||
BytesContainer BehaviorTree::LoadSurface() const
|
||||
{
|
||||
if (WaitForLoaded())
|
||||
return BytesContainer();
|
||||
@@ -182,19 +183,10 @@ BytesContainer BehaviorTree::LoadSurface()
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
bool BehaviorTree::SaveSurface(const BytesContainer& data)
|
||||
bool BehaviorTree::SaveSurface(const BytesContainer& data) const
|
||||
{
|
||||
// Wait for asset to be loaded or don't if last load failed
|
||||
if (LastLoadFailed())
|
||||
{
|
||||
LOG(Warning, "Saving asset that failed to load.");
|
||||
}
|
||||
else if (WaitForLoaded())
|
||||
{
|
||||
LOG(Error, "Asset loading failed. Cannot save it.");
|
||||
if (OnCheckSave())
|
||||
return true;
|
||||
}
|
||||
|
||||
ScopeLock lock(Locker);
|
||||
|
||||
// Set Visject Surface data
|
||||
@@ -250,6 +242,19 @@ void BehaviorTree::GetReferences(Array<Guid>& assets, Array<String>& files) cons
|
||||
}
|
||||
}
|
||||
|
||||
bool BehaviorTree::Save(const StringView& path)
|
||||
{
|
||||
if (OnCheckSave(path))
|
||||
return true;
|
||||
ScopeLock lock(Locker);
|
||||
MemoryWriteStream stream;
|
||||
if (Graph.Save(&stream, true))
|
||||
return true;
|
||||
BytesContainer data;
|
||||
data.Link(ToSpan(stream));
|
||||
return SaveSurface(data);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void BehaviorTree::OnScriptingDispose()
|
||||
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
/// Tries to load surface graph from the asset.
|
||||
/// </summary>
|
||||
/// <returns>The surface data or empty if failed to load it.</returns>
|
||||
API_FUNCTION() BytesContainer LoadSurface();
|
||||
API_FUNCTION() BytesContainer LoadSurface() const;
|
||||
|
||||
#if USE_EDITOR
|
||||
/// <summary>
|
||||
@@ -85,7 +85,7 @@ public:
|
||||
/// </summary>
|
||||
/// <param name="data">Stream with graph data.</param>
|
||||
/// <returns>True if cannot save it, otherwise false.</returns>
|
||||
API_FUNCTION() bool SaveSurface(const BytesContainer& data);
|
||||
API_FUNCTION() bool SaveSurface(const BytesContainer& data) const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
@@ -99,6 +99,7 @@ public:
|
||||
void OnScriptingDispose() override;
|
||||
#if USE_EDITOR
|
||||
void GetReferences(Array<Guid>& assets, Array<String>& files) const override;
|
||||
bool Save(const StringView& path = StringView::Empty) override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "Engine/Content/Factories/BinaryAssetFactory.h"
|
||||
#include "Engine/Content/Assets/MaterialBase.h"
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/Content/Deprecated.h"
|
||||
#include "Engine/Serialization/MemoryReadStream.h"
|
||||
#include "Engine/Audio/AudioClip.h"
|
||||
#include "Engine/Graphics/PostProcessSettings.h"
|
||||
@@ -35,19 +36,166 @@ const BytesContainer& SceneAnimation::LoadTimeline()
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
bool SceneAnimation::SaveTimeline(const BytesContainer& data)
|
||||
void SceneAnimation::SaveData(MemoryWriteStream& stream) const
|
||||
{
|
||||
// Wait for asset to be loaded or don't if last load failed (eg. by shader source compilation error)
|
||||
if (LastLoadFailed())
|
||||
{
|
||||
LOG(Warning, "Saving asset that failed to load.");
|
||||
}
|
||||
else if (WaitForLoaded())
|
||||
{
|
||||
LOG(Error, "Asset loading failed. Cannot save it.");
|
||||
return true;
|
||||
}
|
||||
// Save properties
|
||||
stream.Write(4);
|
||||
stream.Write(FramesPerSecond);
|
||||
stream.Write(DurationFrames);
|
||||
|
||||
// Save tracks
|
||||
stream.Write(Tracks.Count());
|
||||
for (const auto& track : Tracks)
|
||||
{
|
||||
stream.Write((byte)track.Type);
|
||||
stream.Write((byte)track.Flag);
|
||||
stream.Write((int32)track.ParentIndex);
|
||||
stream.Write((int32)track.ChildrenCount);
|
||||
stream.Write(track.Name, -13);
|
||||
stream.Write(track.Color);
|
||||
switch (track.Type)
|
||||
{
|
||||
case Track::Types::Folder:
|
||||
break;
|
||||
case Track::Types::PostProcessMaterial:
|
||||
{
|
||||
auto trackData = stream.Move<PostProcessMaterialTrack::Data>();
|
||||
trackData->AssetID = track.Asset.GetID();
|
||||
const auto trackRuntime = track.GetRuntimeData<PostProcessMaterialTrack::Runtime>();
|
||||
stream.Write((int32)trackRuntime->Count);
|
||||
stream.WriteBytes(trackRuntime->Media, sizeof(Media) * trackRuntime->Count);
|
||||
break;
|
||||
}
|
||||
case Track::Types::NestedSceneAnimation:
|
||||
{
|
||||
auto trackData = stream.Move<NestedSceneAnimationTrack::Data>();
|
||||
*trackData = *track.GetData<NestedSceneAnimationTrack::Data>();
|
||||
trackData->AssetID = track.Asset.GetID();
|
||||
break;
|
||||
}
|
||||
case Track::Types::ScreenFade:
|
||||
{
|
||||
auto trackData = stream.Move<ScreenFadeTrack::Data>();
|
||||
*trackData = *track.GetData<ScreenFadeTrack::Data>();
|
||||
const auto trackRuntime = track.GetRuntimeData<ScreenFadeTrack::Runtime>();
|
||||
stream.WriteBytes(trackRuntime->GradientStops, sizeof(ScreenFadeTrack::GradientStop) * trackData->GradientStopsCount);
|
||||
break;
|
||||
}
|
||||
case Track::Types::Audio:
|
||||
{
|
||||
auto trackData = stream.Move<AudioTrack::Data>();
|
||||
trackData->AssetID = track.Asset.GetID();
|
||||
const auto trackRuntime = track.GetRuntimeData<AudioTrack::Runtime>();
|
||||
stream.Write((int32)trackRuntime->Count);
|
||||
stream.WriteBytes(trackRuntime->Media, sizeof(AudioTrack::Media) * trackRuntime->Count);
|
||||
break;
|
||||
}
|
||||
case Track::Types::AudioVolume:
|
||||
{
|
||||
auto trackData = stream.Move<AudioVolumeTrack::Data>();
|
||||
*trackData = *track.GetData<AudioVolumeTrack::Data>();
|
||||
const auto trackRuntime = track.GetRuntimeData<AudioVolumeTrack::Runtime>();
|
||||
stream.WriteBytes(trackRuntime->Keyframes, sizeof(BezierCurveKeyframe<float>) * trackRuntime->KeyframesCount);
|
||||
break;
|
||||
}
|
||||
case Track::Types::Actor:
|
||||
{
|
||||
auto trackData = stream.Move<ActorTrack::Data>();
|
||||
*trackData = *track.GetData<ActorTrack::Data>();
|
||||
break;
|
||||
}
|
||||
case Track::Types::Script:
|
||||
{
|
||||
auto trackData = stream.Move<ScriptTrack::Data>();
|
||||
*trackData = *track.GetData<ScriptTrack::Data>();
|
||||
break;
|
||||
}
|
||||
case Track::Types::KeyframesProperty:
|
||||
case Track::Types::ObjectReferenceProperty:
|
||||
{
|
||||
auto trackData = stream.Move<KeyframesPropertyTrack::Data>();
|
||||
*trackData = *track.GetData<KeyframesPropertyTrack::Data>();
|
||||
const auto trackRuntime = track.GetRuntimeData<KeyframesPropertyTrack::Runtime>();
|
||||
stream.WriteBytes(trackRuntime->PropertyName, trackData->PropertyNameLength + 1);
|
||||
stream.WriteBytes(trackRuntime->PropertyTypeName, trackData->PropertyTypeNameLength + 1);
|
||||
stream.WriteBytes(trackRuntime->Keyframes, trackRuntime->KeyframesSize);
|
||||
break;
|
||||
}
|
||||
case Track::Types::CurveProperty:
|
||||
{
|
||||
auto trackData = stream.Move<CurvePropertyTrack::Data>();
|
||||
*trackData = *track.GetData<CurvePropertyTrack::Data>();
|
||||
const auto trackRuntime = track.GetRuntimeData<CurvePropertyTrack::Runtime>();
|
||||
stream.WriteBytes(trackRuntime->PropertyName, trackData->PropertyNameLength + 1);
|
||||
stream.WriteBytes(trackRuntime->PropertyTypeName, trackData->PropertyTypeNameLength + 1);
|
||||
const int32 keyframesDataSize = trackData->KeyframesCount * (sizeof(float) + trackData->ValueSize * 3);
|
||||
stream.WriteBytes(trackRuntime->Keyframes, keyframesDataSize);
|
||||
break;
|
||||
}
|
||||
case Track::Types::StringProperty:
|
||||
{
|
||||
const auto trackData = stream.Move<StringPropertyTrack::Data>();
|
||||
*trackData = *track.GetData<StringPropertyTrack::Data>();
|
||||
const auto trackRuntime = track.GetRuntimeData<StringPropertyTrack::Runtime>();
|
||||
stream.WriteBytes(trackRuntime->PropertyName, trackData->PropertyNameLength + 1);
|
||||
stream.WriteBytes(trackRuntime->PropertyTypeName, trackData->PropertyTypeNameLength + 1);
|
||||
const auto keyframesTimes = (float*)((byte*)trackRuntime + sizeof(StringPropertyTrack::Runtime));
|
||||
const auto keyframesLengths = (int32*)((byte*)keyframesTimes + sizeof(float) * trackRuntime->KeyframesCount);
|
||||
const auto keyframesValues = (Char**)((byte*)keyframesLengths + sizeof(int32) * trackRuntime->KeyframesCount);
|
||||
for (int32 j = 0; j < trackRuntime->KeyframesCount; j++)
|
||||
{
|
||||
stream.Write((float)keyframesTimes[j]);
|
||||
stream.Write((int32)keyframesLengths[j]);
|
||||
stream.WriteBytes(keyframesValues[j], keyframesLengths[j] * sizeof(Char));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Track::Types::StructProperty:
|
||||
case Track::Types::ObjectProperty:
|
||||
{
|
||||
auto trackData = stream.Move<StructPropertyTrack::Data>();
|
||||
*trackData = *track.GetData<StructPropertyTrack::Data>();
|
||||
const auto trackRuntime = track.GetRuntimeData<StructPropertyTrack::Runtime>();
|
||||
stream.WriteBytes(trackRuntime->PropertyName, trackData->PropertyNameLength + 1);
|
||||
stream.WriteBytes(trackRuntime->PropertyTypeName, trackData->PropertyTypeNameLength + 1);
|
||||
break;
|
||||
}
|
||||
case Track::Types::Event:
|
||||
{
|
||||
const auto trackRuntime = track.GetRuntimeData<EventTrack::Runtime>();
|
||||
int32 tmp = StringUtils::Length(trackRuntime->EventName);
|
||||
stream.Write((int32)trackRuntime->EventParamsCount);
|
||||
stream.Write((int32)trackRuntime->EventsCount);
|
||||
stream.Write((int32)tmp);
|
||||
stream.WriteBytes(trackRuntime->EventName, tmp + 1);
|
||||
for (int j = 0; j < trackRuntime->EventParamsCount; j++)
|
||||
{
|
||||
stream.Write((int32)trackRuntime->EventParamSizes[j]);
|
||||
stream.Write((int32)tmp);
|
||||
stream.WriteBytes(trackRuntime->EventParamTypes[j], tmp + 1);
|
||||
}
|
||||
stream.WriteBytes(trackRuntime->DataBegin, trackRuntime->EventsCount * (sizeof(float) + trackRuntime->EventParamsSize));
|
||||
break;
|
||||
}
|
||||
case Track::Types::CameraCut:
|
||||
{
|
||||
auto trackData = stream.Move<CameraCutTrack::Data>();
|
||||
*trackData = *track.GetData<CameraCutTrack::Data>();
|
||||
const auto trackRuntime = track.GetRuntimeData<CameraCutTrack::Runtime>();
|
||||
stream.Write((int32)trackRuntime->Count);
|
||||
stream.WriteBytes(trackRuntime->Media, sizeof(Media) * trackRuntime->Count);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SceneAnimation::SaveTimeline(const BytesContainer& data) const
|
||||
{
|
||||
if (OnCheckSave())
|
||||
return true;
|
||||
ScopeLock lock(Locker);
|
||||
|
||||
// Release all chunks
|
||||
@@ -71,10 +219,6 @@ bool SceneAnimation::SaveTimeline(const BytesContainer& data)
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
void SceneAnimation::GetReferences(Array<Guid>& assets, Array<String>& files) const
|
||||
{
|
||||
// Base
|
||||
@@ -88,6 +232,18 @@ void SceneAnimation::GetReferences(Array<Guid>& assets, Array<String>& files) co
|
||||
}
|
||||
}
|
||||
|
||||
bool SceneAnimation::Save(const StringView& path)
|
||||
{
|
||||
if (OnCheckSave(path))
|
||||
return true;
|
||||
ScopeLock lock(Locker);
|
||||
MemoryWriteStream stream;
|
||||
SaveData(stream);
|
||||
BytesContainer data;
|
||||
data.Link(ToSpan(stream));
|
||||
return SaveTimeline(data);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Asset::LoadResult SceneAnimation::load()
|
||||
@@ -117,6 +273,7 @@ Asset::LoadResult SceneAnimation::load()
|
||||
{
|
||||
case 2: // [Deprecated in 2020 expires on 03.09.2023]
|
||||
case 3: // [Deprecated on 03.09.2021 expires on 03.09.2023]
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
case 4:
|
||||
{
|
||||
stream.Read(FramesPerSecond);
|
||||
|
||||
@@ -415,6 +415,10 @@ private:
|
||||
BytesContainer _data;
|
||||
MemoryWriteStream _runtimeData;
|
||||
|
||||
#if USE_EDITOR
|
||||
void SaveData(MemoryWriteStream& stream) const;
|
||||
#endif
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// The frames amount per second of the timeline animation.
|
||||
@@ -457,7 +461,7 @@ public:
|
||||
/// <remarks>It cannot be used by virtual assets.</remarks>
|
||||
/// <param name="data">The timeline data container.</param>
|
||||
/// <returns><c>true</c> failed to save data; otherwise, <c>false</c>.</returns>
|
||||
API_FUNCTION() bool SaveTimeline(const BytesContainer& data);
|
||||
API_FUNCTION() bool SaveTimeline(const BytesContainer& data) const;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -465,6 +469,7 @@ public:
|
||||
// [BinaryAsset]
|
||||
#if USE_EDITOR
|
||||
void GetReferences(Array<Guid>& assets, Array<String>& files) const override;
|
||||
bool Save(const StringView& path = StringView::Empty) override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "Asset.h"
|
||||
#include "Content.h"
|
||||
#include "Deprecated.h"
|
||||
#include "SoftAssetReference.h"
|
||||
#include "Cache/AssetsCache.h"
|
||||
#include "Loading/Tasks/LoadAssetTask.h"
|
||||
@@ -10,6 +11,26 @@
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#include "Engine/Scripting/ManagedCLR/MCore.h"
|
||||
#include "Engine/Threading/MainThreadTask.h"
|
||||
#include "Engine/Threading/ThreadLocal.h"
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
ThreadLocal<bool> ContentDeprecatedFlags;
|
||||
|
||||
void ContentDeprecated::Mark()
|
||||
{
|
||||
ContentDeprecatedFlags.Set(true);
|
||||
}
|
||||
|
||||
bool ContentDeprecated::Clear(bool newValue)
|
||||
{
|
||||
auto& flag = ContentDeprecatedFlags.Get();
|
||||
bool result = flag;
|
||||
flag = newValue;
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
AssetReferenceBase::~AssetReferenceBase()
|
||||
{
|
||||
@@ -340,6 +361,7 @@ void Asset::Reload()
|
||||
// Virtual assets are memory-only so reloading them makes no sense
|
||||
if (IsVirtual())
|
||||
return;
|
||||
PROFILE_CPU_NAMED("Asset.Reload");
|
||||
|
||||
// It's better to call it from the main thread
|
||||
if (IsInMainThread())
|
||||
@@ -476,6 +498,12 @@ Array<Guid> Asset::GetReferences() const
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Asset::Save(const StringView& path)
|
||||
{
|
||||
LOG(Warning, "Asset type '{}' does not support saving.", GetTypeName());
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void Asset::DeleteManaged()
|
||||
@@ -524,12 +552,21 @@ bool Asset::onLoad(LoadAssetTask* task)
|
||||
|
||||
// Load asset
|
||||
LoadResult result;
|
||||
#if USE_EDITOR
|
||||
auto& deprecatedFlag = ContentDeprecatedFlags.Get();
|
||||
bool prevDeprecated = deprecatedFlag;
|
||||
deprecatedFlag = false;
|
||||
#endif
|
||||
{
|
||||
PROFILE_CPU_ASSET(this);
|
||||
result = loadAsset();
|
||||
}
|
||||
const bool isLoaded = result == LoadResult::Ok;
|
||||
const bool failed = !isLoaded;
|
||||
#if USE_EDITOR
|
||||
const bool isDeprecated = deprecatedFlag;
|
||||
deprecatedFlag = prevDeprecated;
|
||||
#endif
|
||||
Platform::AtomicStore(&_loadState, (int64)(isLoaded ? LoadState::Loaded : LoadState::LoadFailed));
|
||||
if (failed)
|
||||
{
|
||||
@@ -550,6 +587,19 @@ bool Asset::onLoad(LoadAssetTask* task)
|
||||
// This allows to reduce mutexes and locks (max one frame delay isn't hurting but provides more safety)
|
||||
Content::onAssetLoaded(this);
|
||||
}
|
||||
|
||||
#if USE_EDITOR
|
||||
// Auto-save deprecated assets to get rid of data in an old format
|
||||
if (isDeprecated && isLoaded)
|
||||
{
|
||||
PROFILE_CPU_NAMED("Asset.Save");
|
||||
LOG(Info, "Resaving asset '{}' that uses deprecated data format", ToString());
|
||||
if (Save())
|
||||
{
|
||||
LOG(Error, "Failed to resave asset '{}'", ToString());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return failed;
|
||||
}
|
||||
@@ -595,3 +645,26 @@ void Asset::onUnload_MainThread()
|
||||
loadingTask->Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
bool Asset::OnCheckSave(const StringView& path) const
|
||||
{
|
||||
if (LastLoadFailed())
|
||||
{
|
||||
LOG(Warning, "Saving asset that failed to load.");
|
||||
}
|
||||
if (WaitForLoaded())
|
||||
{
|
||||
LOG(Error, "Asset loading failed. Cannot save it.");
|
||||
return true;
|
||||
}
|
||||
if (IsVirtual() && path.IsEmpty())
|
||||
{
|
||||
LOG(Error, "To save virtual asset asset you need to specify the target asset path location.");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -75,7 +75,7 @@ public:
|
||||
EventType OnUnloaded;
|
||||
|
||||
/// <summary>
|
||||
/// General purpose mutex for an asset object. Should guard most of asset functionalities to be secure.
|
||||
/// General purpose mutex for an asset object. Should guard most of the asset functionalities to be secure.
|
||||
/// </summary>
|
||||
CriticalSection Locker;
|
||||
|
||||
@@ -209,6 +209,13 @@ public:
|
||||
/// </remarks>
|
||||
/// <returns>The collection of the asset ids referenced by this asset.</returns>
|
||||
API_FUNCTION() Array<Guid, HeapAllocation> GetReferences() const;
|
||||
|
||||
/// <summary>
|
||||
/// Saves this asset to the file. Supported only in Editor.
|
||||
/// </summary>
|
||||
/// <param name="path">The custom asset path to use for the saving. Use empty value to save this asset to its own storage location. Can be used to duplicate asset. Must be specified when saving virtual asset.</param>
|
||||
/// <returns>True when cannot save data, otherwise false.</returns>
|
||||
API_FUNCTION(Sealed) virtual bool Save(const StringView& path = StringView::Empty);
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
@@ -253,6 +260,7 @@ protected:
|
||||
virtual void onLoaded_MainThread();
|
||||
virtual void onUnload_MainThread();
|
||||
#if USE_EDITOR
|
||||
bool OnCheckSave(const StringView& path = StringView::Empty) const;
|
||||
virtual void onRename(const StringView& newPath) = 0;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -226,16 +226,8 @@ void Animation::LoadTimeline(BytesContainer& result) const
|
||||
|
||||
bool Animation::SaveTimeline(BytesContainer& data)
|
||||
{
|
||||
// Wait for asset to be loaded or don't if last load failed (eg. by shader source compilation error)
|
||||
if (LastLoadFailed())
|
||||
{
|
||||
LOG(Warning, "Saving asset that failed to load.");
|
||||
}
|
||||
else if (WaitForLoaded())
|
||||
{
|
||||
LOG(Error, "Asset loading failed. Cannot save it.");
|
||||
if (OnCheckSave())
|
||||
return true;
|
||||
}
|
||||
ScopeLock lock(Locker);
|
||||
MemoryReadStream stream(data.Get(), data.Length());
|
||||
|
||||
@@ -401,17 +393,8 @@ bool Animation::SaveTimeline(BytesContainer& data)
|
||||
|
||||
bool Animation::Save(const StringView& path)
|
||||
{
|
||||
// Wait for asset to be loaded or don't if last load failed (eg. by shader source compilation error)
|
||||
if (LastLoadFailed())
|
||||
{
|
||||
LOG(Warning, "Saving asset that failed to load.");
|
||||
}
|
||||
else if (WaitForLoaded())
|
||||
{
|
||||
LOG(Error, "Asset loading failed. Cannot save it.");
|
||||
if (OnCheckSave(path))
|
||||
return true;
|
||||
}
|
||||
|
||||
ScopeLock lock(Locker);
|
||||
|
||||
// Serialize animation data to the stream
|
||||
|
||||
@@ -138,17 +138,10 @@ public:
|
||||
/// <summary>
|
||||
/// Saves the serialized timeline data to the asset as animation.
|
||||
/// </summary>
|
||||
/// <remarks>The cannot be used by virtual assets.</remarks>
|
||||
/// <remarks>This cannot be used by virtual assets.</remarks>
|
||||
/// <param name="data">The timeline data container.</param>
|
||||
/// <returns><c>true</c> failed to save data; otherwise, <c>false</c>.</returns>
|
||||
API_FUNCTION() bool SaveTimeline(BytesContainer& data);
|
||||
|
||||
/// <summary>
|
||||
/// Saves the animation data to the asset. Supported only in Editor.
|
||||
/// </summary>
|
||||
/// <remarks>The cannot be used by virtual assets.</remarks>
|
||||
/// <returns><c>true</c> failed to save data; otherwise, <c>false</c>.</returns>
|
||||
bool Save(const StringView& path = StringView::Empty);
|
||||
#endif
|
||||
|
||||
private:
|
||||
@@ -161,6 +154,7 @@ public:
|
||||
// [BinaryAsset]
|
||||
#if USE_EDITOR
|
||||
void GetReferences(Array<Guid>& assets, Array<String>& files) const override;
|
||||
bool Save(const StringView& path = StringView::Empty) override;
|
||||
#endif
|
||||
uint64 GetMemoryUsage() const override;
|
||||
void OnScriptingDispose() override;
|
||||
|
||||
@@ -127,7 +127,7 @@ bool AnimationGraph::InitAsAnimation(SkinnedModel* baseModel, Animation* anim, b
|
||||
return Graph.Load(&readStream, USE_EDITOR);
|
||||
}
|
||||
|
||||
BytesContainer AnimationGraph::LoadSurface()
|
||||
BytesContainer AnimationGraph::LoadSurface() const
|
||||
{
|
||||
if (!IsVirtual() && WaitForLoaded())
|
||||
return BytesContainer();
|
||||
@@ -160,19 +160,10 @@ BytesContainer AnimationGraph::LoadSurface()
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
bool AnimationGraph::SaveSurface(BytesContainer& data)
|
||||
bool AnimationGraph::SaveSurface(const BytesContainer& data)
|
||||
{
|
||||
// Wait for asset to be loaded or don't if last load failed
|
||||
if (LastLoadFailed())
|
||||
{
|
||||
LOG(Warning, "Saving asset that failed to load.");
|
||||
}
|
||||
else if (WaitForLoaded())
|
||||
{
|
||||
LOG(Error, "Asset loading failed. Cannot save it.");
|
||||
if (OnCheckSave())
|
||||
return true;
|
||||
}
|
||||
|
||||
ScopeLock lock(Locker);
|
||||
|
||||
if (IsVirtual())
|
||||
@@ -228,4 +219,17 @@ void AnimationGraph::GetReferences(Array<Guid>& assets, Array<String>& files) co
|
||||
Graph.GetReferences(assets);
|
||||
}
|
||||
|
||||
bool AnimationGraph::Save(const StringView& path)
|
||||
{
|
||||
if (OnCheckSave(path))
|
||||
return true;
|
||||
ScopeLock lock(Locker);
|
||||
MemoryWriteStream writeStream;
|
||||
if (Graph.Save(&writeStream, true))
|
||||
return true;
|
||||
BytesContainer data;
|
||||
data.Link(ToSpan(writeStream));
|
||||
return SaveSurface(data);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
/// Tries to load surface graph from the asset.
|
||||
/// </summary>
|
||||
/// <returns>The surface data or empty if failed to load it.</returns>
|
||||
API_FUNCTION() BytesContainer LoadSurface();
|
||||
API_FUNCTION() BytesContainer LoadSurface() const;
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
/// </summary>
|
||||
/// <param name="data">Stream with graph data.</param>
|
||||
/// <returns>True if cannot save it, otherwise false.</returns>
|
||||
API_FUNCTION() bool SaveSurface(BytesContainer& data);
|
||||
API_FUNCTION() bool SaveSurface(const BytesContainer& data);
|
||||
|
||||
private:
|
||||
void FindDependencies(AnimGraphBase* graph);
|
||||
@@ -65,6 +65,7 @@ public:
|
||||
// [BinaryAsset]
|
||||
#if USE_EDITOR
|
||||
void GetReferences(Array<Guid>& assets, Array<String>& files) const override;
|
||||
bool Save(const StringView& path = StringView::Empty) override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Types/DataContainer.h"
|
||||
#include "Engine/Serialization/MemoryReadStream.h"
|
||||
#if USE_EDITOR
|
||||
#include "Engine/Serialization/MemoryWriteStream.h"
|
||||
#endif
|
||||
#include "Engine/Content/Factories/BinaryAssetFactory.h"
|
||||
#include "Engine/Threading/Threading.h"
|
||||
|
||||
@@ -84,19 +87,10 @@ void AnimationGraphFunction::GetSignature(Array<StringView, FixedAllocation<32>>
|
||||
}
|
||||
}
|
||||
|
||||
bool AnimationGraphFunction::SaveSurface(const BytesContainer& data)
|
||||
bool AnimationGraphFunction::SaveSurface(const BytesContainer& data) const
|
||||
{
|
||||
// Wait for asset to be loaded or don't if last load failed
|
||||
if (LastLoadFailed())
|
||||
{
|
||||
LOG(Warning, "Saving asset that failed to load.");
|
||||
}
|
||||
else if (WaitForLoaded())
|
||||
{
|
||||
LOG(Error, "Asset loading failed. Cannot save it.");
|
||||
if (OnCheckSave())
|
||||
return true;
|
||||
}
|
||||
|
||||
ScopeLock lock(Locker);
|
||||
|
||||
// Set Visject Surface data
|
||||
@@ -185,3 +179,24 @@ void AnimationGraphFunction::ProcessGraphForSignature(AnimGraphBase* graph, bool
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
bool AnimationGraphFunction::Save(const StringView& path)
|
||||
{
|
||||
if (OnCheckSave(path))
|
||||
return true;
|
||||
ScopeLock lock(Locker);
|
||||
AnimGraph graph(const_cast<AnimationGraphFunction*>(this), true);
|
||||
MemoryReadStream readStream(GraphData.Get(), GraphData.Length());
|
||||
if (graph.Load(&readStream, true))
|
||||
return true;
|
||||
MemoryWriteStream writeStream;
|
||||
if (graph.Save(&writeStream, true))
|
||||
return true;
|
||||
BytesContainer data;
|
||||
data.Link(ToSpan(writeStream));
|
||||
return SaveSurface(data);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -53,13 +53,19 @@ public:
|
||||
/// </summary>
|
||||
/// <param name="data">The surface graph data.</param>
|
||||
/// <returns>True if cannot save it, otherwise false.</returns>
|
||||
API_FUNCTION() bool SaveSurface(const BytesContainer& data);
|
||||
API_FUNCTION() bool SaveSurface(const BytesContainer& data) const;
|
||||
|
||||
#endif
|
||||
|
||||
private:
|
||||
void ProcessGraphForSignature(AnimGraphBase* graph, bool canUseOutputs);
|
||||
|
||||
public:
|
||||
// [BinaryAsset]
|
||||
#if USE_EDITOR
|
||||
bool Save(const StringView& path = StringView::Empty) override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
// [BinaryAsset]
|
||||
LoadResult load() override;
|
||||
|
||||
@@ -191,12 +191,13 @@ Asset::LoadResult Material::load()
|
||||
auto lock = Storage->Lock();
|
||||
|
||||
// Prepare
|
||||
const String name = ToString();
|
||||
MaterialGenerator generator;
|
||||
generator.Error.Bind(&OnGeneratorError);
|
||||
if (_shaderHeader.Material.GraphVersion != MATERIAL_GRAPH_VERSION)
|
||||
LOG(Info, "Converting material \'{0}\', from version {1} to {2}...", ToString(), _shaderHeader.Material.GraphVersion, MATERIAL_GRAPH_VERSION);
|
||||
LOG(Info, "Converting material \'{0}\', from version {1} to {2}...", name, _shaderHeader.Material.GraphVersion, MATERIAL_GRAPH_VERSION);
|
||||
else
|
||||
LOG(Info, "Updating material \'{0}\'...", ToString());
|
||||
LOG(Info, "Updating material \'{0}\'...", name);
|
||||
|
||||
// Load or create material surface
|
||||
MaterialLayer* layer;
|
||||
@@ -205,7 +206,7 @@ Asset::LoadResult Material::load()
|
||||
// Load graph
|
||||
if (LoadChunks(GET_CHUNK_FLAG(SHADER_FILE_CHUNK_VISJECT_SURFACE)))
|
||||
{
|
||||
LOG(Warning, "Cannot load \'{0}\' data from chunk {1}.", ToString(), SHADER_FILE_CHUNK_VISJECT_SURFACE);
|
||||
LOG(Warning, "Cannot load \'{0}\' data from chunk {1}.", name, SHADER_FILE_CHUNK_VISJECT_SURFACE);
|
||||
return LoadResult::Failed;
|
||||
}
|
||||
|
||||
@@ -214,7 +215,19 @@ Asset::LoadResult Material::load()
|
||||
MemoryReadStream stream(surfaceChunk->Get(), surfaceChunk->Size());
|
||||
|
||||
// Load layer
|
||||
layer = MaterialLayer::Load(GetID(), &stream, _shaderHeader.Material.Info, ToString());
|
||||
layer = MaterialLayer::Load(GetID(), &stream, _shaderHeader.Material.Info, name);
|
||||
if (ContentDeprecated::Clear())
|
||||
{
|
||||
// If encountered any deprecated data when loading graph then serialize it
|
||||
MaterialGraph graph;
|
||||
MemoryWriteStream writeStream(1024);
|
||||
stream.SetPosition(0);
|
||||
if (!graph.Load(&stream, true) && !graph.Save(&writeStream, true))
|
||||
{
|
||||
surfaceChunk->Data.Copy(ToSpan(writeStream));
|
||||
ContentDeprecated::Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -245,7 +258,7 @@ Asset::LoadResult Material::load()
|
||||
MaterialInfo info = _shaderHeader.Material.Info;
|
||||
if (generator.Generate(source, info, materialParamsChunk->Data))
|
||||
{
|
||||
LOG(Error, "Cannot generate material source code for \'{0}\'. Please see log for more info.", ToString());
|
||||
LOG(Error, "Cannot generate material source code for \'{0}\'. Please see log for more info.", name);
|
||||
return LoadResult::Failed;
|
||||
}
|
||||
|
||||
@@ -282,9 +295,9 @@ Asset::LoadResult Material::load()
|
||||
|
||||
// Save to file
|
||||
#if USE_EDITOR
|
||||
if (Save())
|
||||
if (SaveShaderAsset())
|
||||
{
|
||||
LOG(Error, "Cannot save \'{0}\'", ToString());
|
||||
LOG(Error, "Cannot save \'{0}\'", name);
|
||||
return LoadResult::Failed;
|
||||
}
|
||||
#endif
|
||||
@@ -505,6 +518,25 @@ void Material::InitCompilationOptions(ShaderCompilationOptions& options)
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Material::Save(const StringView& path)
|
||||
{
|
||||
if (OnCheckSave(path))
|
||||
return true;
|
||||
ScopeLock lock(Locker);
|
||||
BytesContainer existingData = LoadSurface(true);
|
||||
if (existingData.IsInvalid())
|
||||
return true;
|
||||
MaterialGraph graph;
|
||||
MemoryWriteStream writeStream(existingData.Length());
|
||||
MemoryReadStream readStream(existingData);
|
||||
if (graph.Load(&readStream, true) || graph.Save(&writeStream, true))
|
||||
return true;
|
||||
BytesContainer data;
|
||||
data.Link(ToSpan(writeStream));
|
||||
auto materialInfo = _shaderHeader.Material.Info;
|
||||
return SaveSurface(data, materialInfo);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
BytesContainer Material::LoadSurface(bool createDefaultIfMissing)
|
||||
@@ -555,17 +587,8 @@ BytesContainer Material::LoadSurface(bool createDefaultIfMissing)
|
||||
|
||||
bool Material::SaveSurface(const BytesContainer& data, const MaterialInfo& info)
|
||||
{
|
||||
// Wait for asset to be loaded or don't if last load failed (eg. by shader source compilation error)
|
||||
if (LastLoadFailed())
|
||||
{
|
||||
LOG(Warning, "Saving asset that failed to load.");
|
||||
}
|
||||
else if (WaitForLoaded())
|
||||
{
|
||||
LOG(Error, "Asset loading failed. Cannot save it.");
|
||||
if (OnCheckSave())
|
||||
return true;
|
||||
}
|
||||
|
||||
ScopeLock lock(Locker);
|
||||
|
||||
// Release all chunks
|
||||
@@ -582,7 +605,7 @@ bool Material::SaveSurface(const BytesContainer& data, const MaterialInfo& info)
|
||||
ASSERT(visjectSurfaceChunk != nullptr);
|
||||
visjectSurfaceChunk->Data.Copy(data);
|
||||
|
||||
if (Save())
|
||||
if (SaveShaderAsset())
|
||||
{
|
||||
LOG(Error, "Cannot save \'{0}\'", ToString());
|
||||
return true;
|
||||
|
||||
@@ -13,6 +13,7 @@ class MaterialShader;
|
||||
API_CLASS(NoSpawn) class FLAXENGINE_API Material : public ShaderAssetTypeBase<MaterialBase>
|
||||
{
|
||||
DECLARE_BINARY_ASSET_HEADER(Material, ShadersSerializedVersion);
|
||||
|
||||
private:
|
||||
MaterialShader* _materialShader = nullptr;
|
||||
|
||||
@@ -25,7 +26,6 @@ public:
|
||||
API_FUNCTION() BytesContainer LoadSurface(bool createDefaultIfMissing);
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
/// <summary>
|
||||
/// Updates the material surface (save new one, discard cached data, reload asset).
|
||||
/// </summary>
|
||||
@@ -33,7 +33,6 @@ public:
|
||||
/// <param name="info">The material info structure.</param>
|
||||
/// <returns>True if cannot save it, otherwise false.</returns>
|
||||
API_FUNCTION() bool SaveSurface(const BytesContainer& data, const MaterialInfo& info);
|
||||
|
||||
#endif
|
||||
|
||||
public:
|
||||
@@ -52,6 +51,7 @@ public:
|
||||
// [ShaderAssetBase]
|
||||
#if USE_EDITOR
|
||||
void InitCompilationOptions(ShaderCompilationOptions& options) override;
|
||||
bool Save(const StringView& path = StringView::Empty) override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Types/DataContainer.h"
|
||||
#include "Engine/Serialization/MemoryReadStream.h"
|
||||
#include "Engine/Serialization/MemoryWriteStream.h"
|
||||
#endif
|
||||
#include "Engine/Content/Factories/BinaryAssetFactory.h"
|
||||
|
||||
@@ -24,7 +25,7 @@ Asset::LoadResult MaterialFunction::load()
|
||||
if (!surfaceChunk || !surfaceChunk->IsLoaded())
|
||||
return LoadResult::MissingDataChunk;
|
||||
MemoryReadStream stream(surfaceChunk->Get(), surfaceChunk->Size());
|
||||
if (Graph.Load(&stream, false))
|
||||
if (Graph.Load(&stream, USE_EDITOR))
|
||||
return LoadResult::Failed;
|
||||
|
||||
// Cache input and output nodes
|
||||
@@ -89,7 +90,7 @@ BytesContainer MaterialFunction::LoadSurface()
|
||||
return result;
|
||||
}
|
||||
|
||||
bool MaterialFunction::LoadSurface(MaterialGraph& graph)
|
||||
bool MaterialFunction::LoadSurface(MaterialGraph& graph, bool loadMeta)
|
||||
{
|
||||
if (WaitForLoaded())
|
||||
return true;
|
||||
@@ -100,7 +101,7 @@ bool MaterialFunction::LoadSurface(MaterialGraph& graph)
|
||||
{
|
||||
const auto surfaceChunk = GetChunk(0);
|
||||
MemoryReadStream stream(surfaceChunk->Get(), surfaceChunk->Size());
|
||||
return graph.Load(&stream, false);
|
||||
return graph.Load(&stream, loadMeta);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -128,19 +129,10 @@ void MaterialFunction::GetSignature(Array<StringView, FixedAllocation<32>>& type
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
bool MaterialFunction::SaveSurface(BytesContainer& data)
|
||||
bool MaterialFunction::SaveSurface(const BytesContainer& data) const
|
||||
{
|
||||
// Wait for asset to be loaded or don't if last load failed
|
||||
if (LastLoadFailed())
|
||||
{
|
||||
LOG(Warning, "Saving asset that failed to load.");
|
||||
}
|
||||
else if (WaitForLoaded())
|
||||
{
|
||||
LOG(Error, "Asset loading failed. Cannot save it.");
|
||||
if (OnCheckSave())
|
||||
return true;
|
||||
}
|
||||
|
||||
ScopeLock lock(Locker);
|
||||
|
||||
// Set Visject Surface data
|
||||
@@ -160,4 +152,17 @@ bool MaterialFunction::SaveSurface(BytesContainer& data)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MaterialFunction::Save(const StringView& path)
|
||||
{
|
||||
if (OnCheckSave(path))
|
||||
return true;
|
||||
ScopeLock lock(Locker);
|
||||
MemoryWriteStream writeStream;
|
||||
if (Graph.Save(&writeStream, true))
|
||||
return true;
|
||||
BytesContainer data;
|
||||
data.Link(ToSpan(writeStream));
|
||||
return SaveSurface(data);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
API_CLASS(NoSpawn) class FLAXENGINE_API MaterialFunction : public BinaryAsset
|
||||
{
|
||||
DECLARE_BINARY_ASSET_HEADER(MaterialFunction, 1);
|
||||
|
||||
public:
|
||||
#if COMPILE_WITH_MATERIAL_GRAPH
|
||||
|
||||
/// <summary>
|
||||
/// The loaded material function graph.
|
||||
/// </summary>
|
||||
@@ -39,8 +39,9 @@ public:
|
||||
/// Tries to load surface graph from the asset.
|
||||
/// </summary>
|
||||
/// <param name="graph">The graph to load.</param>
|
||||
/// <param name="loadMeta">True if load metadata.</param>
|
||||
/// <returns>True if failed, otherwise false.</returns>
|
||||
bool LoadSurface(MaterialGraph& graph);
|
||||
bool LoadSurface(MaterialGraph& graph, bool loadMeta = false);
|
||||
|
||||
// Gets the function signature for Visject Surface editor.
|
||||
API_FUNCTION() void GetSignature(API_PARAM(Out) Array<StringView, FixedAllocation<32>>& types, API_PARAM(Out) Array<StringView, FixedAllocation<32>>& names);
|
||||
@@ -48,14 +49,18 @@ public:
|
||||
#endif
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
/// <summary>
|
||||
/// Updates the material graph surface (save new one, discards cached data, reloads asset).
|
||||
/// </summary>
|
||||
/// <param name="data">The surface graph data.</param>
|
||||
/// <returns>True if cannot save it, otherwise false.</returns>
|
||||
API_FUNCTION() bool SaveSurface(BytesContainer& data);
|
||||
API_FUNCTION() bool SaveSurface(const BytesContainer& data) const;
|
||||
#endif
|
||||
|
||||
public:
|
||||
// [BinaryAsset]
|
||||
#if USE_EDITOR
|
||||
bool Save(const StringView& path = StringView::Empty) override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
@@ -310,18 +310,8 @@ void MaterialInstance::ResetParameters()
|
||||
|
||||
bool MaterialInstance::Save(const StringView& path)
|
||||
{
|
||||
// Validate state
|
||||
if (WaitForLoaded())
|
||||
{
|
||||
LOG(Error, "Asset loading failed. Cannot save it.");
|
||||
if (OnCheckSave(path))
|
||||
return true;
|
||||
}
|
||||
if (IsVirtual() && path.IsEmpty())
|
||||
{
|
||||
LOG(Error, "To save virtual asset asset you need to specify the target asset path location.");
|
||||
return true;
|
||||
}
|
||||
|
||||
ScopeLock lock(Locker);
|
||||
|
||||
// Save instance data
|
||||
|
||||
@@ -33,18 +33,6 @@ public:
|
||||
/// </summary>
|
||||
API_FUNCTION() void ResetParameters();
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
/// <summary>
|
||||
/// Saves this asset to the file. Supported only in Editor.
|
||||
/// </summary>
|
||||
/// <remarks>If you use saving with the GPU mesh data then the call has to be provided from the thread other than the main game thread.</remarks>
|
||||
/// <param name="path">The custom asset path to use for the saving. Use empty value to save this asset to its own storage location. Can be used to duplicate asset. Must be specified when saving virtual asset.</param>
|
||||
/// <returns>True if cannot save data, otherwise false.</returns>
|
||||
API_FUNCTION() bool Save(const StringView& path = StringView::Empty);
|
||||
|
||||
#endif
|
||||
|
||||
private:
|
||||
void OnBaseSet();
|
||||
void OnBaseUnset();
|
||||
@@ -56,6 +44,7 @@ public:
|
||||
bool IsMaterialInstance() const override;
|
||||
#if USE_EDITOR
|
||||
void GetReferences(Array<Guid>& assets, Array<String>& files) const override;
|
||||
bool Save(const StringView& path = StringView::Empty) override;
|
||||
#endif
|
||||
|
||||
// [IMaterial]
|
||||
|
||||
@@ -400,7 +400,7 @@ bool Model::LoadHeader(ReadStream& stream, byte& headerVersion)
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
bool Model::SaveHeader(WriteStream& stream)
|
||||
bool Model::SaveHeader(WriteStream& stream) const
|
||||
{
|
||||
if (ModelBase::SaveHeader(stream))
|
||||
return true;
|
||||
@@ -457,7 +457,7 @@ bool Model::SaveHeader(WriteStream& stream, const ModelData& modelData)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Model::Save(bool withMeshDataFromGpu, Function<FlaxChunk*(int32)>& getChunk)
|
||||
bool Model::Save(bool withMeshDataFromGpu, Function<FlaxChunk*(int32)>& getChunk) const
|
||||
{
|
||||
if (ModelBase::Save(withMeshDataFromGpu, getChunk))
|
||||
return true;
|
||||
|
||||
@@ -271,9 +271,9 @@ private:
|
||||
bool LoadHeader(ReadStream& stream, byte& headerVersion);
|
||||
#if USE_EDITOR
|
||||
friend class ImportModel;
|
||||
bool SaveHeader(WriteStream& stream) override;
|
||||
bool SaveHeader(WriteStream& stream) const override;
|
||||
static bool SaveHeader(WriteStream& stream, const ModelData& modelData);
|
||||
bool Save(bool withMeshDataFromGpu, Function<FlaxChunk*(int32)>& getChunk) override;
|
||||
bool Save(bool withMeshDataFromGpu, Function<FlaxChunk*(int32)>& getChunk) const override;
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
@@ -218,16 +218,8 @@ void ModelBase::GetLODData(int32 lodIndex, BytesContainer& data) const
|
||||
bool ModelBase::Save(bool withMeshDataFromGpu, const StringView& path)
|
||||
{
|
||||
// Validate state
|
||||
if (WaitForLoaded())
|
||||
{
|
||||
LOG(Error, "Asset loading failed. Cannot save it.");
|
||||
if (OnCheckSave(path))
|
||||
return true;
|
||||
}
|
||||
if (IsVirtual() && path.IsEmpty())
|
||||
{
|
||||
LOG(Error, "To save virtual asset asset you need to specify the target asset path location.");
|
||||
return true;
|
||||
}
|
||||
if (withMeshDataFromGpu && IsInMainThread())
|
||||
{
|
||||
LOG(Error, "To save model with GPU mesh buffers it needs to be called from the other thread (not the main thread).");
|
||||
@@ -238,7 +230,6 @@ bool ModelBase::Save(bool withMeshDataFromGpu, const StringView& path)
|
||||
LOG(Error, "To save virtual model asset you need to specify 'withMeshDataFromGpu' (it has no other storage container to get data).");
|
||||
return true;
|
||||
}
|
||||
|
||||
ScopeLock lock(Locker);
|
||||
|
||||
// Use a temporary chunks for data storage for virtual assets
|
||||
@@ -399,7 +390,7 @@ bool ModelBase::LoadMesh(MemoryReadStream& stream, byte meshVersion, MeshBase* m
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
bool ModelBase::SaveHeader(WriteStream& stream)
|
||||
bool ModelBase::SaveHeader(WriteStream& stream) const
|
||||
{
|
||||
// Basic info
|
||||
static_assert(MODEL_HEADER_VERSION == 2, "Update code");
|
||||
@@ -852,7 +843,7 @@ bool ModelBase::SaveMesh(WriteStream& stream, const MeshBase* mesh) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ModelBase::Save(bool withMeshDataFromGpu, Function<FlaxChunk*(int32)>& getChunk)
|
||||
bool ModelBase::Save(bool withMeshDataFromGpu, Function<FlaxChunk*(int32)>& getChunk) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -876,6 +867,11 @@ void ModelBase::GetReferences(Array<Guid>& assets, Array<String>& files) const
|
||||
assets.Add(slot.Material.GetID());
|
||||
}
|
||||
|
||||
bool ModelBase::Save(const StringView& path)
|
||||
{
|
||||
return Save(false, path);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int32 ModelBase::GetCurrentResidency() const
|
||||
|
||||
@@ -331,12 +331,12 @@ protected:
|
||||
virtual bool LoadMesh(class MemoryReadStream& stream, byte meshVersion, MeshBase* mesh, MeshData* dataIfReadOnly = nullptr);
|
||||
bool LoadHeader(ReadStream& stream, byte& headerVersion);
|
||||
#if USE_EDITOR
|
||||
virtual bool SaveHeader(WriteStream& stream);
|
||||
virtual bool SaveHeader(WriteStream& stream) const;
|
||||
static bool SaveHeader(WriteStream& stream, const class ModelData& modelData);
|
||||
bool SaveLOD(WriteStream& stream, int32 lodIndex) const;
|
||||
static bool SaveLOD(WriteStream& stream, const ModelData& modelData, int32 lodIndex, bool(saveMesh)(WriteStream& stream, const ModelData& modelData, int32 lodIndex, int32 meshIndex) = nullptr);
|
||||
virtual bool SaveMesh(WriteStream& stream, const MeshBase* mesh) const;
|
||||
virtual bool Save(bool withMeshDataFromGpu, Function<FlaxChunk*(int32)>& getChunk);
|
||||
virtual bool Save(bool withMeshDataFromGpu, Function<FlaxChunk*(int32)>& getChunk) const;
|
||||
#endif
|
||||
|
||||
public:
|
||||
@@ -344,6 +344,7 @@ public:
|
||||
void CancelStreaming() override;
|
||||
#if USE_EDITOR
|
||||
void GetReferences(Array<Guid>& assets, Array<String>& files) const override;
|
||||
bool Save(const StringView& path = StringView::Empty) override;
|
||||
#endif
|
||||
|
||||
// [StreamableResource]
|
||||
|
||||
@@ -18,18 +18,8 @@ RawDataAsset::RawDataAsset(const SpawnParams& params, const AssetInfo* info)
|
||||
|
||||
bool RawDataAsset::Save(const StringView& path)
|
||||
{
|
||||
// Validate state
|
||||
if (WaitForLoaded())
|
||||
{
|
||||
LOG(Error, "Asset loading failed. Cannot save it.");
|
||||
if (OnCheckSave(path))
|
||||
return true;
|
||||
}
|
||||
if (IsVirtual() && path.IsEmpty())
|
||||
{
|
||||
LOG(Error, "To save virtual asset asset you need to specify the target asset path location.");
|
||||
return true;
|
||||
}
|
||||
|
||||
ScopeLock lock(Locker);
|
||||
|
||||
bool result;
|
||||
|
||||
@@ -16,20 +16,11 @@ public:
|
||||
/// </summary>
|
||||
API_FIELD() Array<byte> Data;
|
||||
|
||||
public:
|
||||
#if USE_EDITOR
|
||||
|
||||
/// <summary>
|
||||
/// Saves this asset to the file. Supported only in Editor.
|
||||
/// </summary>
|
||||
/// <param name="path">The custom asset path to use for the saving. Use empty value to save this asset to its own storage location. Can be used to duplicate asset. Must be specified when saving virtual asset.</param>
|
||||
/// <returns>True if failed, otherwise false.</returns>
|
||||
API_FUNCTION() bool Save(const StringView& path = StringView::Empty);
|
||||
|
||||
#endif
|
||||
|
||||
public:
|
||||
// [BinaryAsset]
|
||||
#if USE_EDITOR
|
||||
bool Save(const StringView& path = StringView::Empty) override;
|
||||
#endif
|
||||
uint64 GetMemoryUsage() const override;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -66,18 +66,8 @@ const BitArray<>& SkeletonMask::GetNodesMask()
|
||||
|
||||
bool SkeletonMask::Save(const StringView& path)
|
||||
{
|
||||
// Validate state
|
||||
if (WaitForLoaded())
|
||||
{
|
||||
LOG(Error, "Asset loading failed. Cannot save it.");
|
||||
if (OnCheckSave(path))
|
||||
return true;
|
||||
}
|
||||
if (IsVirtual() && path.IsEmpty())
|
||||
{
|
||||
LOG(Error, "To save virtual asset asset you need to specify the target asset path location.");
|
||||
return true;
|
||||
}
|
||||
|
||||
ScopeLock lock(Locker);
|
||||
|
||||
// Write data
|
||||
|
||||
@@ -51,17 +51,6 @@ public:
|
||||
/// <returns>The constant reference to the skeleton nodes mask.</returns>
|
||||
API_PROPERTY() const BitArray<>& GetNodesMask();
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
/// <summary>
|
||||
/// Saves this asset to the file. Supported only in Editor.
|
||||
/// </summary>
|
||||
/// <param name="path">The custom asset path to use for the saving. Use empty value to save this asset to its own storage location. Can be used to duplicate asset. Must be specified when saving virtual asset.</param>
|
||||
/// <returns>True if cannot save data, otherwise false.</returns>
|
||||
API_FUNCTION() bool Save(const StringView& path = StringView::Empty);
|
||||
|
||||
#endif
|
||||
|
||||
private:
|
||||
void OnSkeletonUnload();
|
||||
|
||||
@@ -73,6 +62,7 @@ public:
|
||||
BinaryAsset::GetReferences(assets, files);
|
||||
assets.Add(Skeleton.GetID());
|
||||
}
|
||||
bool Save(const StringView& path = StringView::Empty) override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
@@ -661,7 +661,7 @@ bool SkinnedModel::LoadHeader(ReadStream& stream, byte& headerVersion)
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
bool SkinnedModel::SaveHeader(WriteStream& stream)
|
||||
bool SkinnedModel::SaveHeader(WriteStream& stream) const
|
||||
{
|
||||
if (ModelBase::SaveHeader(stream))
|
||||
return true;
|
||||
|
||||
@@ -299,7 +299,7 @@ private:
|
||||
bool LoadHeader(ReadStream& stream, byte& headerVersion);
|
||||
#if USE_EDITOR
|
||||
friend class ImportModel;
|
||||
bool SaveHeader(WriteStream& stream) override;
|
||||
bool SaveHeader(WriteStream& stream) const override;
|
||||
static bool SaveHeader(WriteStream& stream, const ModelData& modelData);
|
||||
bool SaveMesh(WriteStream& stream, const MeshBase* mesh) const override;
|
||||
static bool SaveMesh(WriteStream& stream, const ModelData& modelData, int32 lodIndex, int32 meshIndex);
|
||||
|
||||
@@ -29,24 +29,19 @@ bool Texture::IsNormalMap() const
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
bool Texture::Save(const StringView& path)
|
||||
{
|
||||
return Save(path, nullptr);
|
||||
}
|
||||
|
||||
bool Texture::Save(const StringView& path, const InitData* customData)
|
||||
{
|
||||
// Validate state
|
||||
if (WaitForLoaded())
|
||||
{
|
||||
LOG(Error, "Asset loading failed. Cannot save it.");
|
||||
if (OnCheckSave())
|
||||
return true;
|
||||
}
|
||||
if (IsVirtual() && path.IsEmpty())
|
||||
{
|
||||
LOG(Error, "To save virtual asset asset you need to specify the target asset path location.");
|
||||
return true;
|
||||
}
|
||||
|
||||
ScopeLock lock(Locker);
|
||||
|
||||
AssetInitData data;
|
||||
const auto texture = StreamingTexture();
|
||||
const class StreamingTexture* texture = StreamingTexture();
|
||||
|
||||
// Use a temporary chunks for data storage for virtual assets
|
||||
FlaxChunk* tmpChunks[ASSET_FILE_DATA_CHUNKS];
|
||||
|
||||
@@ -23,17 +23,6 @@ API_CLASS(NoSpawn) class FLAXENGINE_API Texture : public TextureBase
|
||||
|
||||
public:
|
||||
#if USE_EDITOR
|
||||
|
||||
/// <summary>
|
||||
/// Saves this asset to the file. Supported only in Editor.
|
||||
/// </summary>
|
||||
/// <param name="path">The custom asset path to use for the saving. Use empty value to save this asset to its own storage location. Can be used to duplicate asset. Must be specified when saving virtual asset.</param>
|
||||
/// <returns>True if cannot save data, otherwise false.</returns>
|
||||
API_FUNCTION() bool Save(const StringView& path = StringView::Empty)
|
||||
{
|
||||
return Save(path, nullptr);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves this asset to the file. Supported only in Editor.
|
||||
/// </summary>
|
||||
@@ -41,7 +30,6 @@ public:
|
||||
/// <param name="customData">The custom texture data container. Can be used to override the data stored in the asset. Use null to ignore this argument.</param>
|
||||
/// <returns>True if cannot save data, otherwise false.</returns>
|
||||
bool Save(const StringView& path, const InitData* customData);
|
||||
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
@@ -60,4 +48,10 @@ public:
|
||||
/// <param name="generateMips">True if generate mipmaps for the imported texture.</param>
|
||||
/// <returns>The loaded texture (virtual asset) or null if fails.</returns>
|
||||
API_FUNCTION() static Texture* FromFile(const StringView& path, bool generateMips = false);
|
||||
|
||||
public:
|
||||
// [TextureBase]
|
||||
#if USE_EDITOR
|
||||
bool Save(const StringView& path = StringView::Empty) override;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "VisualScript.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Types/Span.h"
|
||||
#include "Engine/Core/Types/DataContainer.h"
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/Content/Factories/BinaryAssetFactory.h"
|
||||
@@ -1303,6 +1304,23 @@ VisualScript::VisualScript(const SpawnParams& params, const AssetInfo* info)
|
||||
{
|
||||
}
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
bool VisualScript::Save(const StringView& path)
|
||||
{
|
||||
if (OnCheckSave(path))
|
||||
return true;
|
||||
ScopeLock lock(Locker);
|
||||
MemoryWriteStream writeStream;
|
||||
if (Graph.Save(&writeStream, true))
|
||||
return true;
|
||||
BytesContainer data;
|
||||
data.Link(ToSpan(writeStream));
|
||||
return SaveSurface(data, Meta);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Asset::LoadResult VisualScript::load()
|
||||
{
|
||||
// Build Visual Script typename that is based on asset id
|
||||
@@ -2184,7 +2202,7 @@ const VisualScript::Field* VisualScript::FindField(const StringAnsiView& name) c
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BytesContainer VisualScript::LoadSurface()
|
||||
BytesContainer VisualScript::LoadSurface() const
|
||||
{
|
||||
if (WaitForLoaded())
|
||||
return BytesContainer();
|
||||
@@ -2202,19 +2220,10 @@ BytesContainer VisualScript::LoadSurface()
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
bool VisualScript::SaveSurface(const BytesContainer& data, const Metadata& meta)
|
||||
bool VisualScript::SaveSurface(const BytesContainer& data, const Metadata& meta) const
|
||||
{
|
||||
// Wait for asset to be loaded or don't if last load failed
|
||||
if (LastLoadFailed())
|
||||
{
|
||||
LOG(Warning, "Saving asset that failed to load.");
|
||||
}
|
||||
else if (WaitForLoaded())
|
||||
{
|
||||
LOG(Error, "Asset loading failed. Cannot save it.");
|
||||
if (OnCheckSave())
|
||||
return true;
|
||||
}
|
||||
|
||||
ScopeLock lock(Locker);
|
||||
|
||||
// Release all chunks
|
||||
|
||||
@@ -246,7 +246,7 @@ public:
|
||||
/// Tries to load surface graph from the asset.
|
||||
/// </summary>
|
||||
/// <returns>The surface data or empty if failed to load it.</returns>
|
||||
API_FUNCTION() BytesContainer LoadSurface();
|
||||
API_FUNCTION() BytesContainer LoadSurface() const;
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
@@ -256,7 +256,7 @@ public:
|
||||
/// <param name="data">Stream with graph data.</param>
|
||||
/// <param name="meta">Script metadata.</param>
|
||||
/// <returns>True if cannot save it, otherwise false.</returns>
|
||||
API_FUNCTION() bool SaveSurface(const BytesContainer& data, API_PARAM(Ref) const Metadata& meta);
|
||||
API_FUNCTION() bool SaveSurface(const BytesContainer& data, API_PARAM(Ref) const Metadata& meta) const;
|
||||
|
||||
// Returns the amount of methods in the script.
|
||||
API_FUNCTION() int32 GetMethodsCount() const
|
||||
@@ -286,6 +286,7 @@ public:
|
||||
BinaryAsset::GetReferences(assets, files);
|
||||
Graph.GetReferences(assets);
|
||||
}
|
||||
bool Save(const StringView& path = StringView::Empty) override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
@@ -406,7 +407,6 @@ public:
|
||||
static Variant Invoke(VisualScript::Method* method, ScriptingObject* instance, Span<Variant> parameters = Span<Variant>());
|
||||
|
||||
#if VISUAL_SCRIPT_DEBUGGING
|
||||
|
||||
// Custom event that is called every time the Visual Script signal flows over the graph (including the data connections). Can be used to read nad visualize the Visual Script execution logic.
|
||||
static Action DebugFlow;
|
||||
|
||||
@@ -420,6 +420,5 @@ public:
|
||||
/// <param name="result">The output value. Valid only if method returned true.</param>
|
||||
/// <returns>True if could fetch the value, otherwise false.</returns>
|
||||
static bool Evaluate(VisualScript* script, ScriptingObject* instance, uint32 nodeId, uint32 boxId, Variant& result);
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -189,7 +189,7 @@ bool BinaryAsset::HasDependenciesModified() const
|
||||
|
||||
#endif
|
||||
|
||||
FlaxChunk* BinaryAsset::GetOrCreateChunk(int32 index)
|
||||
FlaxChunk* BinaryAsset::GetOrCreateChunk(int32 index) const
|
||||
{
|
||||
if (IsVirtual()) // Virtual assets don't own storage container
|
||||
return nullptr;
|
||||
@@ -205,7 +205,7 @@ FlaxChunk* BinaryAsset::GetOrCreateChunk(int32 index)
|
||||
|
||||
// Allocate
|
||||
ASSERT(Storage);
|
||||
_header.Chunks[index] = chunk = Storage->AllocateChunk();
|
||||
const_cast<BinaryAsset*>(this)->_header.Chunks[index] = chunk = Storage->AllocateChunk();
|
||||
if (chunk)
|
||||
chunk->RegisterUsage();
|
||||
|
||||
@@ -263,10 +263,9 @@ void BinaryAsset::GetChunkData(int32 index, BytesContainer& data) const
|
||||
data.Link(chunk->Data);
|
||||
}
|
||||
|
||||
bool BinaryAsset::LoadChunk(int32 chunkIndex)
|
||||
bool BinaryAsset::LoadChunk(int32 chunkIndex) const
|
||||
{
|
||||
ASSERT(Storage);
|
||||
|
||||
const auto chunk = _header.Chunks[chunkIndex];
|
||||
if (chunk != nullptr
|
||||
&& chunk->IsMissing()
|
||||
@@ -275,19 +274,14 @@ bool BinaryAsset::LoadChunk(int32 chunkIndex)
|
||||
if (Storage->LoadAssetChunk(chunk))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BinaryAsset::LoadChunks(AssetChunksFlag chunks)
|
||||
bool BinaryAsset::LoadChunks(AssetChunksFlag chunks) const
|
||||
{
|
||||
ASSERT(Storage);
|
||||
|
||||
// Check if skip loading
|
||||
if (chunks == 0)
|
||||
return false;
|
||||
|
||||
// Load all missing marked chunks
|
||||
ASSERT(Storage);
|
||||
for (int32 i = 0; i < ASSET_FILE_DATA_CHUNKS; i++)
|
||||
{
|
||||
auto chunk = _header.Chunks[i];
|
||||
@@ -300,7 +294,6 @@ bool BinaryAsset::LoadChunks(AssetChunksFlag chunks)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -166,7 +166,7 @@ public:
|
||||
/// </summary>
|
||||
/// <param name="index">The chunk index.</param>
|
||||
/// <returns>Flax Chunk object (may be null if asset storage doesn't allow to add new chunks).</returns>
|
||||
FlaxChunk* GetOrCreateChunk(int32 index);
|
||||
FlaxChunk* GetOrCreateChunk(int32 index) const;
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified chunk exists.
|
||||
@@ -238,14 +238,14 @@ public:
|
||||
/// </summary>
|
||||
/// <param name="chunkIndex">The chunk index to load.</param>
|
||||
/// <returns>True if failed, otherwise false.</returns>
|
||||
bool LoadChunk(int32 chunkIndex);
|
||||
bool LoadChunk(int32 chunkIndex) const;
|
||||
|
||||
/// <summary>
|
||||
/// Loads the chunks (synchronous, blocks current thread).
|
||||
/// </summary>
|
||||
/// <param name="chunks">The chunks to load (packed in a flag).</param>
|
||||
/// <returns>True if failed, otherwise false.</returns>
|
||||
bool LoadChunks(AssetChunksFlag chunks);
|
||||
bool LoadChunks(AssetChunksFlag chunks) const;
|
||||
|
||||
#if USE_EDITOR
|
||||
/// <summary>
|
||||
|
||||
@@ -1156,19 +1156,14 @@ void Content::tryCallOnLoaded(Asset* asset)
|
||||
void Content::onAssetLoaded(Asset* asset)
|
||||
{
|
||||
// This is called by the asset on loading end
|
||||
ASSERT(asset && asset->IsLoaded());
|
||||
|
||||
ScopeLock locker(LoadedAssetsToInvokeLocker);
|
||||
|
||||
LoadedAssetsToInvoke.Add(asset);
|
||||
}
|
||||
|
||||
void Content::onAssetUnload(Asset* asset)
|
||||
{
|
||||
// This is called by the asset on unloading
|
||||
|
||||
ScopeLock locker(AssetsLocker);
|
||||
|
||||
Assets.Remove(asset->GetID());
|
||||
UnloadQueue.Remove(asset);
|
||||
LoadedAssetsToInvoke.Remove(asset);
|
||||
|
||||
26
Source/Engine/Content/Deprecated.h
Normal file
26
Source/Engine/Content/Deprecated.h
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Core/Core.h"
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
// Utility for marking content as deprecated when loading it in Editor. Used to auto-upgrade (by resaving) data during development in editor or during game cooking.
|
||||
class FLAXENGINE_API ContentDeprecated
|
||||
{
|
||||
public:
|
||||
// Marks content as deprecated (for the current thread).
|
||||
static void Mark();
|
||||
// Reads and clears deprecation flag (for the current thread).
|
||||
static bool Clear(bool newValue = false);
|
||||
};
|
||||
|
||||
// Marks content as deprecated (for the current thread).
|
||||
#define MARK_CONTENT_DEPRECATED() ContentDeprecated::Mark()
|
||||
|
||||
#else
|
||||
|
||||
#define MARK_CONTENT_DEPRECATED()
|
||||
|
||||
#endif
|
||||
@@ -161,25 +161,19 @@ void JsonAssetBase::GetReferences(const StringAnsiView& json, Array<Guid>& asset
|
||||
FindIds(document, assets, files);
|
||||
}
|
||||
|
||||
bool JsonAssetBase::Save(const StringView& path) const
|
||||
bool JsonAssetBase::Save(const StringView& path)
|
||||
{
|
||||
// Validate state
|
||||
if (WaitForLoaded())
|
||||
{
|
||||
LOG(Error, "Asset loading failed. Cannot save it.");
|
||||
if (OnCheckSave(path))
|
||||
return true;
|
||||
}
|
||||
if (IsVirtual() && path.IsEmpty())
|
||||
{
|
||||
LOG(Error, "To save virtual asset asset you need to specify the target asset path location.");
|
||||
return true;
|
||||
}
|
||||
PROFILE_CPU();
|
||||
ScopeLock lock(Locker);
|
||||
|
||||
// Serialize to json to the buffer
|
||||
rapidjson_flax::StringBuffer buffer;
|
||||
PrettyJsonWriter writerObj(buffer);
|
||||
_isResaving = true;
|
||||
Save(writerObj);
|
||||
_isResaving = false;
|
||||
|
||||
// Save json to file
|
||||
if (File::WriteAllBytes(path.HasChars() ? path : StringView(GetPath()), (byte*)buffer.GetString(), (int32)buffer.GetSize()))
|
||||
@@ -193,12 +187,8 @@ bool JsonAssetBase::Save(const StringView& path) const
|
||||
|
||||
bool JsonAssetBase::Save(JsonWriter& writer) const
|
||||
{
|
||||
// Validate state
|
||||
if (WaitForLoaded())
|
||||
{
|
||||
LOG(Error, "Asset loading failed. Cannot save it.");
|
||||
if (OnCheckSave())
|
||||
return true;
|
||||
}
|
||||
ScopeLock lock(Locker);
|
||||
|
||||
writer.StartObject();
|
||||
@@ -348,6 +338,61 @@ uint64 JsonAsset::GetMemoryUsage() const
|
||||
return result;
|
||||
}
|
||||
|
||||
void JsonAsset::OnGetData(rapidjson_flax::StringBuffer& buffer) const
|
||||
{
|
||||
if (Instance && InstanceType && _isResaving)
|
||||
{
|
||||
// Serialize instance object that was loaded (from potentially deprecated data, serialize method is always up to date)
|
||||
const ScriptingType& type = InstanceType.GetType();
|
||||
PrettyJsonWriter writer(buffer);
|
||||
bool got = false;
|
||||
switch (type.Type)
|
||||
{
|
||||
case ScriptingTypes::Class:
|
||||
case ScriptingTypes::Structure:
|
||||
{
|
||||
const ScriptingType::InterfaceImplementation* interface = type.GetInterface(ISerializable::TypeInitializer);
|
||||
writer.StartObject();
|
||||
((ISerializable*)((byte*)Instance + interface->VTableOffset))->Serialize(writer, nullptr);
|
||||
got = true;
|
||||
break;
|
||||
}
|
||||
case ScriptingTypes::Script:
|
||||
{
|
||||
writer.StartObject();
|
||||
ToInterface<ISerializable>((ScriptingObject*)Instance)->Serialize(writer, nullptr);
|
||||
got = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (got)
|
||||
{
|
||||
writer.EndObject();
|
||||
|
||||
// Parse json document (CreateInstance uses it to spawn object)
|
||||
auto* self = const_cast<JsonAsset*>(this);
|
||||
{
|
||||
PROFILE_CPU_NAMED("Json.Parse");
|
||||
self->Document.Parse(buffer.GetString(), buffer.GetSize());
|
||||
}
|
||||
if (self->Document.HasParseError())
|
||||
{
|
||||
self->Data = nullptr;
|
||||
Log::JsonParseException(Document.GetParseError(), Document.GetErrorOffset());
|
||||
}
|
||||
else
|
||||
{
|
||||
self->Data = &self->Document;
|
||||
self->DataEngineBuild = FLAXENGINE_VERSION_BUILD;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
JsonAssetBase::OnGetData(buffer);
|
||||
}
|
||||
|
||||
Asset::LoadResult JsonAsset::loadAsset()
|
||||
{
|
||||
const auto result = JsonAssetBase::loadAsset();
|
||||
@@ -387,6 +432,7 @@ void JsonAsset::onLoaded_MainThread()
|
||||
JsonAssetBase::onLoaded_MainThread();
|
||||
|
||||
// Special case for Settings assets to flush them after edited and saved in Editor
|
||||
// TODO: add interface for custom JsonAsset interaction of the instance class (eg. OnJsonLoaded, or similar to C# like OnDeserialized from Newtonsoft.Json)
|
||||
const StringAsANSI<> dataTypeNameAnsi(DataTypeName.Get(), DataTypeName.Length());
|
||||
const auto typeHandle = Scripting::FindScriptingType(StringAnsiView(dataTypeNameAnsi.Get(), DataTypeName.Length()));
|
||||
if (Instance && typeHandle && typeHandle.IsSubclassOf(SettingsBase::TypeInitializer) && _isAfterReload)
|
||||
|
||||
@@ -16,6 +16,7 @@ API_CLASS(Abstract, NoSpawn) class FLAXENGINE_API JsonAssetBase : public Asset
|
||||
protected:
|
||||
String _path;
|
||||
bool _isVirtualDocument = false;
|
||||
bool _isResaving = false;
|
||||
|
||||
protected:
|
||||
/// <summary>
|
||||
@@ -73,13 +74,6 @@ public:
|
||||
/// <param name="assets">The output list of object IDs references by the asset (appended, not cleared).</param>
|
||||
API_FUNCTION() static void GetReferences(const StringAnsiView& json, API_PARAM(Out) Array<Guid, HeapAllocation>& assets);
|
||||
|
||||
/// <summary>
|
||||
/// Saves this asset to the file. Supported only in Editor.
|
||||
/// </summary>
|
||||
/// <param name="path">The custom asset path to use for the saving. Use empty value to save this asset to its own storage location. Can be used to duplicate asset. Must be specified when saving virtual asset.</param>
|
||||
/// <returns>True if cannot save data, otherwise false.</returns>
|
||||
API_FUNCTION() bool Save(const StringView& path = StringView::Empty) const;
|
||||
|
||||
/// <summary>
|
||||
/// Saves this asset to the Json Writer buffer (both ID, Typename header and Data contents). Supported only in Editor.
|
||||
/// </summary>
|
||||
@@ -98,6 +92,7 @@ public:
|
||||
uint64 GetMemoryUsage() const override;
|
||||
#if USE_EDITOR
|
||||
void GetReferences(Array<Guid, HeapAllocation>& assets, Array<String, HeapAllocation>& files) const override;
|
||||
bool Save(const StringView& path = StringView::Empty) override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
@@ -149,6 +144,7 @@ public:
|
||||
|
||||
protected:
|
||||
// [JsonAssetBase]
|
||||
void OnGetData(rapidjson_flax::StringBuffer& buffer) const override;
|
||||
LoadResult loadAsset() override;
|
||||
void unload(bool isReloading) override;
|
||||
void onLoaded_MainThread() override;
|
||||
|
||||
@@ -888,10 +888,12 @@ Variant::Variant(const Span<byte>& v)
|
||||
}
|
||||
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||
#include "Engine/Content/Deprecated.h"
|
||||
Variant::Variant(const CommonValue& value)
|
||||
: Variant()
|
||||
{
|
||||
// [Deprecated on 31.07.2020, expires on 31.07.2022]
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
switch (value.Type)
|
||||
{
|
||||
case CommonType::Bool:
|
||||
|
||||
@@ -154,18 +154,8 @@ void GameplayGlobals::ResetValues()
|
||||
|
||||
bool GameplayGlobals::Save(const StringView& path)
|
||||
{
|
||||
// Validate state
|
||||
if (WaitForLoaded())
|
||||
{
|
||||
LOG(Error, "Asset loading failed. Cannot save it.");
|
||||
if (OnCheckSave(path))
|
||||
return true;
|
||||
}
|
||||
if (IsVirtual() && path.IsEmpty())
|
||||
{
|
||||
LOG(Error, "To save virtual asset asset you need to specify the target asset path location.");
|
||||
return true;
|
||||
}
|
||||
|
||||
ScopeLock lock(Locker);
|
||||
|
||||
// Save to bytes
|
||||
|
||||
@@ -80,20 +80,12 @@ public:
|
||||
/// </summary>
|
||||
API_FUNCTION() void ResetValues();
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
/// <summary>
|
||||
/// Saves this asset to the file. Supported only in Editor.
|
||||
/// </summary>
|
||||
/// <param name="path">The custom asset path to use for the saving. Use empty value to save this asset to its own storage location. Can be used to duplicate asset. Must be specified when saving virtual asset.</param>
|
||||
/// <returns>True if cannot save data, otherwise false.</returns>
|
||||
API_FUNCTION() bool Save(const StringView& path = StringView::Empty);
|
||||
|
||||
#endif
|
||||
|
||||
public:
|
||||
// [BinaryAsset]
|
||||
void InitAsVirtual() override;
|
||||
#if USE_EDITOR
|
||||
bool Save(const StringView& path = StringView::Empty) override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
// [BinaryAsset]
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "Engine/Core/Random.h"
|
||||
#include "Engine/Engine/Engine.h"
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
#include "Engine/Content/Deprecated.h"
|
||||
#if !FOLIAGE_USE_SINGLE_QUAD_TREE
|
||||
#include "Engine/Threading/JobSystem.h"
|
||||
#if FOLIAGE_USE_DRAW_CALLS_BATCHING
|
||||
@@ -1374,6 +1375,7 @@ void Foliage::Deserialize(DeserializeStream& stream, ISerializeModifier* modifie
|
||||
if (modifier->EngineBuild <= 6189)
|
||||
{
|
||||
// [Deprecated on 30.11.2019, expires on 30.11.2021]
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
InstanceEncoded1 enc;
|
||||
for (int32 i = 0; i < foliageInstancesCount; i++)
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "Engine/Core/Math/Vector4.h"
|
||||
#include "Engine/Core/Math/Matrix.h"
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/Content/Deprecated.h"
|
||||
#include "Engine/Graphics/GPUContext.h"
|
||||
#include "Engine/Engine/GameplayGlobals.h"
|
||||
#include "Engine/Serialization/MemoryWriteStream.h"
|
||||
@@ -652,6 +653,8 @@ bool MaterialParams::Load(ReadStream* stream)
|
||||
{
|
||||
case 1: // [Deprecated on 15.11.2019, expires on 15.11.2021]
|
||||
{
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
|
||||
// Size of the collection
|
||||
uint16 paramsCount;
|
||||
stream->ReadUint16(¶msCount);
|
||||
@@ -727,6 +730,8 @@ bool MaterialParams::Load(ReadStream* stream)
|
||||
break;
|
||||
case 2: // [Deprecated on 15.11.2019, expires on 15.11.2021]
|
||||
{
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
|
||||
// Size of the collection
|
||||
uint16 paramsCount;
|
||||
stream->ReadUint16(¶msCount);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "Engine/Graphics/Shaders/GPUShader.h"
|
||||
#if COMPILE_WITH_SHADER_COMPILER
|
||||
#include "Engine/Engine/CommandLine.h"
|
||||
#include "Engine/Content/Deprecated.h"
|
||||
#include "Engine/Serialization/MemoryReadStream.h"
|
||||
#endif
|
||||
#include "Engine/ShadowsOfMordor/AtlasChartsPacker.h"
|
||||
@@ -98,8 +99,11 @@ bool ShaderAssetBase::initBase(AssetInitData& initData)
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
bool ShaderAssetBase::Save()
|
||||
bool ShaderAssetBase::SaveShaderAsset() const
|
||||
{
|
||||
// Asset is being saved so no longer need to resave deprecated data in it
|
||||
ContentDeprecated::Clear();
|
||||
|
||||
auto parent = GetShaderAsset();
|
||||
AssetInitData data;
|
||||
data.SerializedVersion = ShaderStorage::Header::Version;
|
||||
@@ -296,7 +300,7 @@ bool ShaderAssetBase::LoadShaderCache(ShaderCacheResult& result)
|
||||
|
||||
#if USE_EDITOR
|
||||
// Save chunks to the asset file
|
||||
if (Save())
|
||||
if (SaveShaderAsset())
|
||||
{
|
||||
LOG(Warning, "Cannot save '{0}'.", parent->ToString());
|
||||
return true;
|
||||
|
||||
@@ -30,15 +30,13 @@ public:
|
||||
static int32 GetCacheChunkIndex(ShaderProfile profile);
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
/// <summary>
|
||||
/// Prepare shader compilation options
|
||||
/// Prepare shader compilation options.
|
||||
/// </summary>
|
||||
/// <param name="options">Options</param>
|
||||
/// <param name="options">The output options.</param>
|
||||
virtual void InitCompilationOptions(struct ShaderCompilationOptions& options)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
protected:
|
||||
@@ -50,13 +48,11 @@ protected:
|
||||
virtual BinaryAsset* GetShaderAsset() const = 0;
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
/// <summary>
|
||||
/// Saves this shader asset to the storage container.
|
||||
/// </summary>
|
||||
/// <returns>True if failed, otherwise false.</returns>
|
||||
bool Save();
|
||||
|
||||
bool SaveShaderAsset() const;
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
@@ -70,12 +66,10 @@ protected:
|
||||
DataContainer<byte> Data;
|
||||
|
||||
#if COMPILE_WITH_SHADER_COMPILER
|
||||
|
||||
/// <summary>
|
||||
/// The list of files included by the shader source (used by the given cache on the runtime graphics platform shader profile). Paths are absolute and unique.
|
||||
/// </summary>
|
||||
Array<String> Includes;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -87,7 +81,6 @@ protected:
|
||||
bool LoadShaderCache(ShaderCacheResult& result);
|
||||
|
||||
#if COMPILE_WITH_SHADER_COMPILER
|
||||
|
||||
/// <summary>
|
||||
/// Registers shader asset for the automated reloads on source includes changes.
|
||||
/// </summary>
|
||||
@@ -100,7 +93,6 @@ protected:
|
||||
/// </summary>
|
||||
/// <param name="asset">The asset.</param>
|
||||
void UnregisterForShaderReloads(Asset* asset);
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ public:
|
||||
};
|
||||
/// <summary>
|
||||
/// File header, version 19
|
||||
/// [Deprecated on 13.07.2022, expires on 13.07.2024]
|
||||
/// [Deprecated on 13.07.2022, expires on 13.07.2024]
|
||||
/// </summary>
|
||||
struct Header19
|
||||
{
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "Engine/Scripting/ManagedCLR/MClass.h"
|
||||
#include "Engine/Threading/Threading.h"
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/Content/Deprecated.h"
|
||||
#include "Engine/Core/Cache.h"
|
||||
#include "Engine/Core/Collections/CollectionPoolCache.h"
|
||||
#include "Engine/Debug/Exceptions/JsonParseException.h"
|
||||
@@ -1074,12 +1075,18 @@ void Actor::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
|
||||
// StaticFlags update - added StaticFlags::Navigation
|
||||
// [Deprecated on 17.05.2020, expires on 17.05.2021]
|
||||
if (modifier->EngineBuild < 6178 && (int32)_staticFlags == (1 + 2 + 4))
|
||||
{
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
_staticFlags |= StaticFlags::Navigation;
|
||||
}
|
||||
|
||||
// StaticFlags update - added StaticFlags::Shadow
|
||||
// [Deprecated on 17.05.2020, expires on 17.05.2021]
|
||||
if (modifier->EngineBuild < 6601 && (int32)_staticFlags == (1 + 2 + 4 + 8))
|
||||
{
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
_staticFlags |= StaticFlags::Shadow;
|
||||
}
|
||||
|
||||
const auto tag = stream.FindMember("Tag");
|
||||
if (tag != stream.MemberEnd())
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "Engine/Core/Math/Matrix3x3.h"
|
||||
#include "Editor/Editor.h"
|
||||
#endif
|
||||
#include "Engine/Content/Deprecated.h"
|
||||
#include "Engine/Graphics/GPUContext.h"
|
||||
#include "Engine/Graphics/GPUDevice.h"
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
@@ -1153,10 +1154,16 @@ void AnimatedModel::Deserialize(DeserializeStream& stream, ISerializeModifier* m
|
||||
|
||||
// [Deprecated on 07.02.2022, expires on 07.02.2024]
|
||||
if (modifier->EngineBuild <= 6330)
|
||||
{
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
DrawModes |= DrawPass::GlobalSDF;
|
||||
}
|
||||
// [Deprecated on 27.04.2022, expires on 27.04.2024]
|
||||
if (modifier->EngineBuild <= 6331)
|
||||
{
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
DrawModes |= DrawPass::GlobalSurfaceAtlas;
|
||||
}
|
||||
}
|
||||
|
||||
const Span<MaterialSlot> AnimatedModel::GetMaterialSlots() const
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "Engine/Renderer/ProbesRenderer.h"
|
||||
#include "Engine/Renderer/ReflectionsPass.h"
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/Content/Deprecated.h"
|
||||
#include "Engine/ContentExporters/AssetExporters.h"
|
||||
#include "Engine/ContentImporters/AssetsImportingManager.h"
|
||||
#include "Engine/Graphics/RenderTools.h"
|
||||
@@ -255,6 +256,7 @@ void EnvironmentProbe::Deserialize(DeserializeStream& stream, ISerializeModifier
|
||||
// [Deprecated on 18.07.2022, expires on 18.07.2022]
|
||||
if (modifier->EngineBuild <= 6332)
|
||||
{
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
const auto member = stream.FindMember("AutoUpdate");
|
||||
if (member != stream.MemberEnd() && member->value.IsBool() && member->value.GetBool())
|
||||
UpdateMode = ProbeUpdateMode::WhenMoved;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "Engine/Core/Math/Matrix3x4.h"
|
||||
#include "Engine/Engine/Engine.h"
|
||||
#include "Engine/Serialization/Serialization.h"
|
||||
#include "Engine/Content/Deprecated.h"
|
||||
#include "Engine/Graphics/GPUBufferDescription.h"
|
||||
#include "Engine/Graphics/GPUDevice.h"
|
||||
#include "Engine/Graphics/GPUBuffer.h"
|
||||
@@ -514,10 +515,16 @@ void SplineModel::Deserialize(DeserializeStream& stream, ISerializeModifier* mod
|
||||
|
||||
// [Deprecated on 07.02.2022, expires on 07.02.2024]
|
||||
if (modifier->EngineBuild <= 6330)
|
||||
{
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
DrawModes |= DrawPass::GlobalSDF;
|
||||
}
|
||||
// [Deprecated on 27.04.2022, expires on 27.04.2024]
|
||||
if (modifier->EngineBuild <= 6331)
|
||||
{
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
DrawModes |= DrawPass::GlobalSurfaceAtlas;
|
||||
}
|
||||
}
|
||||
|
||||
void SplineModel::OnActiveInTreeChanged()
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "StaticModel.h"
|
||||
#include "Engine/Engine/Engine.h"
|
||||
#include "Engine/Content/Deprecated.h"
|
||||
#include "Engine/Graphics/GPUBuffer.h"
|
||||
#include "Engine/Graphics/GPUBufferDescription.h"
|
||||
#include "Engine/Graphics/GPUContext.h"
|
||||
@@ -534,15 +535,22 @@ void StaticModel::Deserialize(DeserializeStream& stream, ISerializeModifier* mod
|
||||
const auto member = stream.FindMember("HiddenShadow");
|
||||
if (member != stream.MemberEnd() && member->value.IsBool() && member->value.GetBool())
|
||||
{
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
DrawModes = DrawPass::Depth;
|
||||
}
|
||||
}
|
||||
// [Deprecated on 07.02.2022, expires on 07.02.2024]
|
||||
if (modifier->EngineBuild <= 6330)
|
||||
{
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
DrawModes |= DrawPass::GlobalSDF;
|
||||
}
|
||||
// [Deprecated on 27.04.2022, expires on 27.04.2024]
|
||||
if (modifier->EngineBuild <= 6331)
|
||||
{
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
DrawModes |= DrawPass::GlobalSurfaceAtlas;
|
||||
}
|
||||
|
||||
{
|
||||
const auto member = stream.FindMember("RenderPasses");
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "NavigationSettings.h"
|
||||
#include "NavMeshRuntime.h"
|
||||
#include "NavMeshBuilder.h"
|
||||
#include "NavMesh.h"
|
||||
#include "Engine/Core/Config/GameSettings.h"
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/Content/JsonAsset.h"
|
||||
@@ -14,8 +15,7 @@
|
||||
#include "Engine/Level/Level.h"
|
||||
#include "Engine/Level/Scene/Scene.h"
|
||||
#endif
|
||||
#include "NavMesh.h"
|
||||
|
||||
#include "Engine/Content/Deprecated.h"
|
||||
#include "Engine/Engine/EngineService.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#include "Engine/Serialization/Serialization.h"
|
||||
@@ -255,6 +255,7 @@ void NavigationSettings::Deserialize(DeserializeStream& stream, ISerializeModifi
|
||||
else
|
||||
{
|
||||
// [Deprecated on 12.01.2021, expires on 12.01.2022]
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
float WalkableRadius = 34.0f;
|
||||
float WalkableHeight = 144.0f;
|
||||
float WalkableMaxClimb = 35.0f;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "ParticleEffect.h"
|
||||
#include "Particles.h"
|
||||
#include "Engine/Core/Types/CommonValue.h"
|
||||
#include "Engine/Content/Deprecated.h"
|
||||
#include "Engine/Serialization/JsonTools.h"
|
||||
#include "Engine/Serialization/Serialization.h"
|
||||
#include "Engine/Level/Scene/SceneRendering.h"
|
||||
@@ -664,6 +665,7 @@ void ParticleEffect::Deserialize(DeserializeStream& stream, ISerializeModifier*
|
||||
if (modifier->EngineBuild < 6197)
|
||||
{
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
const auto& overrides = overridesMember->value;
|
||||
ASSERT(overrides.IsArray());
|
||||
_parametersOverrides.EnsureCapacity(_parametersOverrides.Count() + overrides.Size());
|
||||
|
||||
@@ -154,6 +154,16 @@ Asset::LoadResult ParticleEmitter::load()
|
||||
LOG(Warning, "Cannot load Particle Emitter GPU graph '{0}'.", GetPath());
|
||||
return LoadResult::CannotLoadData;
|
||||
}
|
||||
if (ContentDeprecated::Clear())
|
||||
{
|
||||
// If encountered any deprecated data when loading graph then serialize it
|
||||
MemoryWriteStream writeStream(1024);
|
||||
if (!Graph.Save(&writeStream, true))
|
||||
{
|
||||
surfaceChunk->Data.Copy(ToSpan(writeStream));
|
||||
ContentDeprecated::Clear();
|
||||
}
|
||||
}
|
||||
generator.AddGraph(graph);
|
||||
|
||||
// Get chunk with material parameters
|
||||
@@ -199,7 +209,7 @@ Asset::LoadResult ParticleEmitter::load()
|
||||
|
||||
// Save to file
|
||||
#if USE_EDITOR
|
||||
if (Save())
|
||||
if (SaveShaderAsset())
|
||||
{
|
||||
LOG(Error, "Cannot save \'{0}\'", ToString());
|
||||
return LoadResult::Failed;
|
||||
@@ -318,10 +328,6 @@ void ParticleEmitter::OnDependencyModified(BinaryAsset* asset)
|
||||
Reload();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
void ParticleEmitter::InitCompilationOptions(ShaderCompilationOptions& options)
|
||||
{
|
||||
// Base
|
||||
@@ -377,19 +383,10 @@ BytesContainer ParticleEmitter::LoadSurface(bool createDefaultIfMissing)
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
bool ParticleEmitter::SaveSurface(BytesContainer& data)
|
||||
bool ParticleEmitter::SaveSurface(const BytesContainer& data)
|
||||
{
|
||||
// Wait for asset to be loaded or don't if last load failed (eg. by shader source compilation error)
|
||||
if (LastLoadFailed())
|
||||
{
|
||||
LOG(Warning, "Saving asset that failed to load.");
|
||||
}
|
||||
else if (WaitForLoaded())
|
||||
{
|
||||
LOG(Error, "Asset loading failed. Cannot save it.");
|
||||
if (OnCheckSave())
|
||||
return true;
|
||||
}
|
||||
|
||||
ScopeLock lock(Locker);
|
||||
|
||||
// Release all chunks
|
||||
@@ -406,7 +403,7 @@ bool ParticleEmitter::SaveSurface(BytesContainer& data)
|
||||
ASSERT(visjectSurfaceChunk != nullptr);
|
||||
visjectSurfaceChunk->Data.Copy(data);
|
||||
|
||||
if (Save())
|
||||
if (SaveShaderAsset())
|
||||
{
|
||||
LOG(Error, "Cannot save \'{0}\'", ToString());
|
||||
return true;
|
||||
@@ -420,4 +417,23 @@ bool ParticleEmitter::SaveSurface(BytesContainer& data)
|
||||
return false;
|
||||
}
|
||||
|
||||
void ParticleEmitter::GetReferences(Array<Guid>& assets, Array<String>& files) const
|
||||
{
|
||||
BinaryAsset::GetReferences(assets, files);
|
||||
Graph.GetReferences(assets);
|
||||
}
|
||||
|
||||
bool ParticleEmitter::Save(const StringView& path)
|
||||
{
|
||||
if (OnCheckSave(path))
|
||||
return true;
|
||||
ScopeLock lock(Locker);
|
||||
MemoryWriteStream writeStream;
|
||||
if (Graph.Save(&writeStream, true))
|
||||
return true;
|
||||
BytesContainer data;
|
||||
data.Link(ToSpan(writeStream));
|
||||
return SaveSurface(data);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,6 +20,7 @@ class ParticleEmitterInstance;
|
||||
API_CLASS(NoSpawn) class FLAXENGINE_API ParticleEmitter : public ShaderAssetTypeBase<BinaryAsset>
|
||||
{
|
||||
DECLARE_BINARY_ASSET_HEADER(ParticleEmitter, ShadersSerializedVersion);
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// The loaded particle graph.
|
||||
@@ -84,14 +85,12 @@ public:
|
||||
API_FUNCTION() BytesContainer LoadSurface(bool createDefaultIfMissing);
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
/// <summary>
|
||||
/// Updates surface (saves new one, discard cached data, reloads asset).
|
||||
/// </summary>
|
||||
/// <param name="data">The surface graph data.</param>
|
||||
/// <returns>True if cannot save it, otherwise false.</returns>
|
||||
API_FUNCTION() bool SaveSurface(BytesContainer& data);
|
||||
|
||||
API_FUNCTION() bool SaveSurface(const BytesContainer& data);
|
||||
#endif
|
||||
|
||||
public:
|
||||
@@ -100,7 +99,7 @@ public:
|
||||
/// </summary>
|
||||
/// <param name="position">The spawn position.</param>
|
||||
/// <param name="duration">The effect playback duration (in seconds).</param>
|
||||
/// <param name="autoDestroy">If set to <c>true</c> effect be be auto-destroyed after duration.</param>
|
||||
/// <param name="autoDestroy">If set to <c>true</c> effect will be auto-destroyed after duration.</param>
|
||||
/// <returns>The spawned effect.</returns>
|
||||
API_FUNCTION() ParticleEffect* Spawn(const Vector3& position, float duration = MAX_float, bool autoDestroy = false)
|
||||
{
|
||||
@@ -113,7 +112,7 @@ public:
|
||||
/// <param name="position">The spawn position.</param>
|
||||
/// <param name="rotation">The spawn rotation.</param>
|
||||
/// <param name="duration">The effect playback duration (in seconds).</param>
|
||||
/// <param name="autoDestroy">If set to <c>true</c> effect be be auto-destroyed after duration.</param>
|
||||
/// <param name="autoDestroy">If set to <c>true</c> effect will be auto-destroyed after duration.</param>
|
||||
/// <returns>The spawned effect.</returns>
|
||||
API_FUNCTION() ParticleEffect* Spawn(const Vector3& position, const Quaternion& rotation, float duration = MAX_float, bool autoDestroy = false)
|
||||
{
|
||||
@@ -125,7 +124,7 @@ public:
|
||||
/// </summary>
|
||||
/// <param name="transform">The spawn transform.</param>
|
||||
/// <param name="duration">The effect playback duration (in seconds).</param>
|
||||
/// <param name="autoDestroy">If set to <c>true</c> effect be be auto-destroyed after duration.</param>
|
||||
/// <param name="autoDestroy">If set to <c>true</c> effect will be auto-destroyed after duration.</param>
|
||||
/// <returns>The spawned effect.</returns>
|
||||
API_FUNCTION() ParticleEffect* Spawn(const Transform& transform, float duration = MAX_float, bool autoDestroy = false)
|
||||
{
|
||||
@@ -138,7 +137,7 @@ public:
|
||||
/// <param name="parent">The parent actor (can be null to link it to the first loaded scene).</param>
|
||||
/// <param name="position">The spawn position.</param>
|
||||
/// <param name="duration">The effect playback duration (in seconds).</param>
|
||||
/// <param name="autoDestroy">If set to <c>true</c> effect be be auto-destroyed after duration.</param>
|
||||
/// <param name="autoDestroy">If set to <c>true</c> effect will be auto-destroyed after duration.</param>
|
||||
/// <returns>The spawned effect.</returns>
|
||||
API_FUNCTION() ParticleEffect* Spawn(Actor* parent, const Vector3& position, float duration = MAX_float, bool autoDestroy = false)
|
||||
{
|
||||
@@ -152,7 +151,7 @@ public:
|
||||
/// <param name="position">The spawn position.</param>
|
||||
/// <param name="rotation">The spawn rotation.</param>
|
||||
/// <param name="duration">The effect playback duration (in seconds).</param>
|
||||
/// <param name="autoDestroy">If set to <c>true</c> effect be be auto-destroyed after duration.</param>
|
||||
/// <param name="autoDestroy">If set to <c>true</c> effect will be auto-destroyed after duration.</param>
|
||||
/// <returns>The spawned effect.</returns>
|
||||
API_FUNCTION() ParticleEffect* Spawn(Actor* parent, const Vector3& position, const Quaternion& rotation, float duration = MAX_float, bool autoDestroy = false)
|
||||
{
|
||||
@@ -165,18 +164,15 @@ public:
|
||||
/// <param name="parent">The parent actor (can be null to link it to the first loaded scene).</param>
|
||||
/// <param name="transform">The spawn transform.</param>
|
||||
/// <param name="duration">The effect playback duration (in seconds).</param>
|
||||
/// <param name="autoDestroy">If set to <c>true</c> effect be be auto-destroyed after duration.</param>
|
||||
/// <param name="autoDestroy">If set to <c>true</c> effect will be auto-destroyed after duration.</param>
|
||||
/// <returns>The spawned effect.</returns>
|
||||
API_FUNCTION() ParticleEffect* Spawn(Actor* parent, const Transform& transform, float duration = MAX_float, bool autoDestroy = false);
|
||||
|
||||
public:
|
||||
// [BinaryAsset]
|
||||
#if USE_EDITOR
|
||||
void GetReferences(Array<Guid>& assets, Array<String>& files) const override
|
||||
{
|
||||
BinaryAsset::GetReferences(assets, files);
|
||||
Graph.GetReferences(assets);
|
||||
}
|
||||
void GetReferences(Array<Guid>& assets, Array<String>& files) const override;
|
||||
bool Save(const StringView& path = StringView::Empty) override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
@@ -186,8 +182,6 @@ protected:
|
||||
AssetChunksFlag getChunksToPreload() const override;
|
||||
#if USE_EDITOR
|
||||
void OnDependencyModified(BinaryAsset* asset) override;
|
||||
#endif
|
||||
#if USE_EDITOR
|
||||
void InitCompilationOptions(ShaderCompilationOptions& options) override;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "Engine/Threading/Threading.h"
|
||||
#if USE_EDITOR
|
||||
#include "Engine/Core/Types/DataContainer.h"
|
||||
#include "Engine/Serialization/MemoryWriteStream.h"
|
||||
#endif
|
||||
#include "Engine/Content/Factories/BinaryAssetFactory.h"
|
||||
|
||||
@@ -44,7 +45,7 @@ Asset::LoadResult ParticleEmitterFunction::load()
|
||||
if (!surfaceChunk || !surfaceChunk->IsLoaded())
|
||||
return LoadResult::MissingDataChunk;
|
||||
MemoryReadStream stream(surfaceChunk->Get(), surfaceChunk->Size());
|
||||
if (Graph.Load(&stream, false))
|
||||
if (Graph.Load(&stream, USE_EDITOR))
|
||||
return LoadResult::Failed;
|
||||
for (int32 i = 0; i < Graph.Nodes.Count(); i++)
|
||||
{
|
||||
@@ -103,7 +104,7 @@ AssetChunksFlag ParticleEmitterFunction::getChunksToPreload() const
|
||||
return GET_CHUNK_FLAG(0);
|
||||
}
|
||||
|
||||
bool ParticleEmitterFunction::LoadSurface(ParticleEmitterGraphCPU& graph)
|
||||
bool ParticleEmitterFunction::LoadSurface(ParticleEmitterGraphCPU& graph, bool loadMeta)
|
||||
{
|
||||
if (WaitForLoaded())
|
||||
return true;
|
||||
@@ -114,7 +115,7 @@ bool ParticleEmitterFunction::LoadSurface(ParticleEmitterGraphCPU& graph)
|
||||
{
|
||||
const auto surfaceChunk = GetChunk(0);
|
||||
MemoryReadStream stream(surfaceChunk->Get(), surfaceChunk->Size());
|
||||
return graph.Load(&stream, false);
|
||||
return graph.Load(&stream, loadMeta);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -141,7 +142,7 @@ BytesContainer ParticleEmitterFunction::LoadSurface()
|
||||
|
||||
#if COMPILE_WITH_PARTICLE_GPU_GRAPH
|
||||
|
||||
bool ParticleEmitterFunction::LoadSurface(ParticleEmitterGraphGPU& graph)
|
||||
bool ParticleEmitterFunction::LoadSurface(ParticleEmitterGraphGPU& graph) const
|
||||
{
|
||||
if (WaitForLoaded())
|
||||
return true;
|
||||
@@ -178,19 +179,10 @@ void ParticleEmitterFunction::GetSignature(Array<StringView, FixedAllocation<32>
|
||||
}
|
||||
}
|
||||
|
||||
bool ParticleEmitterFunction::SaveSurface(BytesContainer& data)
|
||||
bool ParticleEmitterFunction::SaveSurface(const BytesContainer& data) const
|
||||
{
|
||||
// Wait for asset to be loaded or don't if last load failed
|
||||
if (LastLoadFailed())
|
||||
{
|
||||
LOG(Warning, "Saving asset that failed to load.");
|
||||
}
|
||||
else if (WaitForLoaded())
|
||||
{
|
||||
LOG(Error, "Asset loading failed. Cannot save it.");
|
||||
if (OnCheckSave())
|
||||
return true;
|
||||
}
|
||||
|
||||
ScopeLock lock(Locker);
|
||||
|
||||
// Set Visject Surface data
|
||||
@@ -210,4 +202,17 @@ bool ParticleEmitterFunction::SaveSurface(BytesContainer& data)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ParticleEmitterFunction::Save(const StringView& path)
|
||||
{
|
||||
if (OnCheckSave(path))
|
||||
return true;
|
||||
ScopeLock lock(Locker);
|
||||
MemoryWriteStream writeStream;
|
||||
if (Graph.Save(&writeStream, true))
|
||||
return true;
|
||||
BytesContainer data;
|
||||
data.Link(ToSpan(writeStream));
|
||||
return SaveSurface(data);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,23 +31,21 @@ public:
|
||||
Array<int32, FixedAllocation<16>> Outputs;
|
||||
|
||||
#if COMPILE_WITH_PARTICLE_GPU_GRAPH
|
||||
|
||||
/// <summary>
|
||||
/// The loaded GPU particle function graph.
|
||||
/// </summary>
|
||||
ParticleEmitterGraphGPU GraphGPU;
|
||||
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Tries to load surface graph from the asset.
|
||||
/// </summary>
|
||||
/// <param name="graph">The graph to load.</param>
|
||||
/// <param name="loadMeta">True if load metadata.</param>
|
||||
/// <returns>True if failed, otherwise false.</returns>
|
||||
bool LoadSurface(ParticleEmitterGraphCPU& graph);
|
||||
bool LoadSurface(ParticleEmitterGraphCPU& graph, bool loadMeta = false);
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
/// <summary>
|
||||
/// Tries to load surface graph from the asset.
|
||||
/// </summary>
|
||||
@@ -55,14 +53,12 @@ public:
|
||||
API_FUNCTION() BytesContainer LoadSurface();
|
||||
|
||||
#if COMPILE_WITH_PARTICLE_GPU_GRAPH
|
||||
|
||||
/// <summary>
|
||||
/// Tries to load surface graph from the asset.
|
||||
/// </summary>
|
||||
/// <param name="graph">The graph to load.</param>
|
||||
/// <returns>True if failed, otherwise false.</returns>
|
||||
bool LoadSurface(ParticleEmitterGraphGPU& graph);
|
||||
|
||||
bool LoadSurface(ParticleEmitterGraphGPU& graph) const;
|
||||
#endif
|
||||
|
||||
// Gets the function signature for Visject Surface editor.
|
||||
@@ -73,8 +69,13 @@ public:
|
||||
/// </summary>
|
||||
/// <param name="data">The surface graph data.</param>
|
||||
/// <returns>True if cannot save it, otherwise false.</returns>
|
||||
API_FUNCTION() bool SaveSurface(BytesContainer& data);
|
||||
API_FUNCTION() bool SaveSurface(const BytesContainer& data) const;
|
||||
#endif
|
||||
|
||||
public:
|
||||
// [BinaryAsset]
|
||||
#if USE_EDITOR
|
||||
bool Save(const StringView& path = StringView::Empty) override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "ParticleEffect.h"
|
||||
#include "Engine/Core/Types/CommonValue.h"
|
||||
#include "Engine/Level/Level.h"
|
||||
#include "Engine/Content/Deprecated.h"
|
||||
#include "Engine/Content/Factories/BinaryAssetFactory.h"
|
||||
#include "Engine/Serialization/MemoryReadStream.h"
|
||||
#include "Engine/Serialization/MemoryWriteStream.h"
|
||||
@@ -46,7 +47,7 @@ void ParticleSystem::Init(ParticleEmitter* emitter, float duration, float fps)
|
||||
}
|
||||
}
|
||||
|
||||
BytesContainer ParticleSystem::LoadTimeline()
|
||||
BytesContainer ParticleSystem::LoadTimeline() const
|
||||
{
|
||||
BytesContainer result;
|
||||
ScopeLock lock(Locker);
|
||||
@@ -108,25 +109,16 @@ BytesContainer ParticleSystem::LoadTimeline()
|
||||
}
|
||||
|
||||
// Set output data
|
||||
result.Copy(stream.GetHandle(), stream.GetPosition());
|
||||
result.Copy(ToSpan(stream));
|
||||
return result;
|
||||
}
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
bool ParticleSystem::SaveTimeline(BytesContainer& data)
|
||||
bool ParticleSystem::SaveTimeline(const BytesContainer& data) const
|
||||
{
|
||||
// Wait for asset to be loaded or don't if last load failed (eg. by shader source compilation error)
|
||||
if (LastLoadFailed())
|
||||
{
|
||||
LOG(Warning, "Saving asset that failed to load.");
|
||||
}
|
||||
else if (WaitForLoaded())
|
||||
{
|
||||
LOG(Error, "Asset loading failed. Cannot save it.");
|
||||
if (OnCheckSave())
|
||||
return true;
|
||||
}
|
||||
|
||||
ScopeLock lock(Locker);
|
||||
|
||||
// Release all chunks
|
||||
@@ -197,6 +189,15 @@ void ParticleSystem::GetReferences(Array<Guid>& assets, Array<String>& files) co
|
||||
}
|
||||
}
|
||||
|
||||
bool ParticleSystem::Save(const StringView& path)
|
||||
{
|
||||
if (OnCheckSave(path))
|
||||
return true;
|
||||
ScopeLock lock(Locker);
|
||||
BytesContainer data = LoadTimeline();
|
||||
return SaveTimeline(data);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Asset::LoadResult ParticleSystem::load()
|
||||
@@ -225,6 +226,7 @@ Asset::LoadResult ParticleSystem::load()
|
||||
case 1:
|
||||
{
|
||||
// [Deprecated on 23.07.2019, expires on 27.04.2021]
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
|
||||
// Load properties
|
||||
stream.ReadFloat(&FramesPerSecond);
|
||||
@@ -299,6 +301,7 @@ Asset::LoadResult ParticleSystem::load()
|
||||
case 2:
|
||||
{
|
||||
// [Deprecated on 31.07.2020, expires on 31.07.2022]
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
|
||||
// Load properties
|
||||
stream.ReadFloat(&FramesPerSecond);
|
||||
@@ -372,6 +375,7 @@ Asset::LoadResult ParticleSystem::load()
|
||||
}
|
||||
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
||||
case 3: // [Deprecated on 03.09.2021 expires on 03.09.2023]
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
case 4:
|
||||
{
|
||||
// Load properties
|
||||
|
||||
@@ -156,17 +156,15 @@ public:
|
||||
/// Loads the serialized timeline data.
|
||||
/// </summary>
|
||||
/// <returns>The output surface data, or empty if failed to load.</returns>
|
||||
API_FUNCTION() BytesContainer LoadTimeline();
|
||||
API_FUNCTION() BytesContainer LoadTimeline() const;
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
/// <summary>
|
||||
/// Saves the serialized timeline data to the asset.
|
||||
/// </summary>
|
||||
/// <param name="data">The timeline data container.</param>
|
||||
/// <returns><c>true</c> failed to save data; otherwise, <c>false</c>.</returns>
|
||||
API_FUNCTION() bool SaveTimeline(BytesContainer& data);
|
||||
|
||||
API_FUNCTION() bool SaveTimeline(const BytesContainer& data) const;
|
||||
#endif
|
||||
|
||||
public:
|
||||
@@ -243,6 +241,7 @@ public:
|
||||
void InitAsVirtual() override;
|
||||
#if USE_EDITOR
|
||||
void GetReferences(Array<Guid>& assets, Array<String>& files) const override;
|
||||
bool Save(const StringView& path = StringView::Empty) override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "WheeledVehicle.h"
|
||||
#include "Engine/Physics/Physics.h"
|
||||
#include "Engine/Level/Scene/Scene.h"
|
||||
#include "Engine/Physics/Physics.h"
|
||||
#include "Engine/Physics/PhysicsBackend.h"
|
||||
#include "Engine/Physics/PhysicsScene.h"
|
||||
#include "Engine/Content/Deprecated.h"
|
||||
#include "Engine/Serialization/Serialization.h"
|
||||
#if USE_EDITOR
|
||||
#include "Engine/Level/Scene/SceneRendering.h"
|
||||
@@ -476,7 +477,11 @@ void WheeledVehicle::Deserialize(DeserializeStream& stream, ISerializeModifier*
|
||||
DESERIALIZE_MEMBER(AntiRollBars, _antiRollBars);
|
||||
|
||||
// [Deprecated on 13.06.2023, expires on 13.06.2025]
|
||||
_fixInvalidForwardDir |= modifier->EngineBuild < 6341;
|
||||
if (modifier->EngineBuild < 6341)
|
||||
{
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
_fixInvalidForwardDir = true;
|
||||
}
|
||||
}
|
||||
|
||||
void WheeledVehicle::OnColliderChanged(Collider* c)
|
||||
|
||||
@@ -167,18 +167,8 @@ bool FontAsset::Init(const BytesContainer& fontFile)
|
||||
|
||||
bool FontAsset::Save(const StringView& path)
|
||||
{
|
||||
// Validate state
|
||||
if (WaitForLoaded())
|
||||
{
|
||||
LOG(Error, "Asset loading failed. Cannot save it.");
|
||||
if (OnCheckSave(path))
|
||||
return true;
|
||||
}
|
||||
if (IsVirtual() && path.IsEmpty())
|
||||
{
|
||||
LOG(Error, "To save virtual asset asset you need to specify the target asset path location.");
|
||||
return true;
|
||||
}
|
||||
|
||||
ScopeLock lock(Locker);
|
||||
|
||||
AssetInitData data;
|
||||
|
||||
@@ -166,15 +166,6 @@ public:
|
||||
/// <returns>True if cannot init, otherwise false.</returns>
|
||||
API_FUNCTION() bool Init(const BytesContainer& fontFile);
|
||||
|
||||
#if USE_EDITOR
|
||||
/// <summary>
|
||||
/// Saves this asset to the file. Supported only in Editor.
|
||||
/// </summary>
|
||||
/// <param name="path">The custom asset path to use for the saving. Use empty value to save this asset to its own storage location. Can be used to duplicate asset. Must be specified when saving virtual asset.</param>
|
||||
/// <returns>True if cannot save data, otherwise false.</returns>
|
||||
API_FUNCTION() bool Save(const StringView& path = StringView::Empty);
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Check if the font contains the glyph of a char.
|
||||
/// </summary>
|
||||
@@ -190,6 +181,9 @@ public:
|
||||
public:
|
||||
// [BinaryAsset]
|
||||
uint64 GetMemoryUsage() const override;
|
||||
#if USE_EDITOR
|
||||
bool Save(const StringView& path = StringView::Empty) override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
// [BinaryAsset]
|
||||
|
||||
@@ -285,9 +285,11 @@ DateTime JsonTools::GetDateTime(const Value& value)
|
||||
}
|
||||
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||
#include "Engine/Content/Deprecated.h"
|
||||
CommonValue JsonTools::GetCommonValue(const Value& value)
|
||||
{
|
||||
// [Deprecated on 31.07.2020, expires on 31.07.2022]
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
CommonValue result;
|
||||
const auto typeMember = value.FindMember("Type");
|
||||
const auto valueMember = value.FindMember("Value");
|
||||
|
||||
@@ -7,13 +7,14 @@
|
||||
#include "Engine/Level/Scene/SceneRendering.h"
|
||||
#include "Engine/Serialization/Serialization.h"
|
||||
#include "Engine/Physics/Physics.h"
|
||||
#include "Engine/Physics/PhysicsScene.h"
|
||||
#include "Engine/Physics/PhysicalMaterial.h"
|
||||
#include "Engine/Physics/PhysicsBackend.h"
|
||||
#include "Engine/Content/Deprecated.h"
|
||||
#include "Engine/Graphics/RenderView.h"
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
#include "Engine/Graphics/Textures/GPUTexture.h"
|
||||
#include "Engine/Level/Scene/Scene.h"
|
||||
#include "Engine/Physics/PhysicsScene.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#include "Engine/Renderer/GlobalSignDistanceFieldPass.h"
|
||||
#include "Engine/Renderer/GI/GlobalSurfaceAtlasPass.h"
|
||||
@@ -810,16 +811,23 @@ void Terrain::Deserialize(DeserializeStream& stream, ISerializeModifier* modifie
|
||||
|
||||
// [Deprecated on 07.02.2022, expires on 07.02.2024]
|
||||
if (modifier->EngineBuild <= 6330)
|
||||
{
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
DrawModes |= DrawPass::GlobalSDF;
|
||||
}
|
||||
// [Deprecated on 27.04.2022, expires on 27.04.2024]
|
||||
if (modifier->EngineBuild <= 6331)
|
||||
{
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
DrawModes |= DrawPass::GlobalSurfaceAtlas;
|
||||
}
|
||||
|
||||
// [Deprecated on 15.02.2024, expires on 15.02.2026]
|
||||
JsonAssetReference<PhysicalMaterial> PhysicalMaterial;
|
||||
DESERIALIZE(PhysicalMaterial);
|
||||
if (PhysicalMaterial)
|
||||
{
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
for (auto& e : _physicalMaterials)
|
||||
e = PhysicalMaterial;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "Engine/Serialization/Serialization.h"
|
||||
#include "Engine/Content/Assets/MaterialInstance.h"
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/Content/Deprecated.h"
|
||||
#include "Engine/Core/Types/Variant.h"
|
||||
#include "Engine/Graphics/RenderTools.h"
|
||||
#include "Engine/Graphics/Shaders/GPUVertexLayout.h"
|
||||
@@ -482,10 +483,16 @@ void TextRender::Deserialize(DeserializeStream& stream, ISerializeModifier* modi
|
||||
|
||||
// [Deprecated on 07.02.2022, expires on 07.02.2024]
|
||||
if (modifier->EngineBuild <= 6330)
|
||||
{
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
DrawModes |= DrawPass::GlobalSDF;
|
||||
}
|
||||
// [Deprecated on 27.04.2022, expires on 27.04.2024]
|
||||
if (modifier->EngineBuild <= 6331)
|
||||
{
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
DrawModes |= DrawPass::GlobalSurfaceAtlas;
|
||||
}
|
||||
|
||||
_isDirty = true;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "VisjectMeta.h"
|
||||
#include "GraphNode.h"
|
||||
#include "GraphParameter.h"
|
||||
#include "Engine/Content/Deprecated.h"
|
||||
#include "Engine/Serialization/ReadStream.h"
|
||||
#include "Engine/Serialization/WriteStream.h"
|
||||
|
||||
@@ -183,6 +184,7 @@ public:
|
||||
if (version < 7000)
|
||||
{
|
||||
// [Deprecated on 31.07.2020, expires on 31.07.2022]
|
||||
MARK_CONTENT_DEPRECATED();
|
||||
|
||||
// Time saved
|
||||
int64 timeSaved;
|
||||
|
||||
Reference in New Issue
Block a user