上一篇中大概描述了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;//发送消息时间戳
}
|