c++ java中關於protobuf反序列化對象實體和實體處理(函數)關係 (一)

網絡遊戲中無論採用什麼語言開發 ,序列化和反序列化工具 google的 flatbuff 和protobuf 都是首選!java

flatbuf後起之秀和protobuf中有一個共同的特性,那就是在遊戲開發中對應的發序列化後的實體和對應的處理函數的對應關係。c++

能夠採用傳統的if else or switch case,若是 可是在實際的場景中要求快速響應。上述確定是不可以知足實際的開發需求。遊戲中區分消息以及消息對應的處理函數都是經過ID來查找。一般設計方案有以下2種:spring

1.用數組來存儲,ID做爲數組下標,對應處理函數或則對應處理函數的引用做爲存儲值。編程

2.經過map來存儲。ID作key,對應處理函數或則對應處理函數的引用做爲存儲值。 數組

兩種數據結構,。針對java c++ 高級的編程語言(支持多態)處理都不錯。不過有一點要注意,java中不可以存儲function。因此在對應的2中方案中對應的值應該是處理函數的引用!這點要注意。c++ 則不一樣,能夠存儲引用或則function。 服務器

這裏遊戲數據包結構:packageLength +ID+message,其中packageLength爲ID和message數據的總長度。 網絡

遊戲中在業務層分發數據的時候,先解析出ID,而後經過上面的2中方式獲取對應處理函數或則對應處理函數的引用做爲存儲值。調用處理函數,將對應的消息派發出去。 session

通常處理函數能夠定義爲void (session ,message);---這裏 本身根據實際的場景來定義吧,seesion一般是一個player ? client 什麼的,message 就是對應的那個pb實體消息類型--- 能夠在分發的時候將字節數組轉化爲pb實體,亦能夠在業務處理函數層轉化。 數據結構

下面具體解析下處理數據和pb實體的關係處理(主要用數組方式,map是同樣的處理): 編程語言

首先全局初始化一個靜態的數組(c++版本):

typedef  function<void(int  , int )> DispatcherMessage;
static DispatcherMessage *array_message_hand_ref = new DispatcherMessage[1000];


業務處理函數


void testFunctionMap2(int a, int b){
	cout << "std::bind call 2 value of a ,b--->" << a << "," << b << endl;
}



對應的初始化ID和function或則引用。(這裏的初始化 要注意選擇合適的位置和時間 一般在程序初始化的時候)


array_message_hand_ref[2] = std::bind(&testFunctionMap2, std::placeholders::_1,
		std::placeholders::_2);;



當業務層解析到ID 和對應的消息以後如這裏是ID==2:

array_message_hand_ref[2](2,3);



這樣就完成了數據的派發。

對於java,採用數組的方式應該用兩個數組,ID 做爲下標。利用java的多態性。

首先獲取對應的引用,調用基類的函數,完成數據派發。

以上2中方案只做爲參考。歡迎討論。

後續。。。。

java 實現方案參考:

/**
 * Created by 石頭哥哥 on 2015/2/7.
 * Content:  測試泛型接口
 */
public interface Function<T extends Object, M extends Message> {


    /**
     * 處理遊戲邏輯接口
     *
     * @param session
     * @param message
     */
    void DispatcherMessage(T session, M message);
}

 

全部實例處理均繼承該類並實現對應的方法

import com.google.protobuf.Message;
import javolution.util.FastMap;

import javax.annotation.PostConstruct;

/**
 * Created by 石頭哥哥 on 2015/2/7.
 * Content:
 */
public abstract class BaseController implements Function<Player, Message> {

    public static FastMap<Integer, Function<Player, Message>> MAP_FUNCTIONS = new FastMap<Integer, Function<Player, Message>>();

    /**
     * 負責初始化  ID 和 處理實體的關係
     */
    @PostConstruct
    protected abstract void PreIntiFunction();

}


import com.google.protobuf.Message;
import org.springframework.stereotype.Service;

/**
 * Created by 石頭哥哥 on 2015/2/7.
 * Content:
 */
@Service
public class TestController extends BaseController {


    @Override
    protected void PreIntiFunction() {
        MAP_FUNCTIONS.put(1, this);  //初始化ID 和 實體處理函數關係
    }

    /**
     * 處理遊戲邏輯接口
     *
     * @param session
     * @param message
     */
    @Override
    public void DispatcherMessage(Player session, Message message) {
    }
}


public class Player {
}


注意java實現的方案 ,初始化 依賴了spring 整個遊戲對象存在spring容器管理,這裏只實現了基於map的方案,服務器要求快速相應 仍是推薦選擇數組方案 空間換時間,若是是客戶端建議用map,內存不足狀況下 尤爲是手機平臺。 技術選型 本身決定!!!

相關文章
相關標籤/搜索