-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Chapter 6: Data Mapping
In NoahGameFrame's world, we have an advanced data mapping system which relates to the logic class. Do you remember these fields of the property system?
- Id: The prop's name, for example, DogName and HP.
- Cache: True: Save this prop into Redis
- Desc: A short description for this prop, for the designer to easily remember the meaning of this prop.
- Force:
- Private: True: Update data to the client when property changed.
- Public: True: Update data to the clients who near the object (in the view area) when the data changed.
- Ref: True: Reference to another property (please set to false before you know NF deeply)
- Save: True: Save this prop to Mysql or other databases.
- Type: The type of this prop, such as int, float, string, object, vector2, vector3
- Upload: Allow the client to upload prop's data to the server and override the server's data.
Yes, how we data mapping dependence these fields especial the fields Type, Private and Public.
Normally, all complex data struct come from the base data type such as int, float(double), string, vector2, and vector3. Of course, we added a class name NFGUID in NoahGameFrame as the object's identity.
So, we just support six types data as below:
////////////////////////BaseCommon/////////////////////////////
message PropertyInt//The base protocol can not be transfer directly
{
required bytes property_name = 1;
required int64 data = 2;
}
message PropertyFloat//The base protocol cannot be transfer directly
{
required bytes property_name = 1;
required float data = 2;
}
message PropertyString//The base protocol cannot be transfer directly
{
required bytes property_name = 1;
required bytes data = 2;
}
message PropertyObject//The base protocol cannot be transfer directly
{
required bytes property_name = 1;
required Ident data = 2;
}
message PropertyVector2//The base protocol cannot be transfer directly
{
required bytes property_name = 1;
required Vector2 data = 2;
}
message PropertyVector3//The base protocol cannot be transfer directly
{
required bytes property_name = 1;
required Vector3 data = 2;
}
//////////////////
message ObjectPropertyInt
{
required Ident player_id = 1;
repeated PropertyInt property_list = 2;
}
message ObjectPropertyFloat
{
required Ident player_id = 1;
repeated PropertyFloat property_list = 2;
}
message ObjectPropertyString
{
required Ident player_id = 1;
repeated PropertyString property_list = 2;
}
message ObjectPropertyObject
{
required Ident player_id = 1;
repeated PropertyObject property_list = 2;
}
message ObjectPropertyVector2
{
required Ident player_id = 1;
repeated PropertyVector2 property_list = 2;
}
message ObjectPropertyVector3
{
required Ident player_id = 1;
repeated PropertyVector3 property_list = 2;
}
Now we have the data struct designed by Protocol-buf, if we want to send some message we can send these structs to the clients. For example, we want to send the "Level" information to the client, below is the pseudocode:
- We would add the monitor/observer for the property named "Level"
bool NFCHelloWorld2::AfterInit()
{
NFIObject* pObject = new NFCObject(NFGUID(0, 1), pPluginManager);
//add a property for this object, actually, this step will be done automatically by NoahGaneFrame
pObject->GetPropertyManager()->AddProperty(pObject->Self(), "Level", TDATA_INT);
//add a callback function for "Level" property
pObject->AddPropertyCallBack("Level", this, &NFCHelloWorld2::OnPropertyCallBackEvent);
//set the "world" property value as 2222[than the function "HelloWorld2::OnPropertyCallBackEvent" will be called]
pObject->SetPropertyInt("World", 2222);
}
int NFCHelloWorld2::OnPropertyCallBackEvent( const NFGUID& self, const std::string& strProperty, const NFData& oldVar, const NFData& newVar)
{
std::cout << "OnPropertyCallBackEvent Property: " << strProperty << " OldValue: " << oldVar.GetInt() << " NewValue: " << newVar.GetInt() << std::endl;
return 0;
}
- We pack the message body as a string stream by Protocol-buf
int NFCHelloWorld2::OnPropertyCallBackEvent( const NFGUID& self, const std::string& strProperty, const NFData& oldVar, const NFData& newVar)
{
std::cout << "OnPropertyCallBackEvent Property: " << strProperty << " OldValue: " << oldVar.GetInt() << " NewValue: " << newVar.GetInt() << std::endl;
NFMsg::MultiObjectPropertyList xPublicMsg;
NFMsg::MultiObjectPropertyList xPrivateMsg;
NFMsg::ObjectPropertyList* pPublicData = xPublicMsg.add_multi_player_property();
NFMsg::ObjectPropertyList* pPrivateData = xPrivateMsg.add_multi_player_property();
if (pPropertyInfo->GetPublic())
{
NFMsg::PropertyInt* pDataInt = pPublicData->add_property_int_list();
pDataInt->set_property_name(pPropertyInfo->GetKey());
pDataInt->set_data(pPropertyInfo->GetInt());
}
if (pPropertyInfo->GetPrivate())
{
NFMsg::PropertyInt* pDataInt = pPrivateData->add_property_int_list();
pDataInt->set_property_name(pPropertyInfo->GetKey());
pDataInt->set_data(pPropertyInfo->GetInt());
}
return 0;
}
- We send the string stream to the client by networking and the user's ID.
SendMsgPBToGate(NFMsg::EGMI_ACK_OBJECT_PROPERTY_ENTRY, xPrivateMsg, identOther);
Actually, we can add the observer for all props when a object has been created, then we just one module can help us to send the message to the clients, this data mapping.