Skip to content

Commit

Permalink
Merge pull request #20 from RaidcoreGG/dev
Browse files Browse the repository at this point in the history
move addon install to thread
  • Loading branch information
DeltaGW2 authored Feb 12, 2024
2 parents ebeafbd + ca17db1 commit ae0aa56
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 72 deletions.
25 changes: 17 additions & 8 deletions src/GUI/Widgets/Addons/AddonItem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,13 +154,13 @@ namespace GUI
}
}

void AddonItem(LibraryAddon aAddon)
void AddonItem(LibraryAddon* aAddon)
{
float btnHeight = 22.0f * Renderer::Scaling;
float itemWidthScaled = itemWidth * Renderer::Scaling;
float itemHeightScaled = itemHeight * Renderer::Scaling;

std::string sig = std::to_string(aAddon.Signature); // helper for unique chkbxIds
std::string sig = std::to_string(aAddon->Signature); // helper for unique chkbxIds

// initial is explicitly set within the window, therefore all positions should be relative to it
ImVec2 initial = ImGui::GetCursorPos();
Expand All @@ -187,10 +187,10 @@ namespace GUI
ImGui::BeginChild("##AddonItemDescription", ImVec2(descWidth, itemHeightScaled - 12.0f - 12.0f));

ImGui::PushFont(Font);
ImGui::TextColored(ImVec4(1.0f, 0.933f, 0.733f, 1.0f), aAddon.Name.c_str());
ImGui::TextColored(ImVec4(1.0f, 0.933f, 0.733f, 1.0f), aAddon->Name.c_str());
ImGui::PopFont();

ImGui::TextWrapped(aAddon.Description.c_str());
ImGui::TextWrapped(aAddon->Description.c_str());

ImGui::EndChild();
}
Expand All @@ -200,15 +200,24 @@ namespace GUI
ImGui::BeginChild("##AddonItemActions", ImVec2(actionsWidth, itemHeightScaled - 12.0f - 12.0f));

