mirror of https://github.com/WerWolv/ImHex
fix: Make sure providers returned by createProvider don't get deleted unexpectedly
This commit is contained in:
parent
e696d384c2
commit
baa3329e7f
|
|
@ -19,7 +19,7 @@ EXPORT_MODULE namespace hex {
|
||||||
|
|
||||||
void addProviderName(const UnlocalizedString &unlocalizedName, const char *icon);
|
void addProviderName(const UnlocalizedString &unlocalizedName, const char *icon);
|
||||||
|
|
||||||
using ProviderCreationFunction = std::function<std::unique_ptr<prv::Provider>()>;
|
using ProviderCreationFunction = std::function<std::shared_ptr<prv::Provider>()>;
|
||||||
void add(const std::string &typeName, ProviderCreationFunction creationFunction);
|
void add(const std::string &typeName, ProviderCreationFunction creationFunction);
|
||||||
|
|
||||||
struct Entry {
|
struct Entry {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ namespace hex {
|
||||||
/**
|
/**
|
||||||
* @brief Creates a provider from its unlocalized name, and add it to the provider list
|
* @brief Creates a provider from its unlocalized name, and add it to the provider list
|
||||||
*/
|
*/
|
||||||
EVENT_DEF(RequestCreateProvider, std::string, bool, bool, hex::prv::Provider **);
|
EVENT_DEF(RequestCreateProvider, std::string, bool, bool, std::shared_ptr<hex::prv::Provider> *);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Move the data from all PerProvider instances from one provider to another
|
* @brief Move the data from all PerProvider instances from one provider to another
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ EXPORT_MODULE namespace hex {
|
||||||
* @param skipLoadInterface Whether to skip the provider's loading interface (see property documentation)
|
* @param skipLoadInterface Whether to skip the provider's loading interface (see property documentation)
|
||||||
* @param select Whether to select the provider after adding it
|
* @param select Whether to select the provider after adding it
|
||||||
*/
|
*/
|
||||||
void add(std::unique_ptr<prv::Provider> &&provider, bool skipLoadInterface = false, bool select = true);
|
void add(std::shared_ptr<prv::Provider> &&provider, bool skipLoadInterface = false, bool select = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Creates a new provider and adds it to the list of providers
|
* @brief Creates a new provider and adds it to the list of providers
|
||||||
|
|
@ -111,7 +111,7 @@ EXPORT_MODULE namespace hex {
|
||||||
* @param skipLoadInterface Whether to skip the provider's loading interface (see property documentation)
|
* @param skipLoadInterface Whether to skip the provider's loading interface (see property documentation)
|
||||||
* @param select Whether to select the provider after adding it
|
* @param select Whether to select the provider after adding it
|
||||||
*/
|
*/
|
||||||
prv::Provider* createProvider(
|
std::shared_ptr<prv::Provider> createProvider(
|
||||||
const UnlocalizedString &unlocalizedName,
|
const UnlocalizedString &unlocalizedName,
|
||||||
bool skipLoadInterface = false,
|
bool skipLoadInterface = false,
|
||||||
bool select = true
|
bool select = true
|
||||||
|
|
|
||||||
|
|
@ -1119,13 +1119,13 @@ namespace hex {
|
||||||
namespace impl {
|
namespace impl {
|
||||||
|
|
||||||
void add(const std::string &typeName, ProviderCreationFunction creationFunction) {
|
void add(const std::string &typeName, ProviderCreationFunction creationFunction) {
|
||||||
(void)RequestCreateProvider::subscribe([expectedName = typeName, creationFunction](const std::string &name, bool skipLoadInterface, bool selectProvider, prv::Provider **provider) {
|
(void)RequestCreateProvider::subscribe([expectedName = typeName, creationFunction](const std::string &name, bool skipLoadInterface, bool selectProvider, std::shared_ptr<prv::Provider> *provider) {
|
||||||
if (name != expectedName) return;
|
if (name != expectedName) return;
|
||||||
|
|
||||||
auto newProvider = creationFunction();
|
auto newProvider = creationFunction();
|
||||||
|
|
||||||
if (provider != nullptr) {
|
if (provider != nullptr) {
|
||||||
*provider = newProvider.get();
|
*provider = newProvider;
|
||||||
ImHexApi::Provider::add(std::move(newProvider), skipLoadInterface, selectProvider);
|
ImHexApi::Provider::add(std::move(newProvider), skipLoadInterface, selectProvider);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -294,8 +294,8 @@ namespace hex {
|
||||||
namespace ImHexApi::Provider {
|
namespace ImHexApi::Provider {
|
||||||
|
|
||||||
static i64 s_currentProvider = -1;
|
static i64 s_currentProvider = -1;
|
||||||
static AutoReset<std::vector<std::unique_ptr<prv::Provider>>> s_providers;
|
static AutoReset<std::vector<std::shared_ptr<prv::Provider>>> s_providers;
|
||||||
static AutoReset<std::map<prv::Provider*, std::unique_ptr<prv::Provider>>> s_providersToRemove;
|
static AutoReset<std::map<prv::Provider*, std::shared_ptr<prv::Provider>>> s_providersToRemove;
|
||||||
|
|
||||||
namespace impl {
|
namespace impl {
|
||||||
|
|
||||||
|
|
@ -382,7 +382,7 @@ namespace hex {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void add(std::unique_ptr<prv::Provider> &&provider, bool skipLoadInterface, bool select) {
|
void add(std::shared_ptr<prv::Provider> &&provider, bool skipLoadInterface, bool select) {
|
||||||
std::scoped_lock lock(impl::s_providerMutex);
|
std::scoped_lock lock(impl::s_providerMutex);
|
||||||
|
|
||||||
if (TaskManager::getRunningTaskCount() > 0)
|
if (TaskManager::getRunningTaskCount() > 0)
|
||||||
|
|
@ -491,8 +491,8 @@ namespace hex {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
prv::Provider* createProvider(const UnlocalizedString &unlocalizedName, bool skipLoadInterface, bool select) {
|
std::shared_ptr<prv::Provider> createProvider(const UnlocalizedString &unlocalizedName, bool skipLoadInterface, bool select) {
|
||||||
prv::Provider* result = nullptr;
|
std::shared_ptr<prv::Provider> result = nullptr;
|
||||||
RequestCreateProvider::post(unlocalizedName, skipLoadInterface, select, &result);
|
RequestCreateProvider::post(unlocalizedName, skipLoadInterface, select, &result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
|
|
@ -50,17 +50,17 @@ namespace hex::plugin::builtin {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto provider = ImHexApi::Provider::createProvider("hex.builtin.provider.file", true);
|
auto provider = ImHexApi::Provider::createProvider("hex.builtin.provider.file", true);
|
||||||
if (auto *fileProvider = dynamic_cast<FileProvider*>(provider); fileProvider != nullptr) {
|
if (auto *fileProvider = dynamic_cast<FileProvider*>(provider.get()); fileProvider != nullptr) {
|
||||||
fileProvider->setPath(path);
|
fileProvider->setPath(path);
|
||||||
if (!provider->open() || !provider->isAvailable()) {
|
if (!provider->open() || !provider->isAvailable()) {
|
||||||
ui::ToastError::open(fmt::format("hex.builtin.provider.error.open"_lang, provider->getErrorMessage()));
|
ui::ToastError::open(fmt::format("hex.builtin.provider.error.open"_lang, provider->getErrorMessage()));
|
||||||
TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); });
|
TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider.get()); });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
EventProviderOpened::post(fileProvider);
|
EventProviderOpened::post(fileProvider);
|
||||||
AchievementManager::unlockAchievement("hex.builtin.achievement.starting_out", "hex.builtin.achievement.starting_out.open_file.name");
|
AchievementManager::unlockAchievement("hex.builtin.achievement.starting_out", "hex.builtin.achievement.starting_out.open_file.name");
|
||||||
ImHexApi::Provider::setCurrentProvider(provider);
|
ImHexApi::Provider::setCurrentProvider(provider.get());
|
||||||
|
|
||||||
glfwRequestWindowAttention(ImHexApi::System::getMainWindowHandle());
|
glfwRequestWindowAttention(ImHexApi::System::getMainWindowHandle());
|
||||||
glfwFocusWindow(ImHexApi::System::getMainWindowHandle());
|
glfwFocusWindow(ImHexApi::System::getMainWindowHandle());
|
||||||
|
|
@ -184,9 +184,9 @@ namespace hex::plugin::builtin {
|
||||||
if (name == "Create File") {
|
if (name == "Create File") {
|
||||||
auto newProvider = hex::ImHexApi::Provider::createProvider("hex.builtin.provider.mem_file", true);
|
auto newProvider = hex::ImHexApi::Provider::createProvider("hex.builtin.provider.mem_file", true);
|
||||||
if (newProvider != nullptr && !newProvider->open())
|
if (newProvider != nullptr && !newProvider->open())
|
||||||
hex::ImHexApi::Provider::remove(newProvider);
|
hex::ImHexApi::Provider::remove(newProvider.get());
|
||||||
else
|
else
|
||||||
EventProviderOpened::post(newProvider);
|
EventProviderOpened::post(newProvider.get());
|
||||||
} else if (name == "Open File") {
|
} else if (name == "Open File") {
|
||||||
fs::openFileBrowser(fs::DialogMode::Open, { }, [](const auto &path) {
|
fs::openFileBrowser(fs::DialogMode::Open, { }, [](const auto &path) {
|
||||||
if (path.extension() == ".hexproj") {
|
if (path.extension() == ".hexproj") {
|
||||||
|
|
@ -197,9 +197,8 @@ namespace hex::plugin::builtin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto newProvider = static_cast<FileProvider*>(
|
auto provider = ImHexApi::Provider::createProvider("hex.builtin.provider.file", true);
|
||||||
ImHexApi::Provider::createProvider("hex.builtin.provider.file", true)
|
auto newProvider = static_cast<FileProvider*>(provider.get());
|
||||||
);
|
|
||||||
|
|
||||||
if (newProvider == nullptr)
|
if (newProvider == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -378,9 +378,9 @@ namespace hex::plugin::builtin {
|
||||||
ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.create_file" }, ICON_VS_FILE, 1050, CTRLCMD + Keys::N + AllowWhileTyping + ShowOnWelcomeScreen, [] {
|
ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.create_file" }, ICON_VS_FILE, 1050, CTRLCMD + Keys::N + AllowWhileTyping + ShowOnWelcomeScreen, [] {
|
||||||
auto newProvider = hex::ImHexApi::Provider::createProvider("hex.builtin.provider.mem_file", true);
|
auto newProvider = hex::ImHexApi::Provider::createProvider("hex.builtin.provider.mem_file", true);
|
||||||
if (newProvider != nullptr && !newProvider->open())
|
if (newProvider != nullptr && !newProvider->open())
|
||||||
hex::ImHexApi::Provider::remove(newProvider);
|
hex::ImHexApi::Provider::remove(newProvider.get());
|
||||||
else
|
else
|
||||||
EventProviderOpened::post(newProvider);
|
EventProviderOpened::post(newProvider.get());
|
||||||
}, noRunningTasks, ContentRegistry::Views::getViewByName("hex.builtin.view.hex_editor.name"));
|
}, noRunningTasks, ContentRegistry::Views::getViewByName("hex.builtin.view.hex_editor.name"));
|
||||||
|
|
||||||
/* Open File */
|
/* Open File */
|
||||||
|
|
|
||||||
|
|
@ -89,13 +89,13 @@ namespace hex::plugin::builtin {
|
||||||
newProvider->loadSettings(providerSettings.at("settings"));
|
newProvider->loadSettings(providerSettings.at("settings"));
|
||||||
loaded = true;
|
loaded = true;
|
||||||
} catch (const std::exception &e){
|
} catch (const std::exception &e){
|
||||||
providerWarnings[newProvider] = e.what();
|
providerWarnings[newProvider.get()] = e.what();
|
||||||
}
|
}
|
||||||
if (loaded) {
|
if (loaded) {
|
||||||
if (!newProvider->open() || !newProvider->isAvailable() || !newProvider->isReadable()) {
|
if (!newProvider->open() || !newProvider->isAvailable() || !newProvider->isReadable()) {
|
||||||
providerWarnings[newProvider] = newProvider->getErrorMessage();
|
providerWarnings[newProvider.get()] = newProvider->getErrorMessage();
|
||||||
} else {
|
} else {
|
||||||
EventProviderOpened::post(newProvider);
|
EventProviderOpened::post(newProvider.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,16 +51,16 @@ namespace hex::plugin::builtin {
|
||||||
|
|
||||||
auto newProvider = hex::ImHexApi::Provider::createProvider("hex.builtin.provider.file", true);
|
auto newProvider = hex::ImHexApi::Provider::createProvider("hex.builtin.provider.file", true);
|
||||||
|
|
||||||
if (auto fileProvider = dynamic_cast<FileProvider*>(newProvider); fileProvider != nullptr) {
|
if (auto fileProvider = dynamic_cast<FileProvider*>(newProvider.get()); fileProvider != nullptr) {
|
||||||
fileProvider->setPath(path);
|
fileProvider->setPath(path);
|
||||||
|
|
||||||
if (!fileProvider->open()) {
|
if (!fileProvider->open()) {
|
||||||
ImHexApi::Provider::remove(newProvider);
|
ImHexApi::Provider::remove(newProvider.get());
|
||||||
} else {
|
} else {
|
||||||
MovePerProviderData::post(this, fileProvider);
|
MovePerProviderData::post(this, fileProvider);
|
||||||
|
|
||||||
fileProvider->markDirty(false);
|
fileProvider->markDirty(false);
|
||||||
EventProviderOpened::post(newProvider);
|
EventProviderOpened::post(newProvider.get());
|
||||||
ImHexApi::Provider::remove(this, true);
|
ImHexApi::Provider::remove(this, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -279,16 +279,16 @@ namespace hex::plugin::builtin::recent {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *provider = ImHexApi::Provider::createProvider(recentEntry.type, true);
|
auto provider = ImHexApi::Provider::createProvider(recentEntry.type, true);
|
||||||
if (provider != nullptr) {
|
if (provider != nullptr) {
|
||||||
provider->loadSettings(recentEntry.data);
|
provider->loadSettings(recentEntry.data);
|
||||||
|
|
||||||
TaskManager::createBlockingTask("hex.builtin.provider.opening", TaskManager::NoProgress, [provider]() {
|
TaskManager::createBlockingTask("hex.builtin.provider.opening", TaskManager::NoProgress, [provider]() {
|
||||||
if (!provider->open() || !provider->isAvailable()) {
|
if (!provider->open() || !provider->isAvailable()) {
|
||||||
ui::ToastError::open(fmt::format("hex.builtin.provider.error.open"_lang, provider->getErrorMessage()));
|
ui::ToastError::open(fmt::format("hex.builtin.provider.error.open"_lang, provider->getErrorMessage()));
|
||||||
TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); });
|
TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider.get()); });
|
||||||
} else {
|
} else {
|
||||||
TaskManager::doLater([provider]{ EventProviderOpened::post(provider); });
|
TaskManager::doLater([provider]{ EventProviderOpened::post(provider.get()); });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -390,7 +390,7 @@ namespace hex::plugin::builtin {
|
||||||
auto provider = ImHexApi::Provider::get();
|
auto provider = ImHexApi::Provider::get();
|
||||||
TaskManager::doLater([region, provider, name]{
|
TaskManager::doLater([region, provider, name]{
|
||||||
auto newProvider = ImHexApi::Provider::createProvider("hex.builtin.provider.view", true);
|
auto newProvider = ImHexApi::Provider::createProvider("hex.builtin.provider.view", true);
|
||||||
if (auto *viewProvider = dynamic_cast<ViewProvider*>(newProvider); viewProvider != nullptr) {
|
if (auto *viewProvider = dynamic_cast<ViewProvider*>(newProvider.get()); viewProvider != nullptr) {
|
||||||
viewProvider->setProvider(region.getStartAddress(), region.getSize(), provider);
|
viewProvider->setProvider(region.getStartAddress(), region.getSize(), provider);
|
||||||
viewProvider->setName(fmt::format("'{}' View", name));
|
viewProvider->setName(fmt::format("'{}' View", name));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1168,7 +1168,7 @@ namespace hex::plugin::builtin {
|
||||||
auto selection = ImHexApi::HexEditor::getSelection();
|
auto selection = ImHexApi::HexEditor::getSelection();
|
||||||
|
|
||||||
auto newProvider = ImHexApi::Provider::createProvider("hex.builtin.provider.view", true);
|
auto newProvider = ImHexApi::Provider::createProvider("hex.builtin.provider.view", true);
|
||||||
if (auto *viewProvider = dynamic_cast<ViewProvider*>(newProvider); viewProvider != nullptr) {
|
if (auto *viewProvider = dynamic_cast<ViewProvider*>(newProvider.get()); viewProvider != nullptr) {
|
||||||
viewProvider->setProvider(selection->getStartAddress(), selection->getSize(), selection->getProvider());
|
viewProvider->setProvider(selection->getStartAddress(), selection->getSize(), selection->getProvider());
|
||||||
if (viewProvider->open())
|
if (viewProvider->open())
|
||||||
EventProviderOpened::post(viewProvider);
|
EventProviderOpened::post(viewProvider);
|
||||||
|
|
|
||||||
|
|
@ -347,9 +347,9 @@ namespace hex::plugin::builtin {
|
||||||
if (ImGuiExt::IconHyperlink(ICON_VS_NEW_FILE, "hex.builtin.welcome.start.create_file"_lang)) {
|
if (ImGuiExt::IconHyperlink(ICON_VS_NEW_FILE, "hex.builtin.welcome.start.create_file"_lang)) {
|
||||||
auto newProvider = hex::ImHexApi::Provider::createProvider("hex.builtin.provider.mem_file", true);
|
auto newProvider = hex::ImHexApi::Provider::createProvider("hex.builtin.provider.mem_file", true);
|
||||||
if (newProvider != nullptr && !newProvider->open())
|
if (newProvider != nullptr && !newProvider->open())
|
||||||
hex::ImHexApi::Provider::remove(newProvider);
|
hex::ImHexApi::Provider::remove(newProvider.get());
|
||||||
else
|
else
|
||||||
EventProviderOpened::post(newProvider);
|
EventProviderOpened::post(newProvider.get());
|
||||||
}
|
}
|
||||||
if (ImGuiExt::IconHyperlink(ICON_VS_GO_TO_FILE, "hex.builtin.welcome.start.open_file"_lang))
|
if (ImGuiExt::IconHyperlink(ICON_VS_GO_TO_FILE, "hex.builtin.welcome.start.open_file"_lang))
|
||||||
RequestOpenWindow::post("Open File");
|
RequestOpenWindow::post("Open File");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue