diff --git a/lib/external/pattern_language b/lib/external/pattern_language index 5f0c69ffa..9fe6b2bd4 160000 --- a/lib/external/pattern_language +++ b/lib/external/pattern_language @@ -1 +1 @@ -Subproject commit 5f0c69ffa3a1a11c4c8834cfc87b851d46d287c0 +Subproject commit 9fe6b2bd4b428f6e31473cbd83e66a5e04d4a045 diff --git a/lib/libimhex/include/hex/providers/provider_data.hpp b/lib/libimhex/include/hex/providers/provider_data.hpp index 60f8e9af7..1b4b3447a 100644 --- a/lib/libimhex/include/hex/providers/provider_data.hpp +++ b/lib/libimhex/include/hex/providers/provider_data.hpp @@ -21,7 +21,7 @@ namespace hex { PerProvider(T data) : m_data({ { ImHexApi::Provider::get(), std::move(data) } }) { this->onCreate(); } - ~PerProvider() = default; + ~PerProvider() { this->onDestroy(); } T* operator->() { return &this->get(); @@ -58,19 +58,25 @@ namespace hex { private: void onCreate() { - (void)EventManager::subscribe([this](prv::Provider *provider) { + EventManager::subscribe(this, [this](prv::Provider *provider) { this->m_data.emplace(provider, T()); }); - (void)EventManager::subscribe([this](prv::Provider *provider){ + EventManager::subscribe(this, [this](prv::Provider *provider){ this->m_data.erase(provider); }); - EventManager::subscribe([this] { + EventManager::subscribe(this, [this] { this->m_data.clear(); }); } + void onDestroy() { + EventManager::unsubscribe(this); + EventManager::unsubscribe(this); + EventManager::unsubscribe(this); + } + private: std::map m_data; }; diff --git a/plugins/builtin/source/content/pl_visualizers.cpp b/plugins/builtin/source/content/pl_visualizers.cpp index acab9a644..f2461ec6c 100644 --- a/plugins/builtin/source/content/pl_visualizers.cpp +++ b/plugins/builtin/source/content/pl_visualizers.cpp @@ -22,6 +22,9 @@ #include #include +#include + +#include namespace hex::plugin::builtin { @@ -447,18 +450,41 @@ namespace hex::plugin::builtin { } void drawChunkBasedEntropyVisualizer(pl::ptrn::Pattern &, pl::ptrn::IIterable &, bool shouldReset, std::span arguments) { - // variable used to store the result to avoid having to recalculate the result at each frame - static DiagramChunkBasedEntropyAnalysis analyzer; + // variable used to store the result to avoid having to recalculate the result at each frame + static DiagramChunkBasedEntropyAnalysis analyzer; - // compute data + // compute data if (shouldReset) { auto pattern = arguments[0].toPattern(); auto chunkSize = arguments[1].toUnsigned(); - analyzer.process(pattern->getBytes(), chunkSize); + analyzer.process(pattern->getBytes(), chunkSize); } - + // show results - analyzer.draw(ImVec2(400, 250), ImPlotFlags_NoChild | ImPlotFlags_CanvasOnly); + analyzer.draw(ImVec2(400, 250), ImPlotFlags_NoChild | ImPlotFlags_CanvasOnly); + } + + void drawHexVisualizer(pl::ptrn::Pattern &, pl::ptrn::IIterable &, bool shouldReset, std::span arguments) { + static ui::HexEditor editor; + static std::unique_ptr dataProvider; + + if (shouldReset) { + auto pattern = arguments[0].toPattern(); + auto data = pattern->getBytes(); + + dataProvider = std::make_unique(); + dataProvider->resize(data.size()); + dataProvider->writeRaw(0x00, data.data(), data.size()); + dataProvider->setReadOnly(true); + + editor.setProvider(dataProvider.get()); + } + + if (ImGui::BeginChild("##editor", scaled(ImVec2(600, 400)))) { + editor.draw(); + + ImGui::EndChild(); + } } } @@ -472,6 +498,7 @@ namespace hex::plugin::builtin { ContentRegistry::PatternLanguage::addVisualizer("3d", draw3DVisualizer, 2); ContentRegistry::PatternLanguage::addVisualizer("sound", drawSoundVisualizer, 3); ContentRegistry::PatternLanguage::addVisualizer("chunk_entropy", drawChunkBasedEntropyVisualizer, 2); + ContentRegistry::PatternLanguage::addVisualizer("hex_viewer", drawHexVisualizer, 1); } }