Skip to content

Chapter 3: Introduction to Property Management

kytooooo edited this page Mar 29, 2021 · 5 revisions

The purpose of NF's original design was to have a way to manage objects and data in a unified manner, and use a unified interface without the need to expand new interfaces and data fields as the business grew. This idea came from Ogre's concept of a Node. After also learning from Bigworld's data management methods, abstractions NFIClass, NFIObject and NFIElementModule were designed, which are the most important three classes of NF and important cornerstones supporting NF's concept of data-oriented programming.

In the bad old days, the programmer had to write all the classes by hand, for example:

If the business needed us to write a dog class, below we would write:

class Dog
{
    int nDogID;
    std::string strDogName;
};

One day, the designers have a new idea, our dogs need HP and MP! Then we do these below:

class Dog
{
    int nDogID;
    int nMaxHP;
    int nHP;
    int nMaxMP;
    int nMP;

    std::string strDogName;
};

Another day the designer said: our dogs need friends! Then we do these below:

class DogFriend
{
    int nDogID;
    std::string strDogName;
};

class Dog
{
    int nDogID;
    int nMaxHP;
    int nHP;
    int nMaxMP;
    int nMP;

    std::string strDogName;

    std::list<DogFriend> lDogFriendList;
};

It's a hard time for developer especially when the class needs change again and again.

Today, I'd like to talk about the new concept: logic classes!

No need to hard-code in many properties like above! No need to write code for saving/loading properties to the database! No need to write any code for broadcasting their property to others! It's logic classes! Up next, we will have a magical journey into NoahGameFrame's world, hold onto your seats!

Generally speaking, all classes are logic classes in NoahGameFrame's world, because a class named NFIProperty/NFCProperty can support any kind of property. Take a look at the example below:

class NFIProperty
{
    int64 GetInt();
    float GetFloat();
    string GetString();
    GUID GetObject();

    void SetInt(Int64 value);
    void SetFloat(float value);
    void  SetString(string value);
    void SetObject(GUIDvalue);
};

class Dog
{
    NFIProperty DogID;
    NFIProperty MaxHP;
    NFIProperty HP;
    NFIProperty MaxMP;
    NFIProperty MP;

    NFIProperty DogName;
};

Next, we can use a PropertyManager to manage these properties:

class NFPropertyManager
{
    bool AddProp(const std::string& strPropName);
    NFIProperty GetProp(const std::string& strPropName);

    std::map<std::string, NFIProperty>
};

class Dog
{
    Dog()
    {
        mPropertyManager.AddProp(DogID);
        mPropertyManager.AddProp(MaxHP);
        mPropertyManager.AddProp(HP);
        mPropertyManager.AddProp(MaxMP);
        mPropertyManager.AddProp(MP);
        mPropertyManager.AddProp(DogName);
    }

    NFPropertyManager mPropertyManager;
};

All that's left is to use a JSON or XML file to configure these properties rather than call the function NFPropertyManager::AddProp for each property. We just use a module for loading the XML file describing a class's properties and call NFPropertyManager::AddProp on each property automatically.

Here is an example XML file for our dog class:

<?xml version='1.0' encoding='utf-8' ?>
<XML>
    <Propertys>
        <Property Id="DogID" Cache="0" Desc="Dog's ID" Force="0" Private="0" Public="0" Ref="0" Save="0" Type="string" Upload="0" />
        <Property Id="MaxHP" Cache="0" Desc="Dog's MaxHP" Force="0" Private="0" Public="0" Ref="0" Save="0" Type="string" Upload="0" />
        <Property Id="HP" Cache="0" Desc="Dog's HP" Force="0" Private="0" Public="0" Ref="0" Save="0" Type="int" Upload="0" />
        <Property Id="MaxMP" Cache="0" Desc="Dog's MaxMP" Force="0" Private="0" Public="0" Ref="0" Save="0" Type="int" Upload="0" />
        <Property Id="MP" Cache="0" Desc="Dog's MP" Force="0" Private="0" Public="0" Ref="0" Save="0" Type="int" Upload="0" />
        <Property Id="DogName" Cache="0" Desc="Dog's Name" Force="0" Private="0" Public="0" Ref="0" Save="0" Type="int" Upload="0" />
    </Propertys>
</XML>

At the sasmetime, a C++ file like below will be generated by tools (other languages such as java, c# and ts too)

	class IObject
	{
	public:
		//Class name
		static const std::string& ThisName(){ static std::string x = "IObject"; return x; };		// Property
		static const std::string& CampID(){ static std::string x = "CampID"; return x; };// object
		static const std::string& ClassName(){ static std::string x = "ClassName"; return x; };// string
		static const std::string& ConfigID(){ static std::string x = "ConfigID"; return x; };// string
		static const std::string& Disable(){ static std::string x = "Disable"; return x; };// int
		static const std::string& GMMoveTo(){ static std::string x = "GMMoveTo"; return x; };// vector3
		static const std::string& GroupID(){ static std::string x = "GroupID"; return x; };// int
		static const std::string& ID(){ static std::string x = "ID"; return x; };// string
		static const std::string& MasterID(){ static std::string x = "MasterID"; return x; };// object
		static const std::string& MoveTo(){ static std::string x = "MoveTo"; return x; };// vector3
		static const std::string& Name(){ static std::string x = "Name"; return x; };// string
		static const std::string& Position(){ static std::string x = "Position"; return x; };// vector3
		static const std::string& SceneID(){ static std::string x = "SceneID"; return x; };// int
		static const std::string& State(){ static std::string x = "State"; return x; };// int
		// Record

	};

What do all these fields mean?

  • 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 the property changed.
  • Public: True: Broadcast the 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 value to the server and override the prop value on the server side.