• 【C++】记录一次代码优化,28490行代码优化到1401行代码



    优化背景,游戏需要做一个旁观功能,那么需要修改的地方有入座和广播。目前看代码是有110个麻将和牌类,代码相似度99.9%,只有一个枚举不一样(游戏id).
    功能是很简单,入座的协议加个字段是否旁边,广播的时候给旁边的玩家也发消息。但是涉及到一百多个游戏,我也可以每个游戏都改一遍,但是如果有bug,或者还需要修改,不是很麻烦吗。
    所以必须把相同的代码抽出来形成通用函数,每个游戏调用通用函数,不一样的再特殊处理。


    接收消息的地方只有一行代码不一样,游戏id

    每个游戏都有一个 CommonClienthandler.cpp

    1. ENHandlerResult CRequestEnterTable::ProcessUpdateSucc(CHandlerTokenBasic* ptoken, CSession* psession)
    2. {
    3. if (psession->_fsm_state == EN_EnterTable_State_ULOCK)
    4. {
    5. PBCSMsg msg;
    6. CSResponseDssEnterTable& response = *msg.mutable_cs_response_dss_enter_table();
    7. response.set_result(EN_MESSAGE_TABLE_NOT_EXIST);
    8. Message::SendResponseMsg(RouteManager::Instance()->GetRouteByRandom(), psession, msg);
    9. return EN_Handler_Done;
    10. }
    11. else if (psession->_fsm_state == EN_EnterTable_State_ULOCK_AF_SAVE)
    12. {
    13. PBCSMsg msg;
    14. CSResponseEnterTable& response = *msg.mutable_cs_response_enter_table();
    15. response.set_result(EN_MESSAGE_NO_EMPTY_SEAT);
    16. Message::SendResponseMsg(RouteManager::Instance()->GetRouteByRandom(), psession, msg);
    17. return EN_Handler_Done;
    18. }
    19. long long uid = psession->_request_route.uid();
    20. const PBUser& user = psession->_kvdb_uid_data_map[uid].user_info();
    21. const CSRequestDssEnterTable& cs_request_enter_table = psession->_request_msg.cs_request_dss_enter_table();
    22. int tid = cs_request_enter_table.tid();
    23. int connect_id = cs_request_enter_table.connect_id();
    24. PBCSMsg msg;
    25. CSResponseDssEnterTable& response = *msg.mutable_cs_response_dss_enter_table();
    26. // const PBBPlayerPositionInfo & pos = user.pos();
    27. // if(pos.pos_type() == EN_Position_DSS_Xj && pos.table_id() != 0)
    28. // {
    29. // tid = pos.table_id();
    30. // }
    31. CPBGameTable* ptable = TableManager::Instance()->FindTable(tid);
    32. if (ptable == NULL)
    33. {
    34. return EN_Handler_Done;
    35. }
    36. PBDSSTableSeat* pseat = TableLogic::FindEmptySeatInTable(*ptable);
    37. if (pseat == NULL)
    38. {
    39. psession->_fsm_state = EN_EnterTable_State_ULOCK_AF_SAVE;
    40. PBUpdateData update;
    41. update.set_key(PBUserDataField::kUserInfo);
    42. {
    43. PBDBAtomicField& field = *update.add_field_list();
    44. field.set_field(EN_DB_Field_POS);
    45. PBBPlayerPositionInfo& pos = *field.mutable_pos();
    46. pos.set_pos_type(EN_Position_Hall);
    47. pos.set_table_id(0);
    48. pos.set_gamesvrd_id(0);
    49. }
    50. psession->NewAddUpdateData(psession->_request_route.uid(), update);
    51. return EN_Handler_Save;
    52. }
    53. const PBUserTeaBarData& tbdata = psession->_kvdb_uid_data_map[uid].user_tea_bar_data();
    54. //竞技场,记录玩家来自哪个亲友圈
    55. if(ptable->config().is_arena())
    56. {
    57. pseat->mutable_src_tea_bar()->set_tbid(cs_request_enter_table.src_tbid());
    58. pseat->mutable_src_tea_bar()->mutable_tb_master()->set_uid(cs_request_enter_table.src_tb_master_uid());
    59. }
    60. TableLogic::SitDownOnTable(*ptable,*pseat,user,tbdata,connect_id);
    61. CSNotifyTableInfo& info = *response.mutable_table_info();
    62. TableLogic::CopyTableToNotify(*ptable, info, uid);
    63. response.set_result(EN_MESSAGE_ERROR_OK);
    64. response.set_gamesvrd_id(TGlobal::_svid);
    65. response.set_pos_type(EN_Position_DSS_Xj);
    66. Message::SendResponseMsg(RouteManager::Instance()->GetRouteByRandom(), psession, msg);
    67. return EN_Handler_Done;
    68. }

    这个代码抽出来是比较简单,但是要能正常运行并没有那么简单,因为这里还有

    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

    1. //
    2. // Author: baiyufei
    3. // Date: 2022-08-25 15:00:00
    4. // 前端协议的通用处理,防止重复代码
    5. //
    6. #pragma once
    7. #include "poker_msg.pb.h"
    8. #include "NewProcessor.h"
    9. namespace base
    10. {
    11. enum EN_EenterTable_State
    12. {
    13. EN_EnterTable_State_ULOCK = 1,
    14. EN_EnterTable_State_ENTERING = 2,
    15. EN_EnterTable_State_ULOCK_AF_SAVE = 3,
    16. };
    17. }
    18. class Clienthandlerbase
    19. {
    20. private:
    21. /* data */
    22. public:
    23. Clienthandlerbase(/* args */);
    24. ~Clienthandlerbase();
    25. static Clienthandlerbase* Instance() {static Clienthandlerbase gInstance; return &gInstance;}
    26. public:
    27. bool cs_response_dss_enter_table(CSession* psession, PBDSSGameTable** ptable, PBDSSTableSeat** pseat, ENPlayerPositionType gameId);
    28. };

    Clienthandlerbase.cpp

    1. #include "Clienthandlerbase.h"
    2. #include "TableMgrbase.h"
    3. using namespace base;
    4. Clienthandlerbase::Clienthandlerbase(/* args */)
    5. {
    6. }
    7. Clienthandlerbase::~Clienthandlerbase()
    8. {
    9. }
    10. bool Clienthandlerbase::cs_response_dss_enter_table(CSession* psession, PBDSSGameTable** ptable, PBDSSTableSeat** pseat, ENPlayerPositionType gameId)
    11. {
    12. if (psession->_fsm_state == EN_EnterTable_State_ULOCK)
    13. {
    14. PBCSMsg msg;
    15. CSResponseDssEnterTable& response = *msg.mutable_cs_response_dss_enter_table();
    16. response.set_result(EN_MESSAGE_TABLE_NOT_EXIST);
    17. Message::SendResponseMsg(RouteManager::Instance()->GetRouteByRandom(), psession, msg);
    18. return false;
    19. }
    20. else if (psession->_fsm_state == EN_EnterTable_State_ULOCK_AF_SAVE)
    21. {
    22. PBCSMsg msg;
    23. CSResponseEnterTable& response = *msg.mutable_cs_response_enter_table();
    24. response.set_result(EN_MESSAGE_NO_EMPTY_SEAT);
    25. Message::SendResponseMsg(RouteManager::Instance()->GetRouteByRandom(), psession, msg);
    26. return false;
    27. }
    28. const CSRequestDssEnterTable& cs_request_enter_table = psession->_request_msg.cs_request_dss_enter_table();
    29. int tid = cs_request_enter_table.tid();
    30. *ptable = TableMgrbase::Instance()->FindTable(tid);
    31. if(NULL == ptable)
    32. return false;
    33. *pseat = TableMgrbase::Instance()->FindEmptySeatInTable(**ptable, cs_request_enter_table.observe());
    34. if(NULL == pseat)
    35. {
    36. psession->_fsm_state = EN_EnterTable_State_ULOCK_AF_SAVE;
    37. PBUpdateData update;
    38. update.set_key(PBUserDataField::kUserInfo);
    39. {
    40. PBDBAtomicField& field = *update.add_field_list();
    41. field.set_field(EN_DB_Field_POS);
    42. PBBPlayerPositionInfo& pos = *field.mutable_pos();
    43. pos.set_pos_type(EN_Position_Hall);
    44. pos.set_table_id(0);
    45. pos.set_gamesvrd_id(0);
    46. }
    47. psession->NewAddUpdateData(psession->_request_route.uid(), update);
    48. return false;
    49. }
    50. long long uid = psession->_request_route.uid();
    51. //竞技场,记录玩家来自哪个亲友圈
    52. if((**ptable).config().is_arena())
    53. {
    54. (**pseat).mutable_src_tea_bar()->set_tbid(cs_request_enter_table.src_tbid());
    55. (**pseat).mutable_src_tea_bar()->mutable_tb_master()->set_uid(cs_request_enter_table.src_tb_master_uid());
    56. }
    57. const PBUser& user = psession->_kvdb_uid_data_map[uid].user_info();
    58. int connect_id = cs_request_enter_table.connect_id();
    59. const PBUserTeaBarData& tbdata = psession->_kvdb_uid_data_map[uid].user_tea_bar_data();
    60. TableMgrbase::Instance()->SitDownOnTable(**ptable,**pseat,user,tbdata,connect_id);
    61. PBCSMsg msg;
    62. CSResponseDssEnterTable& response = *msg.mutable_cs_response_dss_enter_table();
    63. CSNotifyTableInfo& info = *response.mutable_table_info();
    64. TableMgrbase::Instance()->CopyTableToNotify(**ptable, info, uid);
    65. response.set_result(EN_MESSAGE_ERROR_OK);
    66. response.set_gamesvrd_id(TGlobal::_svid);
    67. response.set_pos_type(gameId);
    68. Message::SendResponseMsg(RouteManager::Instance()->GetRouteByRandom(), psession, msg);
    69. return true;
    70. }

    再把 TableLogic和TableManager的代码抽出来形成TableMgrbase

    TableMgrbase.h

    1. //
    2. // Author: baiyufei
    3. // Date: 2022-08-25 15:00:00
    4. // 桌子的通用逻辑(其他游戏的所有桌子数据在这里都有一个指针备份)
    5. //
    6. #pragma once
    7. #include "poker_msg.pb.h"
    8. #include
    9. #include "../core/include/Timer_Handler_Base.h"
    10. using namespace std;
    11. using google::protobuf::RepeatedField;
    12. using google::protobuf::RepeatedPtrField;
    13. typedef long long int64;
    14. typedef int int32;
    15. namespace base
    16. {
    17. #define REPORT_AT_PLAY_TIMER 10000
    18. typedef map baseTableMap;
    19. typedef map baseUserTableMap;
    20. enum ENGameServiceState
    21. {
    22. EN_Game_Service_State_IDEL = 1,
    23. EN_Game_Service_State_Connecting = 2,
    24. EN_Game_Service_State_Registing = 3,
    25. EN_Game_Service_State_Ready = 4,
    26. EN_Game_Service_State_Working = 5,
    27. EN_Game_Service_State_Retired = 6,
    28. };
    29. }
    30. class TableMgrbase
    31. {
    32. private:
    33. /* data */
    34. public:
    35. TableMgrbase(/* args */);
    36. ~TableMgrbase();
    37. static TableMgrbase* Instance();
    38. public:
    39. void Init();
    40. PBDSSGameTable* FindTable(int64 tid);
    41. void ReportGameInfo();
    42. public:
    43. //如果要用通用的桌子逻辑,其他游戏new桌子的时候一定要调用addTable在这里备份一个数据
    44. void addTable(int64 tid, PBDSSGameTable* pPBDSSGameTable);
    45. public:
    46. void SitDownOnTable(PBDSSGameTable & table,PBDSSTableSeat & seat,const PBUser & user,const PBUserTeaBarData& tbdata,int connect_id = 1);
    47. //如果是茶馆房间,刷新下茶馆人数,并且设置备注
    48. void RefreshTeabarTableDisplay(PBDSSGameTable& table, bool is_need_refesh_play_num);
    49. void BroadcastTableMsg(const PBDSSGameTable& table, PBCSMsg& notify, int excepted_uid = 0);
    50. //找一个空位置
    51. PBDSSTableSeat* FindEmptySeatInTable(PBDSSGameTable& table, bool observe);
    52. void CopyTableToNotify(const PBDSSGameTable& table, CSNotifyTableInfo& info, int uid);
    53. //座位判断与状态统计
    54. int GetPlayerNumByState(const PBDSSGameTable& table, ENSeatState expected_state);
    55. PBDSSAction& GetLastActionInFlow(PBDSSGameTable& table);
    56. const PBDSSAction* GetLastActionInFlow(const PBDSSGameTable& table);
    57. public:
    58. base::baseTableMap _tablemap;
    59. base::ENGameServiceState _state;
    60. public:
    61. int64 start_stamp;
    62. };

    TableMgrbase.cpp

    1. #include "TableMgrbase.h"
    2. #include "../core/include/global.h"
    3. #include "NewProcessor.h"
    4. #include "RouteManager.h"
    5. #include "global.h"
    6. #include "../svr/common/LogWriter.h"
    7. TableMgrbase::TableMgrbase(/* args */)
    8. {
    9. }
    10. TableMgrbase::~TableMgrbase()
    11. {
    12. }
    13. void TableMgrbase::Init()
    14. {
    15. }
    16. TableMgrbase* TableMgrbase::Instance()
    17. {
    18. static TableMgrbase gInstance;
    19. return &gInstance;
    20. }
    21. PBDSSGameTable* TableMgrbase::FindTable(int64 tid)
    22. {
    23. if (_tablemap.find(tid) == _tablemap.end())
    24. {
    25. return NULL;
    26. }
    27. PBDSSGameTable* table = _tablemap[tid];
    28. return table;
    29. }
    30. void TableMgrbase::addTable(int64 tid, PBDSSGameTable* pPBDSSGameTable)
    31. {
    32. if (NULL == pPBDSSGameTable || _tablemap.find(tid) != _tablemap.end())
    33. {
    34. return;
    35. }
    36. _tablemap[tid] = pPBDSSGameTable;
    37. }
    38. void TableMgrbase::ReportGameInfo()
    39. {
    40. if (_state == base::EN_Game_Service_State_Retired)
    41. {
    42. return;
    43. }
    44. PBCSMsg msg;
    45. SSReportGameSvrdInfo& ss_report_gamesvrd_info = *msg.mutable_ss_report_game_info();
    46. ss_report_gamesvrd_info.set_gameid(TGlobal::_svid);
    47. ss_report_gamesvrd_info.set_gtype(TGlobal::_svrd_type);
    48. Message::PushInnerMsg(RouteManager::Instance()->GetRouteByRandom(), 0, msg, EN_Node_Room, 1);
    49. }
    50. void TableMgrbase::SitDownOnTable(PBDSSGameTable & table, PBDSSTableSeat & seat, const PBUser & user, const PBUserTeaBarData& tbdata, int connect_id /*= 1*/)
    51. {
    52. //玩家坐下
    53. PBTableUser& tableuser = *seat.mutable_user();
    54. tableuser.set_uid(user.uid());
    55. tableuser.set_nick(user.nick());
    56. tableuser.set_role_picture_url(user.pic_url());
    57. tableuser.set_acc_type(user.acc_type());
    58. tableuser.set_channel(user.channel());
    59. tableuser.set_last_login_ip(user.last_login_ip());
    60. tableuser.set_gender(user.gender());
    61. tableuser.set_chip(user.chips());
    62. tableuser.set_connect_id(connect_id);
    63. tableuser.set_items_info(user.items_info());
    64. if(tbdata.brief_data_size() > 0)
    65. {
    66. for(int i = 0; i < tbdata.brief_data_size(); i++)
    67. {
    68. tableuser.mutable_tbid_list()->Add(tbdata.brief_data(i).tbid());
    69. }
    70. }
    71. seat.set_state(EN_SEAT_STATE_WAIT_FOR_NEXT_ONE_GAME);
    72. seat.set_final_score(0);
    73. seat.set_total_score(0);
    74. if (seat.switch_voices_size() != table.seats_size())
    75. {
    76. seat.mutable_switch_voices()->Resize(table.seats_size(), true);
    77. }
    78. //OnPlayerEnterTable(user.uid(),table.tid());
    79. //如果是茶馆房间,刷新下茶馆人数,并且设置备注
    80. if (table.config().has_tbid() && table.config().has_master_uid())
    81. {
    82. long long tbid = table.config().tbid();
    83. if(table.config().is_arena())
    84. {
    85. tbid = seat.src_tea_bar().tbid();
    86. }
    87. for(int i = 0; i < tbdata.brief_data_size(); i++)
    88. {
    89. if(tbid == tbdata.brief_data(i).tbid())
    90. {
    91. tableuser.set_remark(tbdata.brief_data(i).remarks());
    92. //设置魅力值
    93. if(table.config().has_rpf())
    94. {
    95. seat.set_bind_cooperator_uid(tbdata.brief_data(i).bind_cooperator_uid());
    96. seat.set_charm_score(tbdata.brief_data(i).charm_score() * 100);
    97. seat.set_is_hide_charm_score(tbdata.brief_data(i).is_hide_charm_score());
    98. ErrMsg("当前魅力值[%ld], uid[%ld], tid[%ld], tbid[%ld]", seat.charm_score(), seat.user().uid(), table.tid(), tbdata.brief_data(i).tbid());
    99. }
    100. //设置魅力值
    101. if(table.config().has_rmf())
    102. {
    103. int64 rank_score = 0;
    104. if(tbdata.brief_data(i).rank_score_info().match_id() == table.config().rmf().match_id())
    105. {
    106. rank_score = tbdata.brief_data(i).rank_score_info().rank_score();
    107. }
    108. seat.set_rank_score(rank_score);
    109. seat.set_is_hide_charm_score(tbdata.brief_data(i).is_hide_charm_score());
    110. 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());
    111. }
    112. break;
    113. }
    114. }
    115. RefreshTeabarTableDisplay(table, true);
    116. }
    117. //刷新茶馆玩家游戏状态
    118. if(tbdata.brief_data_size() > 0)
    119. {
    120. PBCSMsg msg_teabar;
    121. SSNotifyTeaBarUserGameState& teabar_notify = *msg_teabar.mutable_ss_notify_tea_bar_user_game_state();
    122. teabar_notify.set_uid(user.uid());
    123. if(table.config().is_arena())
    124. {
    125. teabar_notify.set_game_state(3);
    126. }
    127. else
    128. {
    129. teabar_notify.set_game_state(1);
    130. }
    131. teabar_notify.mutable_tbid_list()->CopyFrom(tableuser.tbid_list());
    132. Message::PushInnerMsg(RouteManager::Instance()->GetRouteByRandom(), 0, msg_teabar, EN_Node_TeaBar, 1);
    133. }
    134. //广播玩家坐下
    135. PBCSMsg msg;
    136. CSNotifySitDown& notify_sit_down = *msg.mutable_cs_notify_sit_down();
    137. notify_sit_down.mutable_dss_seat()->CopyFrom(seat);
    138. BroadcastTableMsg(table, msg, user.uid());
    139. return;
    140. }
    141. void TableMgrbase::RefreshTeabarTableDisplay(PBDSSGameTable& table, bool is_need_refesh_play_num)
    142. {
    143. //如果是茶馆房间,刷新下茶馆人数,并且设置备注
    144. if (table.config().has_tbid() && table.config().has_master_uid())
    145. {
    146. PBCSMsg notify;
    147. SSNotifyTeaBarTablePlayerNum& ss_notify_teabar_table_player_num = *notify.mutable_ss_notify_teabar_table_player_num();
    148. ss_notify_teabar_table_player_num.mutable_conf()->CopyFrom(table.config());
    149. ss_notify_teabar_table_player_num.set_tid(table.tid());
    150. if (is_need_refesh_play_num)
    151. {
    152. ss_notify_teabar_table_player_num.set_player_num(table.seats_size() - GetPlayerNumByState(table, EN_SEAT_STATE_NO_PLAYER));
    153. }
    154. for (int i = 0; i < table.seats_size(); i++)
    155. {
    156. if (table.seats(i).state() == EN_SEAT_STATE_NO_PLAYER)
    157. continue;
    158. PBTeaBarUser& user = *ss_notify_teabar_table_player_num.add_users();
    159. user.set_uid(table.seats(i).user().uid());
    160. user.set_name(table.seats(i).user().nick());
    161. user.set_url(table.seats(i).user().role_picture_url());
    162. user.set_remarks(table.seats(i).user().remark());
    163. user.set_is_online(!table.seats(i).user().is_offline());
    164. user.set_total_score(table.seats(i).total_score());
    165. }
    166. ss_notify_teabar_table_player_num.set_round(table.round());
    167. Message::PushInnerMsg(RouteManager::Instance()->GetRouteByRandom(), 0, notify, EN_Node_TeaBar, 1);
    168. }
    169. return;
    170. }
    171. void TableMgrbase::BroadcastTableMsg(const PBDSSGameTable& table, PBCSMsg& notify, int excepted_uid)
    172. {
    173. for (int i = 0; i < table.seats_size(); i++)
    174. {
    175. const PBDSSTableSeat& seat = table.seats(i);
    176. if (seat.state() == EN_SEAT_STATE_NO_PLAYER)
    177. {
    178. continue;
    179. }
    180. const PBTableUser& user = seat.user();
    181. if (user.uid() != excepted_uid && user.is_offline() == false)
    182. {
    183. VLogMsg(CLIB_LOG_LEV_DEBUG, "broadcast msg[0x%x] to user[%ld].seat index[%d]", notify.msg_union_case(), user.uid(), i);
    184. {
    185. Message::PushMsg(RouteManager::Instance()->GetRouteByRandom(), seat.user().uid(), notify, EN_Node_Connect, seat.user().connect_id());
    186. }
    187. }
    188. }
    189. }
    190. PBDSSTableSeat* TableMgrbase::FindEmptySeatInTable(PBDSSGameTable& table, bool observe)
    191. {
    192. PBDSSTableSeat* pSeat = NULL;
    193. if(observe)
    194. {
    195. pSeat = table.add_observe();
    196. pSeat->set_observe(true);
    197. return pSeat;
    198. }
    199. for (int i = 0; i < table.seats_size(); i++)
    200. {
    201. PBDSSTableSeat& seat = *table.mutable_seats(i);
    202. if (seat.state() == EN_SEAT_STATE_NO_PLAYER)
    203. {
    204. pSeat = & seat;
    205. pSeat->set_observe(false);
    206. break;
    207. }
    208. }
    209. return pSeat;
    210. }
    211. void TableMgrbase::CopyTableToNotify(const PBDSSGameTable& table, CSNotifyTableInfo& info, int uid)
    212. {
    213. for (int i = 0; i < table.seats_size(); i++)
    214. {
    215. PBDSSTableSeat& seat = *info.add_dss_seats();
    216. seat.CopyFrom(table.seats(i));
    217. if (seat.user().is_offline())
    218. {
    219. seat.set_offline_timer(time(NULL) - seat.offline_time());
    220. }
    221. if (seat.state() != EN_SEAT_STATE_NO_PLAYER && seat.user().uid() != uid)
    222. {
    223. for (int j = 0; j < seat.hand_cards_size(); j++)
    224. {
    225. seat.set_hand_cards(j, 0);
    226. }
    227. seat.clear_action_choice();
    228. }
    229. seat.clear_switch_voices();
    230. }
    231. for(int i = 0;iseats_size();i++)
    232. {
    233. if(table.seats(i).state()!=EN_SEAT_STATE_NO_PLAYER && table.seats(i).user().uid() == uid)
    234. {
    235. info.mutable_self_switch_voices()->CopyFrom(table.seats(i).switch_voices());
    236. }
    237. }
    238. info.mutable_out_cards()->CopyFrom(table.out_cards());
    239. info.set_display_anpai(table.display_anpai());
    240. info.set_state(table.state());
    241. info.set_round(table.round());
    242. if (table.dealer_index_2() != -1)
    243. {
    244. RepeatedField<int> di_src;
    245. for (int i = 0; i < table.cards_size() && i < 3; i++)
    246. {
    247. di_src.Add(table.cards(i));
    248. }
    249. info.mutable_cards()->CopyFrom(di_src);
    250. }
    251. else
    252. {
    253. int zhua_cards_size = table.config().lai_zi_num() > 0 ? 4 : 3;
    254. info.mutable_cards()->Resize(zhua_cards_size, 0);
    255. }
    256. if (table.total_action_flows_size() > 0)
    257. {
    258. for (int i = table.total_action_flows_size() - 1; i >= 0; i--)
    259. {
    260. if (table.total_action_flows(i).action().act_type() == EN_DSS_ACTION_PASS
    261. && table.total_action_flows(i).action().is_single_over())
    262. {
    263. for (int j = i + 1; j < table.total_action_flows_size(); j++)
    264. {
    265. info.add_dss_total_action_flows()->CopyFrom(table.total_action_flows(j));
    266. }
    267. break;
    268. }
    269. if (i == 0 && info.dss_total_action_flows_size() == 0)
    270. {
    271. for (int j = 0; j < table.total_action_flows_size(); j++)
    272. {
    273. if (table.total_action_flows(j).action().act_type() == EN_DSS_ACTION_QIANG_DI_ZHU
    274. || table.total_action_flows(j).action().act_type() == EN_DSS_ACTION_BU_QIANG)
    275. {
    276. if (table.state() == EN_TABLE_STATE_WAIT_QIANG_DI_ZHU)
    277. {
    278. info.add_dss_total_action_flows()->CopyFrom(table.total_action_flows(j));
    279. }
    280. }
    281. else
    282. {
    283. info.add_dss_total_action_flows()->CopyFrom(table.total_action_flows(j));
    284. }
    285. }
    286. }
    287. }
    288. if (info.dss_total_action_flows_size() > 0)
    289. {
    290. if (!info.dss_total_action_flows(info.dss_total_action_flows_size() - 1).action().has_col_info())
    291. {
    292. info.mutable_dss_total_action_flows()->RemoveLast();
    293. }
    294. }
    295. }
    296. info.set_xiaojia_index(table.xiaojia_index());
    297. info.set_dealer(table.dealer_index());
    298. if (table.dealer_index_2() == -1)
    299. {
    300. info.set_dealer(-1);
    301. }
    302. info.set_tid(table.tid());
    303. info.mutable_dss_conf()->CopyFrom(table.config());
    304. info.set_creator_uid(table.creator_uid());
    305. info.set_left_card_num(table.cards_size());
    306. info.set_operation_index(table.operation_index());
    307. if (table.has_dissolve_info())
    308. {
    309. info.mutable_dissolve_info()->CopyFrom(table.dissolve_info());
    310. }
    311. {
    312. const PBDSSAction* paction = GetLastActionInFlow(table);
    313. if (paction != NULL)
    314. {
    315. if (paction->act_type() == EN_DSS_ACTION_NAPAI)
    316. {
    317. info.set_is_mopai(true);
    318. }
    319. info.set_dest_card(paction->dest_card());
    320. // 只有出牌和拿牌的时候才需要传 dest_card
    321. if (paction->act_type() != EN_DSS_ACTION_NAPAI && paction->act_type() != EN_DSS_ACTION_CHUPAI)
    322. {
    323. info.set_dest_card(0);
    324. }
    325. }
    326. }
    327. }
    328. int TableMgrbase::GetPlayerNumByState(const PBDSSGameTable& table, ENSeatState expected_state)
    329. {
    330. int num = 0;
    331. for (int i = 0; i < table.seats_size(); i++)
    332. {
    333. const PBDSSTableSeat& seat = table.seats(i);
    334. if (seat.state() == expected_state)
    335. {
    336. num ++ ;
    337. }
    338. }
    339. return num;
    340. }
    341. PBDSSAction& TableMgrbase::GetLastActionInFlow(PBDSSGameTable& table)
    342. {
    343. PBDSSActionFlow& current_flow = *table.mutable_total_action_flows(table.total_action_flows_size() - 1);
    344. PBDSSAction& current_action = *current_flow.mutable_action();
    345. return current_action;
    346. }
    347. const PBDSSAction* TableMgrbase::GetLastActionInFlow(const PBDSSGameTable& table)
    348. {
    349. if (table.total_action_flows_size() > 0)
    350. {
    351. const PBDSSActionFlow& current_flow = table.total_action_flows(table.total_action_flows_size() - 1);
    352. const PBDSSAction& current_action = current_flow.action();
    353. return ¤t_action;
    354. }
    355. return NULL;
    356. }

    这样消息处理三个本地调用的三个函数,
    找桌子  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类

    1. class CPBGameTable : public PBDSSGameTable, public CTimerOutListener
    2. {
    3. public:
    4. CPBGameTable(const CPBGameTable& table)
    5. {
    6. CopyFrom(table);
    7. }
    8. CPBGameTable();
    9. ~CPBGameTable();

    看他这个 CPBGameTable都是继承的同一个基类,那么我们封装的接口就是用的基类。我们去看看他的基类

    1. class PBDSSGameTable : public ::google::protobuf::Message {
    2. public:
    3. PBDSSGameTable();
    4. virtual ~PBDSSGameTable();
    5. PBDSSGameTable(const PBDSSGameTable& from);
    6. inline PBDSSGameTable& operator=(const PBDSSGameTable& from) {
    7. CopyFrom(from);
    8. return *this;
    9. }

    对你没看错,这个基类居然是一个protobuf。那么这个基类是不能自定义函数了。。。。
    那么就是抽象出来的通用接口,只能用基类的数据做逻辑处理,是不能函数调用的,但是我们通用的消息处理那是确实用到了函数调用
    ptable->StopReadyTimer(); ptable->StartReadyTimer(120);怎么办?我们调用基类处理通用逻辑,然后把对象返回,在通用消息处理后把对象强转成子类对象再调用这二个函数。
    所以最终我们优化后的消息处理就改成这样了

    CommonClienthandler.cpp

    1. ENHandlerResult CRequestEnterTable::ProcessUpdateSucc(CHandlerTokenBasic* ptoken, CSession* psession)
    2. {
    3. PBDSSGameTable *pPBDSSGameTable = NULL ; PBDSSTableSeat *pseat = NULL;
    4. if(!Clienthandlerbase::Instance()->cs_response_dss_enter_table(psession, &pPBDSSGameTable, &pseat, EN_Position_DDZ_AY_3))
    5. return EN_Handler_Done;
    6. CPBGameTable* ptable = (CPBGameTable*)pPBDSSGameTable;
    7. TableManager::Instance()->OnPlayerEnterTable(psession->_request_route.uid(), ptable->tid());
    8. ptable->StopReadyTimer();
    9. ptable->StartReadyTimer(120);
    10. return EN_Handler_Done;
    11. }

    我们现在来算算这个优化删掉了多少代码
    消息处理函数
    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行代码
     

  • 相关阅读:
    轻松学会JavaScript事件
    HTML语义化标签(一)
    【Linux】进程控制 (万字详解)—— 进程创建 | 进程退出 | 进程等待 | 程序替换 | 实现简易shell
    EasyExcel复杂表头导出(一对多)升级版
    JAVA【DAO及其实现类】
    解决大众D评网站css加密改进说明
    并发编程带来的安全性挑战之同步锁
    【位运算】只出现一次的数字
    ElementUI之动态树+数据表格+分页
    【EPLAN】统一修改项目中字体大小
  • 原文地址:https://blog.csdn.net/q277055799/article/details/126623589