Polyphase Game Engine
Loading...
Searching...
No Matches
AddonsWindow.h
Go to the documentation of this file.
1#pragma once
2
3#if EDITOR
4
5#include <string>
6#include <vector>
7#include <unordered_map>
8
9#include "imgui.h"
10
11struct Addon;
12struct InstalledAddon;
13
22class AddonsWindow
23{
24public:
25 AddonsWindow();
26 ~AddonsWindow();
27
28 void Open();
29 void Close();
30 void Draw();
31 bool IsOpen() const { return mIsOpen; }
32
33 // Drop the thumbnail path memo and ask the shared EditorImageCache to
34 // forget our entries. Called from EditorImguiPreShutdown; the GPU release
35 // itself is the cache's business.
36 void Shutdown();
37
38 // Queue an addon for download + install by id. Used by the native addon
39 // problem modal's "Install <dependency>" button and the Installed tab.
40 // The work itself happens in ProcessPendingInstalls.
41 void InstallAddonById(const std::string& addonId);
42
43 // Drain EditorState::mPendingAddonInstalls. Called by EditorMain's
44 // end-of-frame dispatcher (never from inside an ImGui frame): downloads
45 // and installs each queued addon under an EditorProgress modal, refreshes
46 // the registry first if this session has not, registers any new native
47 // package with NativeAddonManager, re-checks addons that were blocked on
48 // a missing dependency, and finally reloads the affected native addons
49 // through the project-restart path so they get compiled.
50 void ProcessPendingInstalls();
51
52 // Drain EditorState::mPendingAddonUninstalls (queued dependents-first by
53 // the Remove modal). Pure Lua/asset addons are deleted under an
54 // EditorProgress modal and the Packages asset dir rescanned; if any
55 // queued addon's DLL is loaded, the whole batch goes through
56 // NativeAddonManager::RemoveNativeAddonsWithProjectRestart instead.
57 void ProcessPendingUninstalls();
58
59 // Drain EditorState::mCheckAddonUpdatesAtEndOfFrame: refresh the registry
60 // and query each installed addon's branch head under EditorProgress.
61 void ProcessPendingUpdateCheck();
62
63private:
64 void DrawAddonBrowser();
65 void DrawInstalledAddons();
66 void DrawRepositoryManager();
67 void DrawAddonCard(const Addon& addon, float cardWidth);
68 void DrawAddonDetailsPopup();
69 void DrawAddRepoPopup();
70
71 // Table-view + shared helpers
72 void DrawViewModeToggle();
73 void DrawAddonTable_Browse(const std::vector<const Addon*>& filtered);
74 void DrawAddonTable_Installed(const std::vector<InstalledAddon>& installed);
75 void DrawClampedName(const char* name, float maxWidth);
76 void LoadViewSettings();
77 void SaveViewSettings();
78
79 void OnDownloadAddon(const std::string& addonId);
80 void OnViewMore(const std::string& addonId);
81 // Queue the confirmed removal set (dependents first, target last).
82 void OnUninstallAddon(const std::string& addonId);
83 // Compute dependents + native involvement for the Remove modal.
84 void RequestUninstall(const std::string& addonId);
85 // Open the Update confirm modal (files in Packages/<id> get replaced).
86 void RequestUpdate(const std::string& addonId);
87 void DrawUpdateConfirmPopup();
88 // "Up to date" / "New commits" / ... word with tooltip, from GetUpdateStatus.
89 void DrawUpdateStatusLabel(const std::string& addonId);
90
91 // Git-repo helpers for the per-row "Open in Version Control" /
92 // "Init Git" actions. HasGitRepo does a libgit2 discover under the
93 // hood (filesystem walk) — caching per row avoids re-running it every
94 // frame across the full installed-addon list. Cache invalidates when
95 // the active project changes.
96 bool DoesAddonHaveGitRepo(const std::string& addonId);
97 void InvalidateAddonGitRepoCacheIfProjectChanged();
98 std::string GetAddonDirectory(const std::string& addonId) const;
99 void OpenAddonInVersionControl(const std::string& addonId);
100 void InitAddonGitRepo(const std::string& addonId);
101 void OnAddRepository();
102 void OnRemoveRepository(const std::string& url);
103 void OnRefreshRepositories();
104 void OnResolveDependencies();
105
106 // Native addon operations
107 void OnBuildNativeAddon(const std::string& addonId);
108 void OnReloadNativeAddon(const std::string& addonId);
109 void OnToggleNativeEnabled(const std::string& addonId);
110 void OnToggleNativeMode(const std::string& addonId);
111 void OnSyncNativeAddonBinary(const std::string& addonId);
112
113 bool mIsOpen = false;
114 int mSelectedTab = 0; // 0=Browse, 1=Installed, 2=Repositories
115
116 // View mode: true = table (default), false = cards. Persisted to disk via JsonSettings.
117 bool mUseTableView = true;
118
119 // Popup state
120 bool mShowAddonDetails = false;
121 bool mShowAddRepoPopup = false;
122 std::string mSelectedAddonId;
123 char mRepoUrlBuffer[512] = {};
124 std::string mErrorMessage;
125 std::string mStatusMessage;
126
127 // Filter
128 char mSearchBuffer[256] = {};
129 std::vector<std::string> mSelectedTags;
130 std::string mSelectedCategory; // empty = "All"
131
132 // Available tags (collected from addons)
133 std::vector<std::string> mAvailableTags;
134
135 // Refresh state
136 bool mNeedsRefresh = true;
137 bool mIsRefreshing = false;
138
139 // Remove confirmation. The row buttons run inside table/PushID scopes,
140 // so they only fill these in; DrawUninstallConfirmPopup issues
141 // OpenPopup + BeginPopupModal together at root level.
142 bool mShowUninstallConfirm = false;
143 bool mUninstallPopupRequested = false;
144 std::string mUninstallAddonId;
145 std::vector<std::string> mUninstallDependents; // installed, removal order
146 std::vector<std::string> mUninstallLocalDependents; // in Packages/ with no record; left alone
147 bool mUninstallNeedsRestart = false; // a queued addon's DLL is loaded
148 void DrawUninstallConfirmPopup();
149
150 // Update confirmation
151 bool mShowUpdateConfirm = false;
152 bool mUpdatePopupRequested = false;
153 std::string mUpdateAddonId;
154 bool mUpdateAddonHasOwnRepo = false;
155
156 // Build log popup
157 bool mShowBuildLog = false;
158 std::string mBuildLogAddonId;
159
160 // Thumbnail path memo: addonId -> resolved absolute PNG path ("" when the
161 // addon has none). The decoded texture lives in the shared
162 // EditorImageCache, which owns it for the editor session; this map only
163 // memoizes the two-location path search so we don't stat the filesystem
164 // once per card per frame.
165 ImTextureID GetAddonThumbnail(const std::string& addonId);
166 void ClearThumbnailCache();
167 std::unordered_map<std::string, std::string> mThumbnailPaths;
168
169 // Per-addon "is this dir inside a git repo" cache. Keyed by addonId
170 // (the Packages/ subdir name). Cleared on project switch.
171 std::unordered_map<std::string, bool> mAddonGitRepoCache;
172 std::string mGitRepoCacheProjectDir;
173};
174
175AddonsWindow* GetAddonsWindow();
176
177#endif
void Shutdown()
Definition Engine.cpp:1298