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;
84 bool mDescValid =
false;
87 NativeModuleMetadata mNativeMetadata;
90 ContentMetadata mContentMetadata;
93 NativeAddonResolveMode mActiveResolveMode = NativeAddonResolveMode::Source;
94 bool mLoadedFromBinary =
false;
95 std::string mBinaryStatus;
102 std::vector<uint64_t> mPurgedAssetUuids;
107 bool mBuildFailureAcknowledged =
false;
119class NativeAddonManager
122 static void Create();
124 static NativeAddonManager*
Get();
131 void DiscoverNativeAddons();
136 std::vector<std::string> GetDiscoveredAddonIds()
const;
147 bool BuildNativeAddon(
const std::string& addonId, std::string& outError);
155 std::string ComputeFingerprint(
const std::string& addonId);
163 bool NeedsBuild(
const std::string& addonId);
167 void WriteAddonBuildMeta(
const std::string& outputPath,
168 const std::string& fingerprint);
171 NativeAddonResolveMode ResolveModeForAddon(
const std::string& addonId)
const;
174 bool ResolveBinaryModulePath(
const std::string& addonId, std::string& outModulePath, std::string& outStatus, std::string& outError);
177 bool IsBinaryDescriptorCompatible(
const NativeBinaryDescriptor& descriptor,
const NativeAddonState& state)
const;
182 bool MetaIndicatesRebuildNeeded(
const std::string& outputPath)
const;
194 bool LoadNativeAddon(
const std::string& addonId, std::string& outError);
202 bool UnloadNativeAddon(
const std::string& addonId);
211 bool ReloadNativeAddon(
const std::string& addonId, std::string& outError);
218 void ReloadAllNativeAddons();
229 void UnloadAllNativeAddons();
253 bool RecoverFromStuckAddons(
const char* reason);
264 void TickAsyncBuilds();
267 bool IsBuildingAsync()
const;
270 int GetAsyncBuildTotal()
const;
273 int GetAsyncBuildIndex()
const;
276 std::string GetAsyncBuildAddonId()
const;
280 std::string GetAsyncBuildOutput()
const;
293 bool mActive =
false;
294 std::string mAddonId;
295 std::vector<std::string> mLockedFiles;
299 std::string mIntermediateDir;
307 bool IsBuildBlocked()
const {
return mBlocked.mActive; }
308 const BuildBlocked& GetBuildBlocked()
const {
return mBlocked; }
312 void RetryBlockedBuild();
314 void CancelBlockedBuild();
327 struct BuildFailureEntry
329 std::string mAddonId;
333 std::vector<BuildFailureEntry> GetActiveBuildFailures()
const;
334 bool HasUnacknowledgedBuildFailures()
const;
335 void DismissBuildFailure(
const std::string& addonId);
336 void DismissAllBuildFailures();
339 void RetryFailedBuild(
const std::string& addonId);
363 enum class ProjectRestartPhase
372 struct ProjectRestart
374 ProjectRestartPhase mPhase = ProjectRestartPhase::None;
377 std::vector<std::string> mTargetAddons;
380 bool mForceRebuild =
false;
384 std::string mProjectPath;
385 std::vector<std::string> mOpenSceneNames;
386 std::string mActiveSceneName;
389 std::vector<std::string> mDirtyScenes;
390 int32_t mDirtyCursor = 0;
393 bool IsProjectRestartActive()
const {
return mRestart.mPhase != ProjectRestartPhase::None; }
394 const ProjectRestart& GetProjectRestart()
const {
return mRestart; }
400 void ReloadNativeAddonsWithProjectRestart(
const std::vector<std::string>& addonIds,
407 void ProjectRestartConfirm();
408 void ProjectRestartCancel();
409 void ProjectRestartDirtySave();
410 void ProjectRestartDirtyDiscard();
411 void ProjectRestartDirtyCancel();
421 void TickAllPlugins(
float deltaTime);
431 void TickEditorAllPlugins(
float deltaTime);
436 void CallOnEditorPreInit();
441 void CallOnEditorReady();
451 const NativeAddonState* GetState(
const std::string& addonId)
const;
456 bool IsLoaded(
const std::string& addonId)
const;
464 std::string GetAddonSourcePath(
const std::string& addonId)
const;
478 std::string FindAddonRootForBuildTarget(
const std::string& buildTargetId)
const;
483 std::vector<NativeAddonState> GetEngineAddons()
const;
502 const char* FindAddonIdForFactory(
const void* factoryPtr)
const;
520 bool CreateNativeAddon(
const NativeAddonCreateInfo& info, std::string& outError, std::string* outPath =
nullptr);
534 bool CreateNativeAddonAtPath(
const NativeAddonCreateInfo& info,
const std::string& targetDir,
535 std::string& outError, std::string* outPath =
nullptr);
546 bool PackageNativeAddon(
const NativeAddonPackageOptions& options, std::string& outError);
556 bool GenerateIDEConfig(
const std::string& addonPath);
561 std::vector<std::string> GetLocalPackageIds()
const;
571 static bool GenerateAddonIncludesManifest();
580 static bool LoadAddonIncludesManifest(std::vector<std::string>& outIncludePaths,
581 std::vector<std::string>& outDefines);
584 static NativeAddonManager* sInstance;
585 NativeAddonManager();
586 ~NativeAddonManager();
589 void ScanLocalPackages();
590 void ScanInstalledAddons();
591 bool ParsePackageJson(
const std::string& path, NativeModuleMetadata& outMetadata, ContentMetadata* outContent =
nullptr);
596 std::vector<std::string> GetLoadOrder()
const;
599 std::vector<std::string> mCachedLoadOrder;
602 std::string GetIntermediateDir(
const std::string& addonId);
603 std::string GetOutputPath(
const std::string& addonId,
const std::string& fingerprint);
604 bool GenerateBuildScript(
const std::string& addonId,
const std::string& outputDir,
605 const std::string& outputPath, std::string& outScriptPath);
606 std::vector<std::string> GatherSourceFiles(
const std::string& sourceDir);
614 std::vector<std::string> TryClearAddonIntermediates(
const std::string& addonId);
617 void InitializeEngineAPI();
620 std::string GenerateIdFromName(
const std::string& name);
621 bool WriteTemplateSourceFile(
const std::string& path,
const std::string& addonName,
622 const std::string& binaryName);
623 bool WritePackageJson(
const std::string& path,
const NativeAddonCreateInfo& info);
624 bool WriteVSCodeConfig(
const std::string& addonPath);
625 bool WriteCMakeLists(
const std::string& addonPath,
const std::string& binaryName);
626 bool WriteVSProject(
const std::string& addonPath,
const std::string& addonName,
627 const std::string& binaryName);
629 std::unordered_map<std::string, NativeAddonState> mStates;
639 std::string mShadowSessionId;
640 std::vector<std::string> mPendingShadowDeletes;
642 std::string GetShadowCopyDir(
const std::string& addonId,
643 const std::string& fingerprint);
644 bool StageShadowCopy(
const std::string& sourceModulePath,
645 const std::string& shadowDir,
646 std::string& outShadowModulePath,
647 std::string& outError);
648 void TryDeleteShadowDir(
const std::string& dir);
649 void SweepStaleShadowCopies();
658 struct AsyncAddonBuild
661 std::string scriptPath;
662 std::string outputPath;
663 std::string fingerprint;
666 std::atomic<bool> complete{
false};
667 std::atomic<int> exitCode{0};
669 mutable std::mutex outputMutex;
673 std::unique_ptr<AsyncAddonBuild> mActiveBuild;
674 std::vector<std::string> mBuildQueue;
675 int mBuildQueueTotal = 0;
676 int mBuildQueueIndex = 0;
679 BuildBlocked mBlocked;
687 int mPendingRetryCount = 0;
690 ProjectRestart mRestart;
698 std::unordered_set<std::string> mForceSourceForNextLoad;
701 void StartNextQueuedBuild();
702 void FinalizeAsyncBuild(AsyncAddonBuild& job,
bool success);
703 bool LoadNativeAddonAfterBuild(
const std::string& addonId, std::string& outError);
706 void ProjectRestartBeginClose();
707 void ProjectRestartOnBuildsDone();
708 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:67