评论

收藏

c++ java中关于protobuf反序列化对象实体和实体处理(函数)关系(二)

游戏开发 游戏开发 发布于:2021-07-17 22:31 | 阅读数:663 | 评论:0

上一篇中大概描述了c++  java中关于protobuf反序列化对象实体和实体处理(函数)关系,并贴出了java的实现方案,针对c++版本也只是简单的描述了一下 采用std::bind().这里采用 id+ 指针,通过ID索引到指针,利用多态性来处理。
由于c++ 不像java可以有反射,所以这里实例化引用直接用静态的指针。交给编译器处理 在静态的区来开辟储存。大概实现如下:
基类,所有的处理函数controller均实现该类:
#ifndef __BaseController__
    #define __BaseController__

/**
 * @Author 石头哥哥, 15-02-08 17:02:32
 *
 * @brief  creat a single fot controller
 *
 * @param _CLASS_ _CLASS_ controller who had extend base controller
 *
 * @return controller
 */
    #ifndef SINGLE_INSTANCE_FUNC
    #define SINGLE_INSTANCE_FUNC(_CLASS_)\
static _CLASS_* getInstance( ) \
    { \
static _CLASS_* _p = NULL; \
    if(!_p) _p = new _CLASS_( ); \
    return _p; \
    }
    #endif
/*********pb头文件分类***************/
    //pb  header file
    #include "robotServer.pb.h"
/************************/

    #include <stdio.h>
    #include <iostream>
#include "PlayerInstance.h"
    #include <google/protobuf/message.h>
    using namespace std;
    using namespace google_private::protobuf;
    using namespace google_private::protobuf::io;
    #include <cocos2d.h>
    USING_NS_CC;
    #include <map>
/**
 * @Author 石头哥哥, 15-02-08 20:02:48
 *
 * @brief  this is abstract class
 */
class BaseController{

  public:

  BaseController();

  virtual~BaseController();

  /**
   * @Author 石头哥哥, 15-02-07 22:02:00
   *
   * @brief   游戏逻辑处理函数
   *
   * @param player  封装的游戏客户端session对象  player
   * @param message 对应游戏pb实体数据
   */
  virtual void  dispatcherMessage(PlayerInstance&player,const string &message)const=0;

  public:
  static map<int,BaseController*> CONTROLLER_MAPPERS;
  /**
   * @Author 石头哥哥, 15-02-08 20:02:05
   *
   * @brief  <#Description#>
   */
  static void releaseController();
};
#endif /* defined(__BaseController__) */
//
//  BaseController.cpp
//  mygame5
//
//  Created by chenlei on 15/2/7.
//
//
#include "BaseController.h"
map<int,BaseController*> BaseController::CONTROLLER_MAPPERS;
BaseController::BaseController(){
}
BaseController::~BaseController(){}

void BaseController::releaseController(){
//  for (auto iter=begin(CONTROLLER_MAPPERS); iter!=end(CONTROLLER_MAPPERS); ++iter) {
//        cout<<"获取值:"<<iter->second<<"  key: "<<iter->first<<endl;
//  }
//
  for_each(begin(CONTROLLER_MAPPERS), end(CONTROLLER_MAPPERS), [](map<int,BaseController*>::reference entry){// value_type is reference
    CC_SAFE_DELETE(entry.second);
  });
  CONTROLLER_MAPPERS.clear();

}



子类处理 cpp:
//
//  LoginController.cpp
//  mygame5
//
//  Created by chenlei on 15/2/8.
//
//
#include "LoginController.h"
  //init pointer and register function
LoginController *LoginController::_login_controller=new LoginController;
LoginController::LoginController(){
  CONTROLLER_MAPPERS[LoginRequest::ID]=this;
}

/**
 * @Author 石头哥哥, 15-02-08 18:02:35
 *
 * @brief  <#Description#>
 *
 * @param player#>  <#player#> description#>
 * @param message#> <#message#> description#>
 */
void LoginController::dispatcherMessage(PlayerInstance &player,const string &message)const{
  cout<<message<<endl;

/*
 LoginRequest* LoginRequest::New() const {
 return new LoginRequest;
 }
 careful obj must be delete
 */

  LoginRequest * obj=LoginRequest::default_instance().New();
  if (obj->ParsePartialFromString(message)){
      //do something
  }

  //can use cocos2d macros delete pointer
  CC_SAFE_DELETE(obj);
}

.h:
//
//  LoginController.h
//  mygame5
//
//  Created by chenlei on 15/2/8.
//
//
#ifndef _____LoginController__
#define _____LoginController__
#include <stdio.h>
#include "BaseController.h"
class LoginController : public BaseController
{
public:
  LoginController();

public:
  /**
   * @Author 石头哥哥, 15-02-08 18:02:21
   *
   * @brief  <#Description#>
   *
   * @param player  player description
   * @param message message description
   */
   virtual void  dispatcherMessage(PlayerInstance &player,const string &message)const;
private:
    //pointer for hand controller function
  static LoginController *_login_controller;
};
#endif /* defined(_____LoginController__) */
通过一个静态的map来存储对应的引用和消息处理ID。前文也提到在客户端采用map。
以上是解析多个pb实体的方案,有更好的 欢迎讨论。
附 示例pb描述文件:
message LoginRequest {
  enum msgID {
    ID = 2999;
  } //消息编号
  required string username = 1; //用户名
  required string password = 2; //密码
  optional uint64 sendTime=3;//发送消息时间戳
}


关注下面的标签,发现更多相似文章