I'm using the reflection feature of protocol buffer to read message field value at run time.
The proto I have:
package xapp.battle;
message BATTLE_DATA {
repeated AInfo aInfo = 1;
repeated BInfo bInfo = 2;
repeated CInfo cInfo = 3;
// a lot other repeated messages
}
message AInfo {
int32 test_field = 1;
// ......
}
message BInfo {
int32 test_field = 1;
// ......
}
message CInfo {
int32 test_field = 1;
// ......
}
The code now I have:
void DO_SOMETHING(messageName) {
const Descriptor* pDescriptor = BATTLE_DATA->GetDescriptor();
const FieldDescriptor* pMessageField = pDescriptor->FindFieldByName(messageName);
const Reflection* pReflection = BATTLE_DATA->GetReflection();
if (messageName == "aInfo") {
const RepeatedPtrField<::xapp::battle::AInfo> repeated_ptr_field = pReflection->GetRepeatedPtrField<::xapp::battle::AInfo>(*BATTLE_DATA, pMessageField);
for (int i = 0; i < repeated_ptr_field.size(); i ++) {
::xapp::battle::AInfo messageInfo = repeated_ptr_field.Get(i);
// continue to read the test_field value of messageInfo
}
}
else if (messageName == "bInfo") {
const RepeatedPtrField<::xapp::battle::BInfo> repeated_ptr_field = pReflection->GetRepeatedPtrField<::xapp::battle::BInfo>(*BATTLE_DATA, pMessageField);
for (int i = 0; i < repeated_ptr_field.size(); i ++) {
::xapp::battle::BInfo messageInfo = repeated_ptr_field.Get(i);
// continue to read the test_field value of messageInfo
}
}
else if (messageName == "CInfo") {
const RepeatedPtrField<::xapp::battle::CInfo> repeated_ptr_field = pReflection->GetRepeatedPtrField<::xapp::battle::CInfo>(*BATTLE_DATA, pMessageField);
for (int i = 0; i < repeated_ptr_field.size(); i ++) {
::xapp::battle::CInfo messageInfo = repeated_ptr_field.Get(i);
// continue to read the test_field value of messageInfo
}
}
// ......
else {
LOG("loadOneBin - Unknown messageName");
}
}
This code works but obviously it's not the best solution since there are so many repeated "else-if" code blocks.
What I want is something like (at least get rid of those "else-if" blocks):
const RepeatedPtrField<::xapp::battle::MESSAGE_NAME> repeated_ptr_field = pReflection->GetRepeatedPtrField<::xapp::battle::MESSAGE_NAME>(*BATTLE_DATA, pMessageField);
for (int i = 0; i < repeated_ptr_field.size(); i ++) {
::xapp::battle::MESSAGE_NAME messageInfo = repeated_ptr_field.Get(i);
// continue to read the test_field value of messageInfo
}
The source code of GetRepeatedPtrField:
template<typename PB>
inline const RepeatedPtrField<PB>& Reflection::GetRepeatedPtrField(
const Message& message, const FieldDescriptor* field) const {
return *static_cast<RepeatedPtrField<PB>* >(
MutableRawRepeatedField(const_cast<Message*>(&message), field,
FieldDescriptor::CPPTYPE_MESSAGE, -1,
PB::default_instance().GetDescriptor()));
}
Any suggestion will be appreciated, thanks :)
Aucun commentaire:
Enregistrer un commentaire