#pragma once #include #include #include #include #include #include #include #include namespace hex::prv { class Provider; class Overlay; } namespace hex::dp { class Node { public: Node(std::string unlocalizedTitle, std::vector attributes); virtual ~Node() = default; [[nodiscard]] int getId() const { return this->m_id; } void setId(int id) { this->m_id = id; } [[nodiscard]] const std::string &getUnlocalizedName() const { return this->m_unlocalizedName; } void setUnlocalizedName(const std::string &unlocalizedName) { this->m_unlocalizedName = unlocalizedName; } [[nodiscard]] const std::string &getUnlocalizedTitle() const { return this->m_unlocalizedTitle; } [[nodiscard]] std::vector &getAttributes() { return this->m_attributes; } void setCurrentOverlay(prv::Overlay *overlay) { this->m_overlay = overlay; } virtual void drawNode() { } virtual void process() = 0; virtual void store(nlohmann::json &j) { hex::unused(j); } virtual void load(nlohmann::json &j) { hex::unused(j); } struct NodeError { Node *node; std::string message; }; void resetOutputData() { for (auto &attribute : this->m_attributes) attribute.getOutputData().reset(); } void resetProcessedInputs() { this->m_processedInputs.clear(); } void setPosition(ImVec2 pos) { this->m_position = pos; } [[nodiscard]] ImVec2 getPosition() const { return this->m_position; } static void setIdCounter(int id) { if (id > Node::s_idCounter) Node::s_idCounter = id; } private: int m_id; std::string m_unlocalizedTitle, m_unlocalizedName; std::vector m_attributes; std::set m_processedInputs; prv::Overlay *m_overlay = nullptr; ImVec2 m_position; static int s_idCounter; Attribute *getConnectedInputAttribute(u32 index) { if (index >= this->getAttributes().size()) throw std::runtime_error("Attribute index out of bounds!"); auto &connectedAttribute = this->getAttributes()[index].getConnectedAttributes(); if (connectedAttribute.empty()) return nullptr; return connectedAttribute.begin()->second; } void markInputProcessed(u32 index) { const auto &[iter, inserted] = this->m_processedInputs.insert(index); if (!inserted) throwNodeError("Recursion detected!"); } protected: [[noreturn]] void throwNodeError(const std::string &message) { throw NodeError { this, message }; } std::vector getBufferOnInput(u32 index); i128 getIntegerOnInput(u32 index); long double getFloatOnInput(u32 index); void setBufferOnOutput(u32 index, const std::vector &data); void setIntegerOnOutput(u32 index, i128 integer); void setFloatOnOutput(u32 index, long double floatingPoint); void setOverlayData(u64 address, const std::vector &data); }; }