XNSim/XNInterfaceGenServer/DDSInterfaceGen.cpp

182 lines
8.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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> &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 << " final : public XNDDSInterface" << std::endl;
hppFile << "{" << std::endl;
hppFile << "public:" << 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 <typename T>" << std::endl;
hppFile << "\t" << "void getData(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;
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 <typename T>" << 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" << "clearOutData();" << std::endl;
for (const auto &interface : interfaceData) {
hppFile << "\t\t" << "assign_value_set(data." << interface.interfaceName
<< "(), model_data->" << structName << ");" << std::endl;
}
hppFile << "\t" << "}" << std::endl;
// 11. 写入私有成员变量
hppFile << "" << "private:" << std::endl;
hppFile << "\t" << topicType << " data;" << std::endl;
hppFile << "\t" << topicType << " 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> &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 << "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;
}
//TODO 这里先待定
cxxFile << "\t" << "this->header[0] = 0xa6; // XNSim头0xa6" << std::endl;
cxxFile << "\t" << "this->header[1] = 0xc0; // 机型头0xc0表示C909" << std::endl;
cxxFile << "\t" << "this->header[2] = 0x04; // 章节头0x04表示ATA04" << std::endl;
cxxFile << "\t" << "this->header[3] = 0x01; // 模型头0x01表示GroundHandling" << std::endl;
cxxFile << "\t" << "this->header[4] = 0x00; // 结构体头0x00表示输入结构体" << std::endl;
cxxFile << "\t" << "this->header[5] = 0x00; // 数据方向0x00表示外部输入" << std::endl;
cxxFile << "\t" << "this->header[6] = 0x00; // 数据大小" << std::endl;
cxxFile << "\t" << "this->header[7] = 0x00; // 数据大小" << 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;
}