// // Created by martin on 04.02.22. // #ifndef ANIMTESTBED_ANIMGRAPHRESOURCE_H #define ANIMTESTBED_ANIMGRAPHRESOURCE_H #include <cstring> #include <iostream> #include <map> #include <string> #include <type_traits> #include <vector> #include "AnimGraph.h" #include "AnimGraphData.h" #include "AnimGraphNodes.h" #include "SyncTrack.h" struct AnimNode; struct AnimNodeResource { std::string m_name; std::string m_type_name; AnimNode* m_anim_node = nullptr; NodeDescriptorBase* m_socket_accessor = nullptr; float m_position[2] = {0.f, 0.f}; }; static inline AnimNodeResource AnimNodeResourceFactory( const std::string& node_type_name) { AnimNodeResource result; result.m_type_name = node_type_name; result.m_anim_node = AnimNodeFactory(node_type_name); result.m_socket_accessor = AnimNodeDescriptorFactory(node_type_name, result.m_anim_node); return result; } // // AnimGraphResource // struct AnimGraphConnectionResource { size_t source_node_index = -1; std::string source_socket_name; size_t target_node_index = -1; std::string target_socket_name; }; struct AnimGraphResource { std::string m_name; std::vector<AnimNodeResource> m_nodes; std::vector<AnimGraphConnectionResource> m_connections; ~AnimGraphResource() { for (auto & m_node : m_nodes) { delete m_node.m_anim_node; delete m_node.m_socket_accessor; } } AnimGraphResource() { clear(); } void clear(); void clearNodes(); void initGraphConnectors(); bool saveToFile(const char* filename) const; bool loadFromFile(const char* filename); AnimNodeResource& getGraphOutputNode() { return m_nodes[0]; } AnimNodeResource& getGraphInputNode() { return m_nodes[1]; } size_t getNodeIndex(const AnimNodeResource& node_resource) const { for (size_t i = 0, n = m_nodes.size(); i < n; i++) { if (&m_nodes[i] == &node_resource) { return i; } } return -1; } size_t addNode(const AnimNodeResource &node_resource) { m_nodes.push_back(node_resource); return m_nodes.size() - 1; } bool connectSockets( const AnimNodeResource& source_node, const std::string& source_socket_name, const AnimNodeResource& target_node, const std::string& target_socket_name) { size_t source_node_index = getNodeIndex(source_node); size_t target_node_index = getNodeIndex(target_node); if (source_node_index >= m_nodes.size() || target_node_index >= m_nodes.size()) { std::cerr << "Cannot connect nodes: could not find nodes." << std::endl; return false; } Socket* source_socket = source_node.m_socket_accessor->GetOutputSocket(source_socket_name.c_str()); Socket* target_socket = target_node.m_socket_accessor->GetInputSocket(target_socket_name.c_str()); if (source_socket == nullptr || target_socket == nullptr) { std::cerr << "Cannot connect nodes: could not find sockets." << std::endl; return false; } AnimGraphConnectionResource connection; connection.source_node_index = source_node_index; connection.source_socket_name = source_socket_name; connection.target_node_index = target_node_index; connection.target_socket_name = target_socket_name; m_connections.push_back(connection); return true; } bool isSocketConnected( const AnimNodeResource& node, const std::string& socket_name) { size_t node_index = getNodeIndex(node); for (const auto & connection : m_connections) { if ((connection.source_node_index == node_index && connection.source_socket_name == socket_name) || ((connection.target_node_index == node_index) && connection.target_socket_name == socket_name)) { return true; } } return false; } void createInstance(AnimGraph& result) const; void createRuntimeNodeInstances(AnimGraph& instance) const; void prepareGraphIOData(AnimGraph& instance) const; void setRuntimeNodeProperties(AnimGraph& instance) const; std::vector<Socket*> getConstNodeInputs(std::vector<NodeDescriptorBase*>& instance_node_descriptors) const; }; #endif //ANIMTESTBED_ANIMGRAPHRESOURCE_H