mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-30 13:05:25 -05:00
patterns: Fixed [[static]] attribute and majorly reduced memory usage
Fixes #394
This commit is contained in:
@@ -95,11 +95,13 @@ namespace hex {
|
||||
static EventList s_events;
|
||||
};
|
||||
|
||||
namespace pl { class PatternData; }
|
||||
|
||||
/* Default Events */
|
||||
EVENT_DEF(EventFileLoaded, std::string);
|
||||
EVENT_DEF(EventFileUnloaded);
|
||||
EVENT_DEF(EventDataChanged);
|
||||
EVENT_DEF(EventPatternChanged);
|
||||
EVENT_DEF(EventPatternChanged, std::vector<pl::PatternData*>&);
|
||||
EVENT_DEF(EventWindowClosing, GLFWwindow*);
|
||||
EVENT_DEF(EventRegionSelected, Region);
|
||||
EVENT_DEF(EventProjectFileStore);
|
||||
|
||||
@@ -15,31 +15,10 @@
|
||||
|
||||
namespace hex::pl {
|
||||
|
||||
class ASTNode;
|
||||
class ASTNodeAttribute;
|
||||
|
||||
class PatternData;
|
||||
class Evaluator;
|
||||
|
||||
class Attributable {
|
||||
protected:
|
||||
Attributable() = default;
|
||||
|
||||
Attributable(const Attributable &) = default;
|
||||
|
||||
public:
|
||||
|
||||
void addAttribute(ASTNodeAttribute *attribute) {
|
||||
this->m_attributes.push_back(attribute);
|
||||
}
|
||||
|
||||
[[nodiscard]] const auto &getAttributes() const {
|
||||
return this->m_attributes;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<ASTNodeAttribute *> m_attributes;
|
||||
};
|
||||
class ASTNode;
|
||||
|
||||
class Clonable {
|
||||
public:
|
||||
@@ -99,6 +78,33 @@ namespace hex::pl {
|
||||
std::optional<std::string> m_value;
|
||||
};
|
||||
|
||||
class Attributable {
|
||||
protected:
|
||||
Attributable() = default;
|
||||
~Attributable() {
|
||||
for (auto &attribute : this->m_attributes)
|
||||
delete attribute;
|
||||
}
|
||||
|
||||
Attributable(const Attributable &other) {
|
||||
for (auto &attribute : other.m_attributes)
|
||||
this->m_attributes.push_back(static_cast<ASTNodeAttribute*>(attribute->clone()));
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
void addAttribute(ASTNodeAttribute *attribute) {
|
||||
this->m_attributes.push_back(attribute);
|
||||
}
|
||||
|
||||
[[nodiscard]] const auto &getAttributes() const {
|
||||
return this->m_attributes;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<ASTNodeAttribute *> m_attributes;
|
||||
};
|
||||
|
||||
class ASTNodeLiteral : public ASTNode {
|
||||
public:
|
||||
explicit ASTNodeLiteral(Token::Literal literal) : ASTNode(), m_literal(literal) { }
|
||||
@@ -429,7 +435,14 @@ namespace hex::pl {
|
||||
[[nodiscard]] std::optional<std::endian> getEndian() const { return this->m_endian; }
|
||||
|
||||
[[nodiscard]] ASTNode *evaluate(Evaluator *evaluator) const override {
|
||||
return this->m_type->evaluate(evaluator);
|
||||
auto type = this->m_type->evaluate(evaluator);
|
||||
|
||||
if (auto attributable = dynamic_cast<Attributable*>(type)) {
|
||||
for (auto &attribute : this->getAttributes())
|
||||
attributable->addAttribute(static_cast<ASTNodeAttribute*>(attribute->clone()));
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::vector<PatternData*> createPatterns(Evaluator *evaluator) const override {
|
||||
@@ -978,7 +991,6 @@ namespace hex::pl {
|
||||
delete entries.back();
|
||||
entries.pop_back();
|
||||
entryIndex--;
|
||||
|
||||
};
|
||||
|
||||
if (this->m_size != nullptr) {
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace hex::pl {
|
||||
virtual PatternData* clone() = 0;
|
||||
|
||||
[[nodiscard]] u64 getOffset() const { return this->m_offset; }
|
||||
void setOffset(u64 offset) { this->m_offset = offset; }
|
||||
virtual void setOffset(u64 offset) { this->m_offset = offset; }
|
||||
|
||||
[[nodiscard]] size_t getSize() const { return this->m_size; }
|
||||
void setSize(size_t size) { this->m_size = size; }
|
||||
@@ -135,14 +135,21 @@ namespace hex::pl {
|
||||
virtual void createEntry(prv::Provider* &provider) = 0;
|
||||
[[nodiscard]] virtual std::string getFormattedName() const = 0;
|
||||
|
||||
virtual std::map<u64, u32> getHighlightedAddresses() {
|
||||
if (this->isHidden()) return { };
|
||||
[[nodiscard]]
|
||||
virtual const PatternData* getPattern(u64 offset) const {
|
||||
if (offset >= this->getOffset() && offset < (this->getOffset() + this->getSize()))
|
||||
return this;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual void getHighlightedAddresses(std::map<u64, u32> &highlight) const {
|
||||
if (this->isHidden()) return;
|
||||
|
||||
std::map<u64, u32> result;
|
||||
for (u64 i = 0; i < this->getSize(); i++)
|
||||
result.insert({ this->getOffset() + i, this->getColor() });
|
||||
highlight.insert({ this->getOffset() + i, this->getColor() });
|
||||
|
||||
return result;
|
||||
this->m_evaluator->handleAbort();
|
||||
}
|
||||
|
||||
virtual void sort(ImGuiTableSortSpecs *sortSpecs, prv::Provider *provider) { }
|
||||
@@ -382,14 +389,11 @@ namespace hex::pl {
|
||||
}
|
||||
}
|
||||
|
||||
std::map<u64, u32> getHighlightedAddresses() override {
|
||||
auto ownAddresses = PatternData::getHighlightedAddresses();
|
||||
auto pointedToAddresses = this->m_pointedAt->getHighlightedAddresses();
|
||||
|
||||
ownAddresses.merge(pointedToAddresses);
|
||||
|
||||
return ownAddresses;
|
||||
void getHighlightedAddresses(std::map<u64, u32> &highlight) const override {
|
||||
PatternData::getHighlightedAddresses(highlight);
|
||||
this->m_pointedAt->getHighlightedAddresses(highlight);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string getFormattedName() const override {
|
||||
std::string result = this->m_pointedAt->getFormattedName() + "* : ";
|
||||
switch (this->getSize()) {
|
||||
@@ -440,6 +444,14 @@ namespace hex::pl {
|
||||
this->m_pointerBase = base;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
const PatternData* getPattern(u64 offset) const override {
|
||||
if (offset >= this->getOffset() && offset < (this->getOffset() + this->getSize()))
|
||||
return this;
|
||||
else
|
||||
return this->m_pointedAt->getPattern(offset);
|
||||
}
|
||||
|
||||
private:
|
||||
PatternData *m_pointedAt = nullptr;
|
||||
u64 m_pointedAtAddress = 0;
|
||||
@@ -807,20 +819,23 @@ namespace hex::pl {
|
||||
}
|
||||
}
|
||||
|
||||
std::map<u64, u32> getHighlightedAddresses() override {
|
||||
std::map<u64, u32> result;
|
||||
|
||||
void getHighlightedAddresses(std::map<u64, u32> &highlight) const override {
|
||||
for (auto &entry : this->m_entries) {
|
||||
result.merge(entry->getHighlightedAddresses());
|
||||
entry->getHighlightedAddresses(highlight);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string getFormattedName() const override {
|
||||
return this->m_entries[0]->getTypeName() + "[" + std::to_string(this->m_entries.size()) + "]";
|
||||
}
|
||||
|
||||
void setOffset(u64 offset) override {
|
||||
for (auto &entry : this->m_entries)
|
||||
entry->setOffset(entry->getOffset() - this->getOffset() + offset);
|
||||
|
||||
PatternData::setOffset(offset);
|
||||
}
|
||||
|
||||
[[nodiscard]] const std::vector<PatternData*>& getEntries() {
|
||||
return this->m_entries;
|
||||
}
|
||||
@@ -851,6 +866,18 @@ namespace hex::pl {
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
const PatternData* getPattern(u64 offset) const override {
|
||||
auto iter = std::find_if(this->m_entries.begin(), this->m_entries.end(), [this, offset](PatternData *pattern){
|
||||
return offset >= this->getOffset() && offset < (this->getOffset() + this->getSize());
|
||||
});
|
||||
|
||||
if (iter == this->m_entries.end())
|
||||
return nullptr;
|
||||
else
|
||||
return *iter;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<PatternData*> m_entries;
|
||||
u64 m_displayEnd = 50;
|
||||
@@ -868,6 +895,7 @@ namespace hex::pl {
|
||||
|
||||
~PatternDataStaticArray() override {
|
||||
delete this->m_template;
|
||||
delete this->m_highlightTemplate;
|
||||
}
|
||||
|
||||
PatternData* clone() override {
|
||||
@@ -932,18 +960,21 @@ namespace hex::pl {
|
||||
}
|
||||
}
|
||||
|
||||
std::map<u64, u32> getHighlightedAddresses() override {
|
||||
auto startOffset = this->m_template->getOffset();
|
||||
void getHighlightedAddresses(std::map<u64, u32> &highlight) const override {
|
||||
auto entry = this->m_template->clone();
|
||||
|
||||
std::map<u64, u32> result;
|
||||
for (u64 address = this->getOffset(); address < this->getOffset() + this->getSize(); address += this->m_template->getSize()) {
|
||||
this->m_template->setOffset(address);
|
||||
result.merge(this->m_template->getHighlightedAddresses());
|
||||
for (u64 address = this->getOffset(); address < this->getOffset() + this->getSize(); address += entry->getSize()) {
|
||||
entry->setOffset(address);
|
||||
entry->getHighlightedAddresses(highlight);
|
||||
}
|
||||
|
||||
this->m_template->setOffset(startOffset);
|
||||
delete entry;
|
||||
}
|
||||
|
||||
return result;
|
||||
void setOffset(u64 offset) override {
|
||||
this->m_template->setOffset(this->m_template->getOffset() - this->getOffset() + offset);
|
||||
|
||||
PatternData::setOffset(offset);
|
||||
}
|
||||
|
||||
void setColor(u32 color) override {
|
||||
@@ -969,6 +1000,7 @@ namespace hex::pl {
|
||||
|
||||
void setEntries(PatternData* templ, size_t count) {
|
||||
this->m_template = templ;
|
||||
this->m_highlightTemplate = this->m_template->clone();
|
||||
this->m_entryCount = count;
|
||||
|
||||
if (this->hasOverriddenColor()) this->setColor(this->m_template->getColor());
|
||||
@@ -983,8 +1015,19 @@ namespace hex::pl {
|
||||
return *this->m_template == *otherArray.m_template && this->m_entryCount == otherArray.m_entryCount;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
const PatternData* getPattern(u64 offset) const override {
|
||||
if (offset >= this->getOffset() && offset < (this->getOffset() + this->getSize())) {
|
||||
this->m_highlightTemplate->setOffset((offset / this->m_highlightTemplate->getSize()) * this->m_highlightTemplate->getSize());
|
||||
return this->m_highlightTemplate;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
PatternData *m_template;
|
||||
mutable PatternData *m_highlightTemplate;
|
||||
size_t m_entryCount;
|
||||
u64 m_displayEnd = 50;
|
||||
};
|
||||
@@ -1039,13 +1082,17 @@ namespace hex::pl {
|
||||
|
||||
}
|
||||
|
||||
std::map<u64, u32> getHighlightedAddresses() override {
|
||||
std::map<u64, u32> result;
|
||||
void getHighlightedAddresses(std::map<u64, u32> &highlight) const override {
|
||||
for (auto &member : this->m_members) {
|
||||
result.merge(member->getHighlightedAddresses());
|
||||
member->getHighlightedAddresses(highlight);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
void setOffset(u64 offset) override {
|
||||
for (auto &member : this->m_members)
|
||||
member->setOffset(member->getOffset() - this->getOffset() + offset);
|
||||
|
||||
PatternData::setOffset(offset);
|
||||
}
|
||||
|
||||
void setColor(u32 color) override {
|
||||
@@ -1101,6 +1148,19 @@ namespace hex::pl {
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
const PatternData* getPattern(u64 offset) const override {
|
||||
|
||||
auto iter = std::find_if(this->m_members.begin(), this->m_members.end(), [offset](PatternData *pattern){
|
||||
return offset >= pattern->getOffset() && offset < (pattern->getOffset() + pattern->getSize());
|
||||
});
|
||||
|
||||
if (iter == this->m_members.end())
|
||||
return nullptr;
|
||||
else
|
||||
return *iter;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<PatternData*> m_members;
|
||||
std::vector<PatternData*> m_sortedMembers;
|
||||
@@ -1158,14 +1218,17 @@ namespace hex::pl {
|
||||
|
||||
}
|
||||
|
||||
std::map<u64, u32> getHighlightedAddresses() override {
|
||||
std::map<u64, u32> result;
|
||||
|
||||
void getHighlightedAddresses(std::map<u64, u32> &highlight) const override {
|
||||
for (auto &member : this->m_members) {
|
||||
result.merge(member->getHighlightedAddresses());
|
||||
member->getHighlightedAddresses(highlight);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
void setOffset(u64 offset) override {
|
||||
for (auto &member : this->m_members)
|
||||
member->setOffset(member->getOffset() - this->getOffset() + offset);
|
||||
|
||||
PatternData::setOffset(offset);
|
||||
}
|
||||
|
||||
void setColor(u32 color) override {
|
||||
@@ -1220,6 +1283,19 @@ namespace hex::pl {
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
const PatternData* getPattern(u64 offset) const override {
|
||||
|
||||
auto largestMember = std::find_if(this->m_members.begin(), this->m_members.end(), [this](PatternData *pattern) {
|
||||
return pattern->getSize() == this->getSize();
|
||||
});
|
||||
|
||||
if (largestMember == this->m_members.end())
|
||||
return nullptr;
|
||||
else
|
||||
return *largestMember;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<PatternData*> m_members;
|
||||
std::vector<PatternData*> m_sortedMembers;
|
||||
@@ -1451,6 +1527,13 @@ namespace hex::pl {
|
||||
|
||||
}
|
||||
|
||||
void setOffset(u64 offset) override {
|
||||
for (auto &field : this->m_fields)
|
||||
field->setOffset(field->getOffset() - this->getOffset() + offset);
|
||||
|
||||
PatternData::setOffset(offset);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string getFormattedName() const override {
|
||||
return "bitfield " + PatternData::getTypeName();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user