// just check if loaded, if it was not hot-reloadable it would be EAddonState::LoadedLOCKED
if (ImGui::GW2Button(("Install##" + sig).c_str(), ImVec2(btnWidth * ImGui::GetFontSize(), btnHeight)))
if (ImGui::GW2Button(aAddon->IsInstalling ? ("Installing...##" + sig).c_str() : ("Install##" + sig).c_str(), ImVec2(btnWidth * ImGui::GetFontSize(), btnHeight)))
{
Loader::InstallAddon(aAddon);
if (!aAddon->IsInstalling)
{
std::thread([aAddon]()
{
Loader::InstallAddon(aAddon);
aAddon->IsInstalling = false;
Loader::NotifyChanges();
})
.detach();
}
}
if (aAddon.Provider == EUpdateProvider::GitHub && !aAddon.DownloadURL.empty())
if (aAddon->Provider == EUpdateProvider::GitHub && !aAddon->DownloadURL.empty())
{
if (ImGui::GW2Button(("GitHub##" + sig).c_str(), ImVec2(btnWidth * ImGui::GetFontSize(), btnHeight)))
{
ShellExecuteA(0, 0, aAddon.DownloadURL.c_str(), 0, 0, SW_SHOW);
ShellExecuteA(0, 0, aAddon->DownloadURL.c_str(), 0, 0, SW_SHOW);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/GUI/Widgets/Addons/AddonItem.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace GUI
{
void AddonItem(Addon* aAddon);
void AddonItem(LibraryAddon aAddon);
void AddonItem(LibraryAddon* aAddon);
}

#endif
36 changes: 5 additions & 31 deletions src/GUI/Widgets/Addons/AddonsWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,30 +43,6 @@ namespace GUI
TabIndex = 0;
Tab1Hovered = false;
Tab2Hovered = false;

json response = RaidcoreAPI->Get("/addonlibrary");

if (!response.is_null())
{
for (const auto& addon : response)
{
LibraryAddon newAddon;
newAddon.Signature = addon["id"];
newAddon.Name = addon["name"];
newAddon.Description = addon["description"];
newAddon.Provider = GetProvider(addon["download"]);
newAddon.DownloadURL = addon["download"];
AddonLibrary.push_back(newAddon);
}

std::sort(AddonLibrary.begin(), AddonLibrary.end(), [](const LibraryAddon& a, const LibraryAddon& b) {
return a.Name < b.Name;
});
}
else
{
LogWarning(CH_CORE, "Error parsing API response for /addonlibrary.");
}
}

void AddonsWindow::Render()
Expand Down Expand Up @@ -200,18 +176,16 @@ namespace GUI
ImGui::BeginChild("##AddonTabScroll", ImVec2(ImGui::GetWindowContentRegionWidth(), (btnHeight * 1.5f) * -1));

int downloadable = 0;
if (AddonLibrary.size() != 0)
const std::lock_guard<std::mutex> lockLoader(Loader::Mutex);
if (Loader::AddonLibrary.size() != 0)
{
const std::lock_guard<std::mutex> lockLibrary(LibraryMutex); // complete overkill, but why not
const std::lock_guard<std::mutex> lockLoader(Loader::Mutex);

for (auto& libAddon : AddonLibrary)
for (auto& libAddon : Loader::AddonLibrary)
{
bool exists = false;
{
for (auto& [path, addon] : Loader::Addons)
{
if (addon->Definitions != nullptr && addon->Definitions->Signature == libAddon.Signature)
if (addon->Definitions != nullptr && addon->Definitions->Signature == libAddon->Signature)
{
exists = true;
break;
Expand All @@ -226,7 +200,7 @@ namespace GUI
}
}

if (AddonLibrary.size() == 0 || downloadable == 0)
if (Loader::AddonLibrary.size() == 0 || downloadable == 0)
{
ImVec2 windowSize = ImGui::GetWindowSize();
ImVec2 textSize = ImGui::CalcTextSize("There's nothing here.\nMaybe ask your favourite developer to support Nexus!");
Expand Down
3 changes: 0 additions & 3 deletions src/GUI/Widgets/Addons/AddonsWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ namespace GUI
bool Tab1Hovered;
bool Tab2Hovered;

std::mutex LibraryMutex;
std::vector<LibraryAddon> AddonLibrary;

AddonsWindow(std::string aName);
void Render();
};
Expand Down
1 change: 1 addition & 0 deletions src/Loader/LibraryAddon.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

struct LibraryAddon
{
bool IsInstalling = false;
signed int Signature;
std::string Name;
std::string Description;
Expand Down
70 changes: 42 additions & 28 deletions src/Loader/Loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ using json = nlohmann::json;
namespace Loader
{
std::mutex Mutex;
std::vector<LibraryAddon*> AddonLibrary;
std::unordered_map<
std::filesystem::path,
ELoaderAction
Expand Down Expand Up @@ -89,6 +90,30 @@ namespace Loader
return;
}

json response = RaidcoreAPI->Get("/addonlibrary");

if (!response.is_null())
{
for (const auto& addon : response)
{
LibraryAddon* newAddon = new LibraryAddon{};
newAddon->Signature = addon["id"];
newAddon->Name = addon["name"];
newAddon->Description = addon["description"];
newAddon->Provider = GetProvider(addon["download"]);
newAddon->DownloadURL = addon["download"];
AddonLibrary.push_back(newAddon);
}

std::sort(AddonLibrary.begin(), AddonLibrary.end(), [](LibraryAddon* a, LibraryAddon* b) {
return a->Name < b->Name;
});
}
else
{
LogWarning(CH_CORE, "Error parsing API response for /addonlibrary.");
}

LoaderThread = std::thread(ProcessChanges);
LoaderThread.detach();
}
Expand Down Expand Up @@ -888,63 +913,52 @@ namespace Loader

return wasUpdated;
}
void InstallAddon(LibraryAddon aAddon)
void InstallAddon(LibraryAddon* aAddon)
{
/*std::string outName = "addon_" + std::to_string(aAddon.Signature);
std::filesystem::path addonPath = Path::D_GW2_ADDONS / outName;
int i = 0;
while(std::filesystem::exists(addonPath.string() + extDll))
{
addonPath = addonPath.string() + "_" + std::to_string(i);
i++;
}
addonPath = addonPath.string() + extDll;*/
// FIXME: look into the .append func of path and check if adds with a / or just appends the string to maybe simplify this
aAddon->IsInstalling = true;

/* this is all modified duplicate code from update */
std::string baseUrl;
std::string endpoint;

// override provider if none set, but a Raidcore ID is used
if (aAddon.Provider == EUpdateProvider::None && aAddon.Signature > 0)
if (aAddon->Provider == EUpdateProvider::None && aAddon->Signature > 0)
{
aAddon.Provider = EUpdateProvider::Raidcore;
aAddon->Provider = EUpdateProvider::Raidcore;
}

/* setup baseUrl and endpoint */
switch (aAddon.Provider)
switch (aAddon->Provider)
{
case EUpdateProvider::None: return;

case EUpdateProvider::Raidcore:
baseUrl = API_RAIDCORE;
endpoint = "/addons/" + std::to_string(aAddon.Signature);
endpoint = "/addons/" + std::to_string(aAddon->Signature);

break;

case EUpdateProvider::GitHub:
baseUrl = API_GITHUB;
if (aAddon.DownloadURL.empty())
if (aAddon->DownloadURL.empty())
{
LogWarning(CH_LOADER, "Addon %s declares EUpdateProvider::GitHub but has no UpdateLink set.", aAddon.Name);
LogWarning(CH_LOADER, "Addon %s declares EUpdateProvider::GitHub but has no UpdateLink set.", aAddon->Name);
return;
}

endpoint = "/repos" + GetEndpoint(aAddon.DownloadURL) + "/releases"; // "/releases/latest"; // fuck you Sognus
endpoint = "/repos" + GetEndpoint(aAddon->DownloadURL) + "/releases"; // "/releases/latest"; // fuck you Sognus

break;

case EUpdateProvider::Direct:
if (aAddon.DownloadURL.empty())
if (aAddon->DownloadURL.empty())
{
LogWarning(CH_LOADER, "Addon %s declares EUpdateProvider::Direct but has no UpdateLink set.", aAddon.Name);
LogWarning(CH_LOADER, "Addon %s declares EUpdateProvider::Direct but has no UpdateLink set.", aAddon->Name);
return;
}

baseUrl = GetBaseURL(aAddon.DownloadURL);
endpoint = GetEndpoint(aAddon.DownloadURL);
baseUrl = GetBaseURL(aAddon->DownloadURL);
endpoint = GetEndpoint(aAddon->DownloadURL);

if (baseUrl.empty() || endpoint.empty())
{
Expand All @@ -954,13 +968,13 @@ namespace Loader
break;
}

if (EUpdateProvider::Raidcore == aAddon.Provider)
if (EUpdateProvider::Raidcore == aAddon->Provider)
{
LogWarning(CH_LOADER, "Downloading via Raidcore is not implemented yet, due to user-friendly names requiring an API request. If you see this tell the developers about it! Thank you!");
return;
//RaidcoreAPI->Download(addonPath, endpoint + "/download"); // e.g. api.raidcore.gg/addons/17/download
}
else if (EUpdateProvider::GitHub == aAddon.Provider)
else if (EUpdateProvider::GitHub == aAddon->Provider)
{
json response = GitHubAPI->Get(endpoint);

Expand Down Expand Up @@ -1037,7 +1051,7 @@ namespace Loader
return;
}
}
else if (EUpdateProvider::Direct == aAddon.Provider)
else if (EUpdateProvider::Direct == aAddon->Provider)
{
/* prepare client request */
httplib::Client client(baseUrl);
Expand Down Expand Up @@ -1073,7 +1087,7 @@ namespace Loader
}
}

LogInfo(CH_LOADER, "Successfully installed %s.", aAddon.Name);
LogInfo(CH_LOADER, "Successfully installed %s.", aAddon->Name);
}

AddonAPI* GetAddonAPI(int aVersion)
Expand Down
3 changes: 2 additions & 1 deletion src/Loader/Loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
namespace Loader
{
extern std::mutex Mutex;
extern std::vector<LibraryAddon*> AddonLibrary;
extern std::unordered_map<
std::filesystem::path,
ELoaderAction
Expand Down Expand Up @@ -74,7 +75,7 @@ namespace Loader
std::string aUpdateLink
);
/* Installs an addon. */
void InstallAddon(LibraryAddon aAddon);
void InstallAddon(LibraryAddon* aAddon);

/* Gets or creates a pointer to the provided version, or nullptr if no such version exists. */
AddonAPI* GetAddonAPI(int aVersion);
Expand Down

0 comments on commit ae0aa56

Please sign in to comment.