From 0794ab4ee59c7d57515cc487f6d6dc199eca17aa Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 20 Jul 2021 16:32:55 +0200 Subject: [PATCH] Add support for bundling custom assets by `GamePlugins` --- Source/Editor/Cooker/GameCooker.cpp | 34 ++++++++++++++++++- Source/Editor/Cooker/GameCooker.cs | 30 ++++++++++++++-- Source/Editor/Cooker/GameCooker.h | 7 ++-- Source/Editor/Cooker/Steps/DeployDataStep.cpp | 4 +++ Source/Engine/Scripting/Plugins/GamePlugin.cs | 9 +++++ 5 files changed, 78 insertions(+), 6 deletions(-) diff --git a/Source/Editor/Cooker/GameCooker.cpp b/Source/Editor/Cooker/GameCooker.cpp index d9525b28e..fddd63a78 100644 --- a/Source/Editor/Cooker/GameCooker.cpp +++ b/Source/Editor/Cooker/GameCooker.cpp @@ -26,6 +26,7 @@ #include "Engine/Scripting/ManagedCLR/MAssembly.h" #include "Engine/Content/JsonAsset.h" #include "Engine/Content/AssetReference.h" +#include "Engine/Scripting/MException.h" #if PLATFORM_TOOLS_WINDOWS #include "Platform/Windows/WindowsPlatformTools.h" #include "Engine/Platform/Windows/WindowsPlatformSettings.h" @@ -55,7 +56,7 @@ namespace GameCookerImpl { MMethod* Internal_OnEvent = nullptr; MMethod* Internal_OnProgress = nullptr; - MMethod* Internal_CanDeployPlugin = nullptr; + MMethod* Internal_OnCollectAssets = nullptr; bool IsRunning = false; bool IsThreadRunning = false; @@ -77,6 +78,7 @@ namespace GameCookerImpl void CallEvent(GameCooker::EventType type); void ReportProgress(const String& info, float totalProgress); + void OnCollectAssets(HashSet& assets); bool Build(); int32 ThreadFunction(); @@ -84,6 +86,7 @@ namespace GameCookerImpl { Internal_OnEvent = nullptr; Internal_OnProgress = nullptr; + Internal_OnCollectAssets = nullptr; } } @@ -91,6 +94,7 @@ using namespace GameCookerImpl; Delegate GameCooker::OnEvent; Delegate GameCooker::OnProgress; +Delegate&> GameCooker::OnCollectAssets; const Char* ToString(const BuildPlatform platform) { @@ -415,6 +419,33 @@ void GameCookerImpl::ReportProgress(const String& info, float totalProgress) ProgressValue = totalProgress; } +void GameCookerImpl::OnCollectAssets(HashSet& assets) +{ + if (Internal_OnCollectAssets == nullptr) + { + auto c = GameCooker::GetStaticClass(); + if (c) + Internal_OnCollectAssets = c->GetMethod("Internal_OnCollectAssets", 0); + ASSERT(GameCookerImpl::Internal_OnCollectAssets); + } + + MCore::AttachThread(); + MonoObject* exception = nullptr; + auto list = (MonoArray*)Internal_OnCollectAssets->Invoke(nullptr, nullptr, &exception); + if (exception) + { + MException ex(exception); + ex.Log(LogType::Error, TEXT("OnCollectAssets")); + } + + if (list) + { + auto ids = MUtils::ToSpan(list); + for (int32 i = 0; i < ids.Length(); i++) + assets.Add(ids[i]); + } +} + bool GameCookerImpl::Build() { CookingData& data = Data; @@ -511,6 +542,7 @@ bool GameCookerService::Init() { auto editorAssembly = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly; editorAssembly->Unloading.Bind(OnEditorAssemblyUnloading); + GameCooker::OnCollectAssets.Bind(OnCollectAssets); return false; } diff --git a/Source/Editor/Cooker/GameCooker.cs b/Source/Editor/Cooker/GameCooker.cs index 91741e074..64b84a9ac 100644 --- a/Source/Editor/Cooker/GameCooker.cs +++ b/Source/Editor/Cooker/GameCooker.cs @@ -1,9 +1,7 @@ // Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. using System; -using System.Linq; -using System.Reflection; -using System.Runtime.CompilerServices; +using System.Collections.Generic; using FlaxEngine; namespace FlaxEditor @@ -80,6 +78,11 @@ namespace FlaxEditor /// public static event BuildProgressDelegate Progress; + /// + /// Occurs when building collects assets to cook. + /// + public static event Action> CollectAssets; + /// /// Gets the type of the platform from the game build platform type. /// @@ -96,6 +99,9 @@ namespace FlaxEditor case BuildPlatform.XboxOne: return PlatformType.XboxOne; case BuildPlatform.LinuxX64: return PlatformType.Linux; case BuildPlatform.PS4: return PlatformType.PS4; + case BuildPlatform.AndroidARM64: return PlatformType.Android; + case BuildPlatform.XboxScarlett: return PlatformType.XboxScarlett; + case BuildPlatform.Switch: return PlatformType.Switch; default: throw new ArgumentOutOfRangeException(nameof(buildPlatform), buildPlatform, null); } } @@ -109,5 +115,23 @@ namespace FlaxEditor { Progress?.Invoke(info, totalProgress); } + + internal static Guid[] Internal_OnCollectAssets() + { + var list = new List(); + + // Custom assets + CollectAssets?.Invoke(list); + + // Plugin assets + foreach (var plugin in PluginManager.GamePlugins) + { + plugin.OnCollectAssets(list); + } + + if (list.Count == 0) + return null; + return list.ToArray(); + } } } diff --git a/Source/Editor/Cooker/GameCooker.h b/Source/Editor/Cooker/GameCooker.h index f1bfc4ad3..075bf79b4 100644 --- a/Source/Editor/Cooker/GameCooker.h +++ b/Source/Editor/Cooker/GameCooker.h @@ -61,13 +61,11 @@ public: /// /// Determines whether game building is running. /// - /// true if game building is running; otherwise, false. API_PROPERTY() static bool IsRunning(); /// /// Determines whether building cancel has been requested. /// - /// true if building cancel has been requested; otherwise, false. API_PROPERTY() static bool IsCancelRequested(); /// @@ -123,4 +121,9 @@ public: /// Occurs when building game progress fires. /// static Delegate OnProgress; + + /// + /// Occurs when building collects assets to cook. + /// + static Delegate&> OnCollectAssets; }; diff --git a/Source/Editor/Cooker/Steps/DeployDataStep.cpp b/Source/Editor/Cooker/Steps/DeployDataStep.cpp index 17ddbf73c..835fdc8e8 100644 --- a/Source/Editor/Cooker/Steps/DeployDataStep.cpp +++ b/Source/Editor/Cooker/Steps/DeployDataStep.cpp @@ -101,6 +101,10 @@ bool DeployDataStep::Perform(CookingData& data) if (data.Configuration != BuildConfiguration::Release) data.AddRootEngineAsset(TEXT("Editor/Fonts/Roboto-Regular")); + // Register custom assets (eg. plugins) + data.StepProgress(TEXT("Deploying custom data"), 30); + GameCooker::OnCollectAssets(data.RootAssets); + // Register game assets data.StepProgress(TEXT("Deploying game data"), 50); auto& buildSettings = *BuildSettings::Get(); diff --git a/Source/Engine/Scripting/Plugins/GamePlugin.cs b/Source/Engine/Scripting/Plugins/GamePlugin.cs index 84dfc7b1a..d5f6184d3 100644 --- a/Source/Engine/Scripting/Plugins/GamePlugin.cs +++ b/Source/Engine/Scripting/Plugins/GamePlugin.cs @@ -11,5 +11,14 @@ namespace FlaxEngine /// public abstract class GamePlugin : Plugin { +#if FLAX_EDITOR + /// + /// Event called during game cooking in Editor to collect any assets that this plugin uses. Can be used to inject content for plugins. + /// + /// The result assets list (always valid). + public virtual void OnCollectAssets(System.Collections.Generic.List assets) + { + } +#endif } }