#include "DDSInterfaceGen.h" DDSInterfaceGen::DDSInterfaceGen(const std::string &idlPath) { IDLPath = fs::path(idlPath).parent_path().string(); IDLName = fs::path(idlPath).stem().string(); } bool DDSInterfaceGen::generateDDSInterface(const AllInterfaceData &interfaceData) { std::string systemName = interfaceData.systemName; std::string planeName = interfaceData.planeName; for (const auto &ata : interfaceData.ataInterfaceData) { std::string ataName = ata.ataName; std::string interfaceFolderPath = IDLPath + "/" + ataName; fs::create_directories(interfaceFolderPath); std::string nameSpace = systemName + "::" + planeName + "::" + ataName; for (const auto &structData : ata.structInterfaceData) { std::string structName = structData.modelStructName; generateDDSInterfaceHpp(nameSpace, structName, interfaceFolderPath, structData.interfaceData); generateDDSInterfaceCxx(nameSpace, structName, interfaceFolderPath, structData.interfaceData); } } return true; } bool DDSInterfaceGen::generateDDSInterfaceHpp(const std::string &nameSpace, const std::string &structName, const std::string &interfaceFolderPath, const std::vector &interfaceData) { std::string className = structName + "_Interface"; std::string topicType = nameSpace + "::" + structName; std::string hppFilePath = interfaceFolderPath + "/" + structName + ".hpp"; std::ofstream hppFile(hppFilePath); // 1. 写入引用头文件 hppFile << "#pragma once" << std::endl; hppFile << "#include \"../" << IDLName << "PubSubTypes.hpp\"" << std::endl; hppFile << "#include \"XNCore/XNDDSInterface.h\"" << std::endl; // 2. 写入命名空间 hppFile << "namespace " << nameSpace << std::endl; hppFile << "{" << std::endl; // 3. 写入类声明 hppFile << "class " << className << " : public XNDDSInterface" << std::endl; hppFile << "{" << std::endl; hppFile << "public:" << std::endl; hppFile << "\t" << "using DDSType = " << topicType << ";" << std::endl; hppFile << "\t" << "using DDSPubSubType = " << topicType << "PubSubType;" << std::endl; hppFile << "\t" << "static const std::string topic_name;" << std::endl; // 4. 写入构造函数和析构函数 hppFile << "\t" << className << "();" << std::endl; hppFile << "\t" << "virtual ~" << className << "();" << std::endl; // 5. 写入初始化函数 hppFile << "\t" << "virtual void Initialize(XNFrameworkPtr framework, uint32_t modelId, uint32_t " "DDS_type) override;" << std::endl; // 6. 写入清空数据函数 hppFile << "\t" << "virtual void clearOutData() override;" << std::endl; // 7. 写入发送数据函数 hppFile << "\t" << "virtual void sendOutData() override;" << std::endl; // 8. 写入输入数据监听函数 hppFile << "\t" << "void inputDataListener(const " << topicType << " &input);" << std::endl; // 9. 写入获取数据模板函数 hppFile << "\t" << "template " << std::endl; hppFile << "\t" << "void getData(T *model_data)" << std::endl; hppFile << "\t" << "{" << std::endl; hppFile << "\t\t" << "std::lock_guard lock(dataMutex);" << std::endl; hppFile << "\t\t" << "if(model_data == nullptr)" << std::endl; hppFile << "\t\t\t" << "return;" << std::endl; for (const auto &interface : interfaceData) { hppFile << "\t\t" << "assign_value_get(data." << interface.interfaceName << "(), model_data->" << interface.interfaceName << ");" << std::endl; } hppFile << "\t" << "}" << std::endl; // 10. 写入设置数据模板函数 hppFile << "\t" << "template " << std::endl; hppFile << "\t" << "void setData(T *model_data)" << std::endl; hppFile << "\t" << "{" << std::endl; hppFile << "\t\t" << "if(model_data == nullptr)" << std::endl; hppFile << "\t\t\t" << "return;" << std::endl; hppFile << "\t\t" << "std::lock_guard lock(outDataMutex);" << std::endl; hppFile << "\t\t" << "clearOutData();" << std::endl; for (const auto &interface : interfaceData) { hppFile << "\t\t" << "assign_value_set(data." << interface.interfaceName << "(), model_data->" << interface.interfaceName << ");" << std::endl; } hppFile << "\t" << "}" << std::endl; // 11. 写入私有成员变量 hppFile << "" << "protected:" << std::endl; hppFile << "\t" << "DDSType data;" << std::endl; hppFile << "\t" << "DDSType out_data;" << std::endl; // 12. 写入类声明结束 hppFile << "};" << std::endl; // 13. 写入命名空间结束 hppFile << "}" << std::endl; hppFile.close(); return true; } bool DDSInterfaceGen::generateDDSInterfaceCxx(const std::string &nameSpace, const std::string &structName, const std::string &interfaceFolderPath, const std::vector &interfaceData) { std::string className = structName + "_Interface"; std::string topicType = nameSpace + "::" + structName; std::string cxxFilePath = interfaceFolderPath + "/" + structName + ".cxx"; std::ofstream cxxFile(cxxFilePath); // 1. 写入引用头文件 cxxFile << "#include \"" << structName << ".hpp\"" << std::endl; // 2. 写入命名空间 cxxFile << "const std::string " << nameSpace << "::" << className << "::topic_name = \"" << topicType << "\";" << std::endl; cxxFile << "namespace " << nameSpace << std::endl; cxxFile << "{" << std::endl; // 3. 写入类构造函数实现 cxxFile << className << "::" << className << "()" << std::endl; cxxFile << "{" << std::endl; for (const auto &interface : interfaceData) { cxxFile << "\t" << "MAP_DATA_FUNC(" << interface.interfaceName << ");" << std::endl; } cxxFile << "}" << std::endl; // 4. 写入类析构函数实现 cxxFile << className << "::~" << className << "()" << std::endl; cxxFile << "{" << std::endl; cxxFile << "}" << std::endl; // 5. 写入类初始化函数实现 cxxFile << "void " << className << "::Initialize(XNFrameworkPtr framework, uint32_t modelId,uint32_t DDS_type)" << std::endl; cxxFile << "{" << std::endl; cxxFile << "\t" << "auto ddsManager = framework->GetDDSManager();" << std::endl; cxxFile << "\t" << "if (!ddsManager) {" << std::endl; cxxFile << "\t\t" << "LOG_ERROR(\"DDSManager is nullptr\");" << std::endl; cxxFile << "\t\t" << "return;" << std::endl; cxxFile << "\t" << "}" << std::endl; cxxFile << "\t" << "if (DDS_type == 0) {" << std::endl; // 读取与发送都进行 cxxFile << "\t\t" << "dataWriter = ddsManager->RegisterPublisher<" << topicType << "PubSubType>(\"" << topicType << "\", modelId);" << std::endl; cxxFile << "\t\t" << "ddsManager->RegisterSubscriber<" << topicType << "PubSubType>(\"" << topicType << "\", modelId, std::bind(&" << className << "::inputDataListener, this, std::placeholders::_1));" << std::endl; cxxFile << "\t" << "}" << std::endl; cxxFile << "\t" << "else if (DDS_type == 1) {" << std::endl; // 只读取 cxxFile << "\t\t" << "ddsManager->RegisterSubscriber<" << topicType << "PubSubType>(\"" << topicType << "\", modelId, std::bind(&" << className << "::inputDataListener, this, std::placeholders::_1));" << std::endl; cxxFile << "\t" << "}" << std::endl; cxxFile << "\t" << "else if (DDS_type == 2) {" << std::endl; // 只发送 cxxFile << "\t\t" << "dataWriter = ddsManager->RegisterPublisher<" << topicType << "PubSubType>(\"" << topicType << "\", modelId);" << std::endl; cxxFile << "\t" << "}" << std::endl; cxxFile << "}" << std::endl; // 6. 写入清空数据函数实现 cxxFile << "void " << className << "::clearOutData()" << std::endl; cxxFile << "{" << std::endl; cxxFile << "\t" << "this->out_data = " << topicType << "();" << std::endl; cxxFile << "}" << std::endl; // 7. 写入发送数据函数实现 cxxFile << "void " << className << "::sendOutData()" << std::endl; cxxFile << "{" << std::endl; cxxFile << "\t" << "if (dataWriter) {" << std::endl; cxxFile << "\t\t" << "dataWriter->write(&this->out_data);" << std::endl; cxxFile << "\t" << "}" << std::endl; cxxFile << "}" << std::endl; // 8. 写入输入数据监听函数实现 cxxFile << "void " << className << "::inputDataListener(const " << topicType << " &input)" << std::endl; cxxFile << "{" << std::endl; cxxFile << "\t" << "this->data = input;" << std::endl; cxxFile << "}" << std::endl; // 9. 写入命名空间实现结束 cxxFile << "}" << std::endl; cxxFile.close(); return true; }