优化背景,游戏需要做一个旁观功能,那么需要修改的地方有入座和广播。目前看代码是有110个麻将和牌类,代码相似度99.9%,只有一个枚举不一样(游戏id).
功能是很简单,入座的协议加个字段是否旁边,广播的时候给旁边的玩家也发消息。但是涉及到一百多个游戏,我也可以每个游戏都改一遍,但是如果有bug,或者还需要修改,不是很麻烦吗。
所以必须把相同的代码抽出来形成通用函数,每个游戏调用通用函数,不一样的再特殊处理。
接收消息的地方只有一行代码不一样,游戏id
每个游戏都有一个 CommonClienthandler.cpp
ENHandlerResult CRequestEnterTable::ProcessUpdateSucc(CHandlerTokenBasic* ptoken, CSession* psession)
{
if (psession->_fsm_state == EN_EnterTable_State_ULOCK)
{
PBCSMsg msg;
CSResponseDssEnterTable& response = *msg.mutable_cs_response_dss_enter_table();
response.set_result(EN_MESSAGE_TABLE_NOT_EXIST);
Message::SendResponseMsg(RouteManager::Instance()->GetRouteByRandom(), psession, msg);
return EN_Handler_Done;
}
else if (psession->_fsm_state == EN_EnterTable_State_ULOCK_AF_SAVE)
{
PBCSMsg msg;
CSResponseEnterTable& response = *msg.mutable_cs_response_enter_table();
response.set_result(EN_MESSAGE_NO_EMPTY_SEAT);
Message::SendResponseMsg(RouteManager::Instance()->GetRouteByRandom(), psession, msg);
return EN_Handler_Done;
}
long long uid = psession->_request_route.uid();
const PBUser& user = psession->_kvdb_uid_data_map[uid].user_info();
const CSRequestDssEnterTable& cs_request_enter_table = psession->_request_msg.cs_request_dss_enter_table();
int tid = cs_request_enter_table.tid();
int connect_id = cs_request_enter_table.connect_id();
PBCSMsg msg;
CSResponseDssEnterTable& response = *msg.mutable_cs_response_dss_enter_table();
// const PBBPlayerPositionInfo & pos = user.pos();
// if(pos.pos_type() == EN_Position_DSS_Xj && pos.table_id() != 0)
// {
// tid = pos.table_id();
// }
CPBGameTable* ptable = TableManager::Instance()->FindTable(tid);
if (ptable == NULL)
{
return EN_Handler_Done;
}
PBDSSTableSeat* pseat = TableLogic::FindEmptySeatInTable(*ptable);
if (pseat == NULL)
{
psession->_fsm_state = EN_EnterTable_State_ULOCK_AF_SAVE;
PBUpdateData update;
update.set_key(PBUserDataField::kUserInfo);
{
PBDBAtomicField& field = *update.add_field_list();
field.set_field(EN_DB_Field_POS);
PBBPlayerPositionInfo& pos = *field.mutable_pos();
pos.set_pos_type(EN_Position_Hall);
pos.set_table_id(0);
pos.set_gamesvrd_id(0);
}
psession->NewAddUpdateData(psession->_request_route.uid(), update);
return EN_Handler_Save;
}
const PBUserTeaBarData& tbdata = psession->_kvdb_uid_data_map[uid].user_tea_bar_data();
//竞技场,记录玩家来自哪个亲友圈
if(ptable->config().is_arena())
{
pseat->mutable_src_tea_bar()->set_tbid(cs_request_enter_table.src_tbid());
pseat->mutable_src_tea_bar()->mutable_tb_master()->set_uid(cs_request_enter_table.src_tb_master_uid());
}
TableLogic::SitDownOnTable(*ptable,*pseat,user,tbdata,connect_id);
CSNotifyTableInfo& info = *response.mutable_table_info();
TableLogic::CopyTableToNotify(*ptable, info, uid);
response.set_result(EN_MESSAGE_ERROR_OK);
response.set_gamesvrd_id(TGlobal::_svid);
response.set_pos_type(EN_Position_DSS_Xj);
Message::SendResponseMsg(RouteManager::Instance()->GetRouteByRandom(), psession, msg);
return EN_Handler_Done;
}
这个代码抽出来是比较简单,但是要能正常运行并没有那么简单,因为这里还有
TableLogic::CopyTableToNotify(*ptable, info, uid); TableLogic::FindEmptySeatInTable(*ptable); TableLogic::CopyTableToNotify(*ptable, info, uid);
三个函数调用,这三个TableLogic也是每个游戏都有一份,,。。代码相识度100%... 同理 CPBGameTable* ptable = TableManager::Instance()->FindTable(tid); 这也是一个相识度100%代码的一个函数调用,是本地的另外一个文件。那么这些代码也必须抽出来
1.先把消息处理的代码抽出来吧
Clienthandlerbase.h
//
// Author: baiyufei
// Date: 2022-08-25 15:00:00
// 前端协议的通用处理,防止重复代码
//
#pragma once
#include "poker_msg.pb.h"
#include "NewProcessor.h"
namespace base
{
enum EN_EenterTable_State
{
EN_EnterTable_State_ULOCK = 1,
EN_EnterTable_State_ENTERING = 2,
EN_EnterTable_State_ULOCK_AF_SAVE = 3,
};
}
class Clienthandlerbase
{
private:
/* data */
public:
Clienthandlerbase(/* args */);
~Clienthandlerbase();
static Clienthandlerbase* Instance() {static Clienthandlerbase gInstance; return &gInstance;}
public:
bool cs_response_dss_enter_table(CSession* psession, PBDSSGameTable** ptable, PBDSSTableSeat** pseat, ENPlayerPositionType gameId);
};
Clienthandlerbase.cpp
#include "Clienthandlerbase.h"
#include "TableMgrbase.h"
using namespace base;
Clienthandlerbase::Clienthandlerbase(/* args */)
{
}
Clienthandlerbase::~Clienthandlerbase()
{
}
bool Clienthandlerbase::cs_response_dss_enter_table(CSession* psession, PBDSSGameTable** ptable, PBDSSTableSeat** pseat, ENPlayerPositionType gameId)
{
if (psession->_fsm_state == EN_EnterTable_State_ULOCK)
{
PBCSMsg msg;
CSResponseDssEnterTable& response = *msg.mutable_cs_response_dss_enter_table();
response.set_result(EN_MESSAGE_TABLE_NOT_EXIST);
Message::SendResponseMsg(RouteManager::Instance()->GetRouteByRandom(), psession, msg);
return false;
}
else if (psession->_fsm_state == EN_EnterTable_State_ULOCK_AF_SAVE)
{
PBCSMsg msg;
CSResponseEnterTable& response = *msg.mutable_cs_response_enter_table();
response.set_result(EN_MESSAGE_NO_EMPTY_SEAT);
Message::SendResponseMsg(RouteManager::Instance()->GetRouteByRandom(), psession, msg);
return false;
}
const CSRequestDssEnterTable& cs_request_enter_table = psession->_request_msg.cs_request_dss_enter_table();
int tid = cs_request_enter_table.tid();
*ptable = TableMgrbase::Instance()->FindTable(tid);
if(NULL == ptable)
return false;
*pseat = TableMgrbase::Instance()->FindEmptySeatInTable(**ptable, cs_request_enter_table.observe());
if(NULL == pseat)
{
psession->_fsm_state = EN_EnterTable_State_ULOCK_AF_SAVE;
PBUpdateData update;
update.set_key(PBUserDataField::kUserInfo);
{
PBDBAtomicField& field = *update.add_field_list();
field.set_field(EN_DB_Field_POS);
PBBPlayerPositionInfo& pos = *field.mutable_pos();
pos.set_pos_type(EN_Position_Hall);
pos.set_table_id(0);
pos.set_gamesvrd_id(0);
}
psession->NewAddUpdateData(psession->_request_route.uid(), update);
return false;
}
long long uid = psession->_request_route.uid();
//竞技场,记录玩家来自哪个亲友圈
if((**ptable).config().is_arena())
{
(**pseat).mutable_src_tea_bar()->set_tbid(cs_request_enter_table.src_tbid());
(**pseat).mutable_src_tea_bar()->mutable_tb_master()->set_uid(cs_request_enter_table.src_tb_master_uid());
}
const PBUser& user = psession->_kvdb_uid_data_map[uid].user_info();
int connect_id = cs_request_enter_table.connect_id();
const PBUserTeaBarData& tbdata = psession->_kvdb_uid_data_map[uid].user_tea_bar_data();
TableMgrbase::Instance()->SitDownOnTable(**ptable,**pseat,user,tbdata,connect_id);
PBCSMsg msg;
CSResponseDssEnterTable& response = *msg.mutable_cs_response_dss_enter_table();
CSNotifyTableInfo& info = *response.mutable_table_info();
TableMgrbase::Instance()->CopyTableToNotify(**ptable, info, uid);
response.set_result(EN_MESSAGE_ERROR_OK);
response.set_gamesvrd_id(TGlobal::_svid);
response.set_pos_type(gameId);
Message::SendResponseMsg(RouteManager::Instance()->GetRouteByRandom(), psession, msg);
return true;
}
再把 TableLogic和TableManager的代码抽出来形成TableMgrbase
TableMgrbase.h
//
// Author: baiyufei
// Date: 2022-08-25 15:00:00
// 桌子的通用逻辑(其他游戏的所有桌子数据在这里都有一个指针备份)
//
#pragma once
#include "poker_msg.pb.h"
#include <map>
#include "../core/include/Timer_Handler_Base.h"
using namespace std;
using google::protobuf::RepeatedField;
using google::protobuf::RepeatedPtrField;
typedef long long int64;
typedef int int32;
namespace base
{
#define REPORT_AT_PLAY_TIMER 10000
typedef map<int64, PBDSSGameTable*> baseTableMap;
typedef map<int64, int64> baseUserTableMap;
enum ENGameServiceState
{
EN_Game_Service_State_IDEL = 1,
EN_Game_Service_State_Connecting = 2,
EN_Game_Service_State_Registing = 3,
EN_Game_Service_State_Ready = 4,
EN_Game_Service_State_Working = 5,
EN_Game_Service_State_Retired = 6,
};
}
class TableMgrbase
{
private:
/* data */
public:
TableMgrbase(/* args */);
~TableMgrbase();
static TableMgrbase* Instance();
public:
void Init();
PBDSSGameTable* FindTable(int64 tid);
void ReportGameInfo();
public:
//如果要用通用的桌子逻辑,其他游戏new桌子的时候一定要调用addTable在这里备份一个数据
void addTable(int64 tid, PBDSSGameTable* pPBDSSGameTable);
public:
void SitDownOnTable(PBDSSGameTable & table,PBDSSTableSeat & seat,const PBUser & user,const PBUserTeaBarData& tbdata,int connect_id = 1);
//如果是茶馆房间,刷新下茶馆人数,并且设置备注
void RefreshTeabarTableDisplay(PBDSSGameTable& table, bool is_need_refesh_play_num);
void BroadcastTableMsg(const PBDSSGameTable& table, PBCSMsg& notify, int excepted_uid = 0);
//找一个空位置
PBDSSTableSeat* FindEmptySeatInTable(PBDSSGameTable& table, bool observe);
void CopyTableToNotify(const PBDSSGameTable& table, CSNotifyTableInfo& info, int uid);
//座位判断与状态统计
int GetPlayerNumByState(const PBDSSGameTable& table, ENSeatState expected_state);
PBDSSAction& GetLastActionInFlow(PBDSSGameTable& table);
const PBDSSAction* GetLastActionInFlow(const PBDSSGameTable& table);
public:
base::baseTableMap _tablemap;
base::ENGameServiceState _state;
public:
int64 start_stamp;
};
TableMgrbase.cpp
#include "TableMgrbase.h"
#include "../core/include/global.h"
#include "NewProcessor.h"
#include "RouteManager.h"
#include "global.h"
#include "../svr/common/LogWriter.h"
TableMgrbase::TableMgrbase(/* args */)
{
}
TableMgrbase::~TableMgrbase()
{
}
void TableMgrbase::Init()
{
}
TableMgrbase* TableMgrbase::Instance()
{
static TableMgrbase gInstance;
return &gInstance;
}
PBDSSGameTable* TableMgrbase::FindTable(int64 tid)
{
if (_tablemap.find(tid) == _tablemap.end())
{
return NULL;
}
PBDSSGameTable* table = _tablemap[tid];
return table;
}
void TableMgrbase::addTable(int64 tid, PBDSSGameTable* pPBDSSGameTable)
{
if (NULL == pPBDSSGameTable || _tablemap.find(tid) != _tablemap.end())
{
return;
}
_tablemap[tid] = pPBDSSGameTable;
}
void TableMgrbase::ReportGameInfo()
{
if (_state == base::EN_Game_Service_State_Retired)
{
return;
}
PBCSMsg msg;
SSReportGameSvrdInfo& ss_report_gamesvrd_info = *msg.mutable_ss_report_game_info();
ss_report_gamesvrd_info.set_gameid(TGlobal::_svid);
ss_report_gamesvrd_info.set_gtype(TGlobal::_svrd_type);
Message::PushInnerMsg(RouteManager::Instance()->GetRouteByRandom(), 0, msg, EN_Node_Room, 1);
}
void TableMgrbase::SitDownOnTable(PBDSSGameTable & table, PBDSSTableSeat & seat, const PBUser & user, const PBUserTeaBarData& tbdata, int connect_id /*= 1*/)
{
//玩家坐下
PBTableUser& tableuser = *seat.mutable_user();
tableuser.set_uid(user.uid());
tableuser.set_nick(user.nick());
tableuser.set_role_picture_url(user.pic_url());
tableuser.set_acc_type(user.acc_type());
tableuser.set_channel(user.channel());
tableuser.set_last_login_ip(user.last_login_ip());
tableuser.set_gender(user.gender());
tableuser.set_chip(user.chips());
tableuser.set_connect_id(connect_id);
tableuser.set_items_info(user.items_info());
if(tbdata.brief_data_size() > 0)
{
for(int i = 0; i < tbdata.brief_data_size(); i++)
{
tableuser.mutable_tbid_list()->Add(tbdata.brief_data(i).tbid());
}
}
seat.set_state(EN_SEAT_STATE_WAIT_FOR_NEXT_ONE_GAME);
seat.set_final_score(0);
seat.set_total_score(0);
if (seat.switch_voices_size() != table.seats_size())
{
seat.mutable_switch_voices()->Resize(table.seats_size(), true);
}
//OnPlayerEnterTable(user.uid(),table.tid());
//如果是茶馆房间,刷新下茶馆人数,并且设置备注
if (table.config().has_tbid() && table.config().has_master_uid())
{
long long tbid = table.config().tbid();
if(table.config().is_arena())
{
tbid = seat.src_tea_bar().tbid();
}
for(int i = 0; i < tbdata.brief_data_size(); i++)
{
if(tbid == tbdata.brief_data(i).tbid())
{
tableuser.set_remark(tbdata.brief_data(i).remarks());
//设置魅力值
if(table.config().has_rpf())
{
seat.set_bind_cooperator_uid(tbdata.brief_data(i).bind_cooperator_uid());
seat.set_charm_score(tbdata.brief_data(i).charm_score() * 100);
seat.set_is_hide_charm_score(tbdata.brief_data(i).is_hide_charm_score());
ErrMsg("当前魅力值[%ld], uid[%ld], tid[%ld], tbid[%ld]", seat.charm_score(), seat.user().uid(), table.tid(), tbdata.brief_data(i).tbid());
}
//设置魅力值
if(table.config().has_rmf())
{
int64 rank_score = 0;
if(tbdata.brief_data(i).rank_score_info().match_id() == table.config().rmf().match_id())
{
rank_score = tbdata.brief_data(i).rank_score_info().rank_score();
}
seat.set_rank_score(rank_score);
seat.set_is_hide_charm_score(tbdata.brief_data(i).is_hide_charm_score());
VLogMsg(CLIB_LOG_LEV_DEBUG, "当前比赛分[%ld], uid[%ld], tid[%ld], tbid[%ld] tbdata.brief_data(i).rank_score_info().match_id():%d table.config().has_rmf().match_id():%d ", seat.rank_score(), seat.user().uid(), table.tid(), tbdata.brief_data(i).tbid(),tbdata.brief_data(i).rank_score_info().match_id(), table.config().rmf().match_id());
}
break;
}
}
RefreshTeabarTableDisplay(table, true);
}
//刷新茶馆玩家游戏状态
if(tbdata.brief_data_size() > 0)
{
PBCSMsg msg_teabar;
SSNotifyTeaBarUserGameState& teabar_notify = *msg_teabar.mutable_ss_notify_tea_bar_user_game_state();
teabar_notify.set_uid(user.uid());
if(table.config().is_arena())
{
teabar_notify.set_game_state(3);
}
else
{
teabar_notify.set_game_state(1);
}
teabar_notify.mutable_tbid_list()->CopyFrom(tableuser.tbid_list());
Message::PushInnerMsg(RouteManager::Instance()->GetRouteByRandom(), 0, msg_teabar, EN_Node_TeaBar, 1);
}
//广播玩家坐下
PBCSMsg msg;
CSNotifySitDown& notify_sit_down = *msg.mutable_cs_notify_sit_down();
notify_sit_down.mutable_dss_seat()->CopyFrom(seat);
BroadcastTableMsg(table, msg, user.uid());
return;
}
void TableMgrbase::RefreshTeabarTableDisplay(PBDSSGameTable& table, bool is_need_refesh_play_num)
{
//如果是茶馆房间,刷新下茶馆人数,并且设置备注
if (table.config().has_tbid() && table.config().has_master_uid())
{
PBCSMsg notify;
SSNotifyTeaBarTablePlayerNum& ss_notify_teabar_table_player_num = *notify.mutable_ss_notify_teabar_table_player_num();
ss_notify_teabar_table_player_num.mutable_conf()->CopyFrom(table.config());
ss_notify_teabar_table_player_num.set_tid(table.tid());
if (is_need_refesh_play_num)
{
ss_notify_teabar_table_player_num.set_player_num(table.seats_size() - GetPlayerNumByState(table, EN_SEAT_STATE_NO_PLAYER));
}
for (int i = 0; i < table.seats_size(); i++)
{
if (table.seats(i).state() == EN_SEAT_STATE_NO_PLAYER)
continue;
PBTeaBarUser& user = *ss_notify_teabar_table_player_num.add_users();
user.set_uid(table.seats(i).user().uid());
user.set_name(table.seats(i).user().nick());
user.set_url(table.seats(i).user().role_picture_url());
user.set_remarks(table.seats(i).user().remark());
user.set_is_online(!table.seats(i).user().is_offline());
user.set_total_score(table.seats(i).total_score());
}
ss_notify_teabar_table_player_num.set_round(table.round());
Message::PushInnerMsg(RouteManager::Instance()->GetRouteByRandom(), 0, notify, EN_Node_TeaBar, 1);
}
return;
}
void TableMgrbase::BroadcastTableMsg(const PBDSSGameTable& table, PBCSMsg& notify, int excepted_uid)
{
for (int i = 0; i < table.seats_size(); i++)
{
const PBDSSTableSeat& seat = table.seats(i);
if (seat.state() == EN_SEAT_STATE_NO_PLAYER)
{
continue;
}
const PBTableUser& user = seat.user();
if (user.uid() != excepted_uid && user.is_offline() == false)
{
VLogMsg(CLIB_LOG_LEV_DEBUG, "broadcast msg[0x%x] to user[%ld].seat index[%d]", notify.msg_union_case(), user.uid(), i);
{
Message::PushMsg(RouteManager::Instance()->GetRouteByRandom(), seat.user().uid(), notify, EN_Node_Connect, seat.user().connect_id());
}
}
}
}
PBDSSTableSeat* TableMgrbase::FindEmptySeatInTable(PBDSSGameTable& table, bool observe)
{
PBDSSTableSeat* pSeat = NULL;
if(observe)
{
pSeat = table.add_observe();
pSeat->set_observe(true);
return pSeat;
}
for (int i = 0; i < table.seats_size(); i++)
{
PBDSSTableSeat& seat = *table.mutable_seats(i);
if (seat.state() == EN_SEAT_STATE_NO_PLAYER)
{
pSeat = & seat;
pSeat->set_observe(false);
break;
}
}
return pSeat;
}
void TableMgrbase::CopyTableToNotify(const PBDSSGameTable& table, CSNotifyTableInfo& info, int uid)
{
for (int i = 0; i < table.seats_size(); i++)
{
PBDSSTableSeat& seat = *info.add_dss_seats();
seat.CopyFrom(table.seats(i));
if (seat.user().is_offline())
{
seat.set_offline_timer(time(NULL) - seat.offline_time());
}
if (seat.state() != EN_SEAT_STATE_NO_PLAYER && seat.user().uid() != uid)
{
for (int j = 0; j < seat.hand_cards_size(); j++)
{
seat.set_hand_cards(j, 0);
}
seat.clear_action_choice();
}
seat.clear_switch_voices();
}
for(int i = 0;i<table.seats_size();i++)
{
if(table.seats(i).state()!=EN_SEAT_STATE_NO_PLAYER && table.seats(i).user().uid() == uid)
{
info.mutable_self_switch_voices()->CopyFrom(table.seats(i).switch_voices());
}
}
info.mutable_out_cards()->CopyFrom(table.out_cards());
info.set_display_anpai(table.display_anpai());
info.set_state(table.state());
info.set_round(table.round());
if (table.dealer_index_2() != -1)
{
RepeatedField<int> di_src;
for (int i = 0; i < table.cards_size() && i < 3; i++)
{
di_src.Add(table.cards(i));
}
info.mutable_cards()->CopyFrom(di_src);
}
else
{
int zhua_cards_size = table.config().lai_zi_num() > 0 ? 4 : 3;
info.mutable_cards()->Resize(zhua_cards_size, 0);
}
if (table.total_action_flows_size() > 0)
{
for (int i = table.total_action_flows_size() - 1; i >= 0; i--)
{
if (table.total_action_flows(i).action().act_type() == EN_DSS_ACTION_PASS
&& table.total_action_flows(i).action().is_single_over())
{
for (int j = i + 1; j < table.total_action_flows_size(); j++)
{
info.add_dss_total_action_flows()->CopyFrom(table.total_action_flows(j));
}
break;
}
if (i == 0 && info.dss_total_action_flows_size() == 0)
{
for (int j = 0; j < table.total_action_flows_size(); j++)
{
if (table.total_action_flows(j).action().act_type() == EN_DSS_ACTION_QIANG_DI_ZHU
|| table.total_action_flows(j).action().act_type() == EN_DSS_ACTION_BU_QIANG)
{
if (table.state() == EN_TABLE_STATE_WAIT_QIANG_DI_ZHU)
{
info.add_dss_total_action_flows()->CopyFrom(table.total_action_flows(j));
}
}
else
{
info.add_dss_total_action_flows()->CopyFrom(table.total_action_flows(j));
}
}
}
}
if (info.dss_total_action_flows_size() > 0)
{
if (!info.dss_total_action_flows(info.dss_total_action_flows_size() - 1).action().has_col_info())
{
info.mutable_dss_total_action_flows()->RemoveLast();
}
}
}
info.set_xiaojia_index(table.xiaojia_index());
info.set_dealer(table.dealer_index());
if (table.dealer_index_2() == -1)
{
info.set_dealer(-1);
}
info.set_tid(table.tid());
info.mutable_dss_conf()->CopyFrom(table.config());
info.set_creator_uid(table.creator_uid());
info.set_left_card_num(table.cards_size());
info.set_operation_index(table.operation_index());
if (table.has_dissolve_info())
{
info.mutable_dissolve_info()->CopyFrom(table.dissolve_info());
}
{
const PBDSSAction* paction = GetLastActionInFlow(table);
if (paction != NULL)
{
if (paction->act_type() == EN_DSS_ACTION_NAPAI)
{
info.set_is_mopai(true);
}
info.set_dest_card(paction->dest_card());
// 只有出牌和拿牌的时候才需要传 dest_card
if (paction->act_type() != EN_DSS_ACTION_NAPAI && paction->act_type() != EN_DSS_ACTION_CHUPAI)
{
info.set_dest_card(0);
}
}
}
}
int TableMgrbase::GetPlayerNumByState(const PBDSSGameTable& table, ENSeatState expected_state)
{
int num = 0;
for (int i = 0; i < table.seats_size(); i++)
{
const PBDSSTableSeat& seat = table.seats(i);
if (seat.state() == expected_state)
{
num ++ ;
}
}
return num;
}
PBDSSAction& TableMgrbase::GetLastActionInFlow(PBDSSGameTable& table)
{
PBDSSActionFlow& current_flow = *table.mutable_total_action_flows(table.total_action_flows_size() - 1);
PBDSSAction& current_action = *current_flow.mutable_action();
return current_action;
}
const PBDSSAction* TableMgrbase::GetLastActionInFlow(const PBDSSGameTable& table)
{
if (table.total_action_flows_size() > 0)
{
const PBDSSActionFlow& current_flow = table.total_action_flows(table.total_action_flows_size() - 1);
const PBDSSAction& current_action = current_flow.action();
return ¤t_action;
}
return NULL;
}
这样消息处理三个本地调用的三个函数,
找桌子 CPBGameTable* ptable = TableManager::Instance()->FindTable(tid);
找位置 PBDSSTableSeat* pseat = TableLogic::FindEmptySeatInTable(*ptable);,
坐下 TableLogic::SitDownOnTable(*ptable,*pseat,user,tbdata,connect_id);
的逻辑都抽在TableMgrbase类里面了。
其实这里开始遇到一个难点,我抽出来了后,每个游戏都跑这个代码,那么 TableManager::Instance()->FindTable(tid); 必然是每个游戏自己的table,我一个抽象出来的类怎么兼容110个游戏对象?
游戏的table类
class CPBGameTable : public PBDSSGameTable, public CTimerOutListener
{
public:
CPBGameTable(const CPBGameTable& table)
{
CopyFrom(table);
}
CPBGameTable();
~CPBGameTable();
看他这个 CPBGameTable都是继承的同一个基类,那么我们封装的接口就是用的基类。我们去看看他的基类
class PBDSSGameTable : public ::google::protobuf::Message {
public:
PBDSSGameTable();
virtual ~PBDSSGameTable();
PBDSSGameTable(const PBDSSGameTable& from);
inline PBDSSGameTable& operator=(const PBDSSGameTable& from) {
CopyFrom(from);
return *this;
}
对你没看错,这个基类居然是一个protobuf。那么这个基类是不能自定义函数了。。。。
那么就是抽象出来的通用接口,只能用基类的数据做逻辑处理,是不能函数调用的,但是我们通用的消息处理那是确实用到了函数调用
ptable->StopReadyTimer(); ptable->StartReadyTimer(120);怎么办?我们调用基类处理通用逻辑,然后把对象返回,在通用消息处理后把对象强转成子类对象再调用这二个函数。
所以最终我们优化后的消息处理就改成这样了
CommonClienthandler.cpp
ENHandlerResult CRequestEnterTable::ProcessUpdateSucc(CHandlerTokenBasic* ptoken, CSession* psession)
{
PBDSSGameTable *pPBDSSGameTable = NULL ; PBDSSTableSeat *pseat = NULL;
if(!Clienthandlerbase::Instance()->cs_response_dss_enter_table(psession, &pPBDSSGameTable, &pseat, EN_Position_DDZ_AY_3))
return EN_Handler_Done;
CPBGameTable* ptable = (CPBGameTable*)pPBDSSGameTable;
TableManager::Instance()->OnPlayerEnterTable(psession->_request_route.uid(), ptable->tid());
ptable->StopReadyTimer();
ptable->StartReadyTimer(120);
return EN_Handler_Done;
}
我们现在来算算这个优化删掉了多少代码
消息处理函数
ENHandlerResult CRequestEnterTable::ProcessUpdateSucc(CHandlerTokenBasic* ptoken, CSession* psession)
原本68行代码
优化后11行代码
看起来消息处理这里只优化了57行?
你忘了消息处理这里还有函数调用
PBDSSGameTable* TableMgrbase::FindTable(int64 tid) 9行
PBDSSTableSeat* TableMgrbase::FindEmptySeatInTable(PBDSSGameTable& table, bool observe) 22行
TableMgrbase::Instance()->SitDownOnTable(**ptable,**pseat,user,tbdata,connect_id); 92行
SitDownOnTable里面还有函数调用
RefreshTeabarTableDisplay(table, true); 30行
BroadcastTableMsg(table, msg, user.uid()); 38行
函数调用一共191行,加上消息处理68行 ,之前是多少行代码?(68+191)*110=28490行
现在多少行?11*110 +191 = 1401行代码