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


优化背景,游戏需要做一个旁观功能,那么需要修改的地方有入座和广播。目前看代码是有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 &current_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行代码
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值