15#include <unordered_map>
16#include <unordered_set>
26struct NativeAddonCreateInfo
31 std::string mDescription;
32 std::string mVersion =
"1.0.0";
33 NativeAddonTarget mTarget = NativeAddonTarget::EngineAndEditor;
34 std::string mBinaryName;
40struct NativeAddonPackageOptions
43 bool mIncludeSource =
true;
44 bool mIncludeAssets =
true;
45 bool mIncludeScripts =
true;
46 bool mIncludeThumbnail =
true;
47 std::string mOutputPath;
53struct NativeAddonState
56 std::string mSourcePath;
57 std::string mLoadedPath;
58 void* mModuleHandle =
nullptr;
66 uintptr_t mModuleBase = 0;
67 uintptr_t mModuleEnd = 0;
68 std::string mFingerprint;
74 std::string mShadowDir;
77 bool mBuildInProgress =
false;
78 bool mBuildSucceeded =
false;
79 std::string mBuildLog;
80 std::string mBuildError;
89 std::vector<std::string> mMissingDependencies;
93 bool mDescValid =
false;
96 NativeModuleMetadata mNativeMetadata;
99 ContentMetadata mContentMetadata;
102 NativeAddonResolveMode mActiveResolveMode = NativeAddonResolveMode::Source;
103 bool mLoadedFromBinary =
false;
104 std::string mBinaryStatus;
111 std::vector<uint64_t> mPurgedAssetUuids;
116 bool mBuildFailureAcknowledged =
false;
128class NativeAddonManager
131 static void Create();
133 static NativeAddonManager*
Get();
140 void DiscoverNativeAddons();
145 std::vector<std::string> GetDiscoveredAddonIds()
const;
156 bool BuildNativeAddon(
const std::string& addonId, std::string& outError);
164 std::string ComputeFingerprint(
const std::string& addonId);
172 bool NeedsBuild(
const std::string& addonId);
176 void WriteAddonBuildMeta(
const std::string& outputPath,
177 const std::string& fingerprint);
180 NativeAddonResolveMode ResolveModeForAddon(
const std::string& addonId)
const;
183 bool ResolveBinaryModulePath(
const std::string& addonId, std::string& outModulePath, std::string& outStatus, std::string& outError);
186 bool IsBinaryDescriptorCompatible(
const NativeBinaryDescriptor& descriptor,
const NativeAddonState& state)
const;
191 bool MetaIndicatesRebuildNeeded(
const std::string& outputPath)
const;
203 bool LoadNativeAddon(
const std::string& addonId, std::string& outError);
211 bool UnloadNativeAddon(
const std::string& addonId);
220 bool ReloadNativeAddon(
const std::string& addonId, std::string& outError);
227 void ReloadAllNativeAddons();
238 void UnloadAllNativeAddons();
262 bool RecoverFromStuckAddons(
const char* reason);
273 void TickAsyncBuilds();
276 bool IsBuildingAsync()
const;
279 int GetAsyncBuildTotal()
const;
282 int GetAsyncBuildIndex()
const;
285 std::string GetAsyncBuildAddonId()
const;
289 std::string GetAsyncBuildOutput()
const;
302 bool mActive =
false;
303 std::string mAddonId;
304 std::vector<std::string> mLockedFiles;
308 std::string mIntermediateDir;
316 bool IsBuildBlocked()
const {
return mBlocked.mActive; }
317 const BuildBlocked& GetBuildBlocked()
const {
return mBlocked; }
321 void RetryBlockedBuild();
323 void CancelBlockedBuild();
336 struct BuildFailureEntry
338 std::string mAddonId;
341 std::string mFixHint;
343 std::vector<std::string> mMissingDependencies;
345 std::vector<BuildFailureEntry> GetActiveBuildFailures()
const;
346 bool HasUnacknowledgedBuildFailures()
const;
347 void DismissBuildFailure(
const std::string& addonId);
348 void DismissAllBuildFailures();
351 void RetryFailedBuild(
const std::string& addonId);
360 static std::string ResolveVulkanIncludeDir();
362 struct BuildFailureHint
366 std::string mDependencyId;
369 static BuildFailureHint ClassifyBuildFailure(
const std::string& log);
375 bool DiscoverAddonPackage(
const std::string& addonId);
381 std::vector<std::string> RefreshMissingDependencies();
405 enum class ProjectRestartPhase
414 struct ProjectRestart
416 ProjectRestartPhase mPhase = ProjectRestartPhase::None;
420 std::vector<std::string> mTargetAddons;
423 bool mForceRebuild =
false;
428 std::vector<std::string> mRemoveAddons;
429 bool mIsRemoval =
false;
432 std::string mProjectPath;
433 std::vector<std::string> mOpenSceneNames;
434 std::string mActiveSceneName;
437 std::vector<std::string> mDirtyScenes;
438 int32_t mDirtyCursor = 0;
441 bool IsProjectRestartActive()
const {
return mRestart.mPhase != ProjectRestartPhase::None; }
442 const ProjectRestart& GetProjectRestart()
const {
return mRestart; }
448 void ReloadNativeAddonsWithProjectRestart(
const std::vector<std::string>& addonIds,
459 bool RemoveNativeAddonsWithProjectRestart(
const std::vector<std::string>& removeIds,
465 void ForgetAddon(
const std::string& addonId);
470 void ProjectRestartConfirm();
471 void ProjectRestartCancel();
472 void ProjectRestartDirtySave();
473 void ProjectRestartDirtyDiscard();
474 void ProjectRestartDirtyCancel();
484 void TickAllPlugins(
float deltaTime);
494 void TickEditorAllPlugins(
float deltaTime);
499 void CallOnEditorPreInit();
504 void CallOnEditorReady();
514 const NativeAddonState* GetState(
const std::string& addonId)
const;
519 bool IsLoaded(
const std::string& addonId)
const;
527 std::string GetAddonSourcePath(
const std::string& addonId)
const;
541 std::string FindAddonRootForBuildTarget(
const std::string& buildTargetId)
const;
546 std::vector<NativeAddonState> GetEngineAddons()
const;
565 const char* FindAddonIdForFactory(
const void* factoryPtr)
const;
583 bool CreateNativeAddon(
const NativeAddonCreateInfo& info, std::string& outError, std::string* outPath =
nullptr);
597 bool CreateNativeAddonAtPath(
const NativeAddonCreateInfo& info,
const std::string& targetDir,
598 std::string& outError, std::string* outPath =
nullptr);
609 bool PackageNativeAddon(
const NativeAddonPackageOptions& options, std::string& outError);
619 bool GenerateIDEConfig(
const std::string& addonPath);
624 std::vector<std::string> GetLocalPackageIds()
const;
634 static bool GenerateAddonIncludesManifest();
643 static bool LoadAddonIncludesManifest(std::vector<std::string>& outIncludePaths,
644 std::vector<std::string>& outDefines);
647 static NativeAddonManager* sInstance;
648 NativeAddonManager();
649 ~NativeAddonManager();
652 void ScanLocalPackages();
653 void ScanInstalledAddons();
654 bool ParsePackageJson(
const std::string& path, NativeModuleMetadata& outMetadata, ContentMetadata* outContent =
nullptr);
659 std::vector<std::string> GetLoadOrder()
const;
662 std::vector<std::string> mCachedLoadOrder;
665 std::string GetIntermediateDir(
const std::string& addonId);
666 std::string GetOutputPath(
const std::string& addonId,
const std::string& fingerprint);
671 bool RunBuildPreflight(
const std::string& addonId, std::string& outError,
672 BuildFailureHint& outHint);
674 bool GenerateBuildScript(
const std::string& addonId,
const std::string& outputDir,
675 const std::string& outputPath, std::string& outScriptPath);
676 std::vector<std::string> GatherSourceFiles(
const std::string& sourceDir);
684 std::vector<std::string> TryClearAddonIntermediates(
const std::string& addonId);
687 void InitializeEngineAPI();
690 std::string GenerateIdFromName(
const std::string& name);
691 bool WriteTemplateSourceFile(
const std::string& path,
const std::string& addonName,
692 const std::string& binaryName);
693 bool WritePackageJson(
const std::string& path,
const NativeAddonCreateInfo& info);
694 bool WriteVSCodeConfig(
const std::string& addonPath);
695 bool WriteCMakeLists(
const std::string& addonPath,
const std::string& binaryName);
696 bool WriteVSProject(
const std::string& addonPath,
const std::string& addonName,
697 const std::string& binaryName);
699 std::unordered_map<std::string, NativeAddonState> mStates;
709 std::string mShadowSessionId;
710 std::vector<std::string> mPendingShadowDeletes;
715 float mShadowDeleteRetryTimer = 0.0f;
716 int mShadowDeleteRetryCount = 0;
717 void RetryPendingShadowDeletes(
float deltaTime);
719 std::string GetShadowCopyDir(
const std::string& addonId,
720 const std::string& fingerprint);
721 bool StageShadowCopy(
const std::string& sourceModulePath,
722 const std::string& shadowDir,
723 std::string& outShadowModulePath,
724 std::string& outError);
725 void TryDeleteShadowDir(
const std::string& dir);
726 void SweepStaleShadowCopies();
735 struct AsyncAddonBuild
738 std::string scriptPath;
739 std::string outputPath;
740 std::string fingerprint;
743 std::atomic<bool> complete{
false};
744 std::atomic<int> exitCode{0};
746 mutable std::mutex outputMutex;
750 std::unique_ptr<AsyncAddonBuild> mActiveBuild;
751 std::vector<std::string> mBuildQueue;
752 int mBuildQueueTotal = 0;
753 int mBuildQueueIndex = 0;
756 BuildBlocked mBlocked;
764 int mPendingRetryCount = 0;
767 ProjectRestart mRestart;
775 std::unordered_set<std::string> mForceSourceForNextLoad;
778 void StartNextQueuedBuild();
779 void FinalizeAsyncBuild(AsyncAddonBuild& job,
bool success);
780 bool LoadNativeAddonAfterBuild(
const std::string& addonId, std::string& outError);
783 bool ProjectRestartStage(
const std::vector<std::string>& addonIds,
784 bool forceRebuild,
const char* reason);
785 void ProjectRestartBeginClose();
786 void ProjectRestartOnBuildsDone();
787 void ProjectRestartReset();
Engine API exposed to native addon plugins.
Stable C ABI header for native addon plugins.
Engine API provided to plugins during OnLoad.
Definition PolyphaseEngineAPI.h:32
Plugin descriptor returned by PolyphasePlugin_GetDesc.
Definition PolyphasePluginAPI.h:75