Chinaunix首页 | 论坛 | 博客
  • 博客访问: 331108
  • 博文数量: 100
  • 博客积分: 2620
  • 博客等级: 少校
  • 技术积分: 920
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-16 02:50
文章分类

全部博文(100)

文章存档

2011年(5)

2010年(12)

2009年(83)

分类:

2009-12-19 01:05:29


mangosd 之 CliRunnable

    启动的控制台线程,该线程从stdin读入用户命令,解析后通过command打包后由LockedQueue传到
WorldRunnable Thread执行,在WorldRunnable中,每次调用update的最后都会对用户的命令进行处理。
    和MysqlDelayThread中的SqlOperation类似,此处在LockedQueue中存放的依然是对command进行包裹后的类的指针(CliCommandHolder*),在WorldRunnable中,要做的事情很简单,只需要调用一下
CliCommandHolder的Execute函数,而这个函数会自动的执行CliCommand自己的回调函数。
class CliCommandHolder
{
    private:
        const CliCommand *cmd;
        char *args;
        pPrintf m_zprintf;
    public:
        CliCommandHolder(const CliCommand *command, const char *arguments, pPrintf p_zprintf)
            : cmd(command), m_zprintf(p_zprintf)
        {
            size_t len = strlen(arguments)+1;
            args = new char[len];
            memcpy(args, arguments, len);
        }
        ~CliCommandHolder() { delete[] args; }
        void Execute() const { cmd->Func(args, m_zprintf); }
        pPrintf GetOutputMethod() const {return (m_zprintf);}
};
typedef int(* pPrintf)(const char*,...);
typedef void(* pCliFunc)(char *,pPrintf);
/// Command Template class
struct CliCommand
{
    char const * cmd;
    pCliFunc Func;
    char const * description;
};
而各种Client Command对应的回调函数,早就准备妥当了:
/// Table of known commands
const CliCommand Commands[]=
{
    {"help", & CliHelp,"Display this help message"},
    {"broadcast", & CliBroadcast,"Announce in-game message"},
    {"create", & CliCreate,"Create account"},
    {"delete", & CliDelete,"Delete account and characters"},
    {"info", & CliInfo,"Display Server infomation"},
    {"uptime", & CliUpTime, "Displays the server uptime"},
    {"motd", & CliMotd,"Change or display motd"},
    {"kick", & CliKick,"Kick user"},
    {"ban", & CliBan,"Ban account|ip"},
    {"listbans", & CliBanList,"List bans"},
    {"unban", & CliRemoveBan,"Remove ban from account|ip"},
    {"setgm", & CliSetGM,"Edit user privileges"},
    {"setbc", & CliSetTBC,"Set user expansion allowed"},
    {"listgm", & CliListGM,"Display user privileges"},
    {"loadscripts", & CliLoadScripts,"Load script library"},
    {"setloglevel", & CliSetLogLevel,"Set Log Level"},
    {"corpses", & CliCorpses,"Manually call corpses erase global even code"},
    {"version", & CliVersion,"Display server version"},
    {"idleshutdown", & CliIdleShutdown,"Shutdown server with some delay when not active connections at server"},
    {"shutdown", & CliShutdown,"Shutdown server with some delay"},
    {"exit", & CliExit,"Shutdown server NOW"},
    {"writepdump", &CliWritePlayerDump,"Write a player dump to a file"},
    {"loadpdump", &CliLoadPlayerDump,"Load a player dump from a file"},
    {"saveall", &CliSave,"Save all players"},
    {"send", &CliSend,"Send message to a player"},
    {"tele", &CliTele,"Teleport player to location"},
    {"plimit", &CliPLimit,"Show or set player login limitations"}
};
     个人感觉这样设计真的是挺好的,首先,对于WorldRunnable来说,不需要关系具体的CliCommand怎么处理,CliRunnable只需要告诉他一个句柄和这个句柄的调用接口,具体的数据和逻辑都在这个接口中实现好了;这样一来,WorldRunnable就很符合KISS原则了。其次,对于CliRunnable来说,它需要关注每个CliCommand的细节和处理方式,如果处理逻辑发生变化或者增加了新的CliCommand,做的任何修改都在CliRunnable中,对WorldRunnable来说都是透明的,它只是一个任务的执行者,他们互相有很好的隔离性;而建立起这个防火墙的正是上面这样的针对接口编程的机制。
 
阅读(974) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~