#pragma once #include #include #include #include #include class Animation; #define TYPE_NODE 0x01 #define TYPE_SERVONODE 0x02 #define TYPE_CURVENODE 0x03 #define TYPE_NOISENODE 0x04 #define TYPE_VARIABLENODE 0x05 #define TYPE_MATHNODE 0x06 #define TYPE_MAPNODE 0x07 enum VariableSource { VAR_FACE_X, VAR_FACE_Y, VAR_SINE, VAR_ANALOG }; enum MathOperator { OP_MULTIPLY, OP_DIVIDE, OP_ADD, OP_SUBTRACT }; // Base Node class struct Node { uint8_t id; uint8_t type; uint16_t x; uint16_t y; virtual void evaluate(uint32_t tick) = 0; virtual ~Node() {} uint16_t inputValue; uint16_t outputValue = 0; }; // CurveNode: evaluates a curve at a given tick struct CurveNode : public Node { uint8_t curveID; Animation* animation = nullptr; // ✅ no need to include animation.h void evaluate(uint32_t tick) override; }; // ServoNode: sends a value to a motor struct ServoNode : public Node { uint8_t motorID; void evaluate(uint32_t tick) override; }; struct VariableNode : public Node { VariableSource source = VAR_SINE; // default void evaluate(uint32_t tick) override; void setSource(VariableSource src) { source = src; } }; struct MathNode : public Node { MathOperator op = OP_MULTIPLY; float value = 1.0f; void evaluate(uint32_t tick) override; }; struct MapNode : public Node { float inMin = 0; float inMax = 1023; float outMin = 0; float outMax = 255; void evaluate(uint32_t tick) override; }; // NodeGraph container struct NodeConnection { uint8_t fromID; uint8_t toID; }; class NodeGraph { public: std::vector nodes; std::vector connections; Node* findNodeByID(uint8_t id) const; void tick(uint32_t currentTick, const Animation& animation); std::vector> getServoOutputs() const; std::vector getSortedNodes(); void bindAnimationContext(Animation* animation); }; // Loader function void loadNodeGraph(const uint8_t* packet, size_t length, NodeGraph& graph); String printNodeGraph(const NodeGraph& graph);