mercredi 11 mars 2015

protocol buffer GetRepeatedField (reflection) code optimization

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